Cucumber-js: 添加 BeforeStep / AfterStep 钩子

创建于 2018-01-04  ·  33评论  ·  资料来源: cucumber/cucumber-js

对每一步结束后的验证很有用。 this应该是世界实例

最有用的评论

大家好,

Step hooks 有更新吗? 或者在每个步骤执行之前和/或之后运行一些代码的任何解决方法?

所有33条评论

@charlierudolph我想在这里提供帮助,但需要一些关于实现它的适当方式的指针。 我相信最近删除了 registerHandler 的语法糖 AfterStep。 我查看了 support_code_library_builder/define_helpers.js。 但是需要一些关于如何实现这些钩子的指示。
谢谢
阿里
PS 感谢您恢复结果 json 格式。

但这里的一个问题是这如何影响工作流程? 这可以编辑步骤结果状态还是作为另一个可以通过/失败的步骤?

我在其中一个评论中看到的并且我也想使用的用例是在该步骤之后创建一个屏幕截图。 在 cucumber ruby​​ 中,我使用了 AfterStep,它提供了对 Scenario 对象的访问。
恕我直言,afterstep 钩子只能用于用户想要内省步骤结果但不能更改结果的用例。 我也认为它不应该是另一个可以通过/失败的步骤。

@charlierudolph我也在寻找类似的解决方案。
在 registerHandler 被弃用之前,我使用此代码在步骤失败后截取屏幕截图。:

```
this.registerHandler('StepResult', function (event, callback) {
var stepResult = event.getPayloadItem('stepResult');

if (stepResult.getStatus() == 'failed') {
  takeScreenshot()
    .then(function () {
      callback();
    });
} else {
  callback();
}});

````

现在我没有解决方案。

你好,

我在我阅读的关于 BeforeStep/AfterStep 钩子的大多数线程中看到,用例正在打印屏幕。 这不是我的用例,我只想为这些钩子表达其他用例:

我的项目在黄瓜 1.x 中使用了 this.AfterStep 钩子:

  • 收集数据 - 例如所有外部链接:
    element.all(by.css('a')).each(function(link) { link.getAttribute('href').then(function(href) { ... }); });

然后在单独的测试套件中测试所有外部链接。

  • 检查元素 ID 重复项(目的是确保所有 ID 都是唯一的以符合 HTML 标准,并且还可以更轻松地创建测试)
  • 检查脚本错误(AfterStep 将为 After 挂钩设置一个变量以实际失败场景)。
  • 无视浏览器警报。 一些测试场景使网络浏览器打开警报窗口,我们可能想忽略它。 这尤其适用于有表单和输入元素时,浏览器会发出警报(“您有未保存的更改...”)

目前使用 Cucumber 4.0.0 和 Protractor 4.0.14

旁注:我们的用例在 Cucumber 1.xx 中无法与 this.AfterStep() 一起正常工作,因为它的设计目的不是包含这种类型的代码,而且我们看到了竞态条件的问题。 所以我们升级到 Cucumber 4.0.0 并禁用 AfterStep 逻辑,直到有适当的支持。

你好,

关于此步骤挂钩之前/之后的任何更新?
AfterStep钩子有什么解决方法吗? 如果特定测试失败,我想截屏。

“附加”对我来说不可用,因为我们已经覆盖了默认的 World 构造函数https://github.com/cucumber/cucumber-js/blob/master/docs/support_files/world.md

谢谢

@gajo4256

我正在使用黄瓜 4.0.0 和这个片段:

After(function (scenario) {
  if (scenario.result.status === Status.FAILED) {
    const World = this;

    return browser.takeScreenshot().then(function (buffer) {
      return World.attach(buffer, 'image/png');
    });
  }});

这将在每个失败的场景后截取屏幕截图。 (它对我有用,因为对于黄瓜,每当一个步骤失败时,整个场景都会失败,所以它几乎与“步骤失败后”相同。

希望能帮助到你。

@mracz

thnx,我实际上尝试过这个(尽管在每一步之后它会更适合我)。
既然我已经覆盖了默认的 World 构造函数,那么在正常情况下,我怎样才能再次为我提供附加信息?

谢谢

@gajo4256

这就是我在自定义世界实现中所拥有的:

const { setWorldConstructor } = require('cucumber');

function CustomWorld( { attach } ) {
  this.attach = attach;
}

setWorldConstructor(CustomWorld);

@mracz ,我目前对每个步骤都这样做:

    When('I do something', function () {
        return takeScreenshot(this, () => {
            return $(...).click();
        });
    });

截图功能是这样的:

export function takeScreenshot(world, stepToExecute: () => promise.Promise<any>): promise.Promise<any> {
    return stepToExecute().then(() => {
        return doTakeScreenshot(world);
    }).catch((err) => {
        return doTakeScreenshot(world).then(() => {
            throw err;
        });
    });
}

function doTakeScreenshot(world) {
    return browser.takeScreenshot().then((screenshot) => {
        world.attach(screenshot, 'image/png');
    }).catch((err) => {
        console.warn('Could not create screenshot', err);
    });
}

我可能对异常过于防御,但我尽了最大的努力,额外的代码不会干扰真实的测试结果。 我现在能做的最好的事情是,一个有效的AfterStep钩子会让我添加更少的样板。

但是,当我做出不改变屏幕的断言时,钩子可能不会做的是跳过屏幕截图(因此屏幕截图将无用),例如Then some element is not shown 。 我想一个可扩展的世界对象可以在那里提供帮助。

这是AfterStep钩子的另一个用例:等待对等方同步(使用矢量时钟或 lamport 时间戳)。 /cc @tooky @jbpros

大家好。
我实际上正在研究这个问题。

我们正在寻找一种从所有不同步骤中截取屏幕截图的方法。
现在,我们正在考虑从 cucumber 中重写 StepDefinitions 函数。

不知道这是否是最好的方法,所以请不要犹豫,提出您的意见!

对于任何在这里苦苦挣扎的人,可以使用定义函数包装器来做到这一点: https ://github.com/PeerioTechnologies/peerio-icebear/blob/dev/test/e2e/code/hooks.js#L28

我们的主要用例与此处的其他用例一样:屏幕截图,但更多地将其用作调试工具,这样如果我们在配置中打开调试模式,我们就可以看到每个步骤的输出。

另一个用途:我们有一些模态可能会在我们网站上出现一定时间后出现。 如果我们运行一个场景,我们希望在每一步之后检查页面上的那些模态,以确保我们的测试不会因为这些模态而变得脆弱。

另一个用例:如果有人想创建一个带有仪表板的报告工具(当前运行的测试状态、以前运行的测试用例等),黄瓜可以在步骤挂钩中发布到工具以更新进度。 这是一个不寻常的例子,我知道,但我现在已经考虑过了,我有兴趣研究它。

KyleFairns,正如你提到的,我需要仪表板的 AfterStep

你好,

我们想检查每一步之后是否有任何 javascript 错误。 不仅是失败的步骤。
(位与@markus-lundin-86 相同)
现在我们只能在每个场景之后这样做。
那么这是在路线图上,还是有人有其他解决方案?

我刚刚发现 WebDriverIO 有用于黄瓜的 beforeStep 和 afterStep 钩子,这解决了我的问题。

希望有帮助...

大家好,

Step hooks 有更新吗? 或者在每个步骤执行之前和/或之后运行一些代码的任何解决方法?

大家好,
与@Prasant-Sutaria 的情况相同。
步骤挂钩或解决方法的任何更新?
提前致谢。

没有更新。 仍在等待有人为此提交拉取请求。

有任何路线图或任何东西吗? 由于这是拥有此功能的一个主要痛点,也许官方声明会很好。

@aslakhellesoy是否有清单或拉取请求需要实施的东西? AFAIK #1058 和 #1121 尝试引入此功能,或一些解决方法。

大家好,
我刚刚创建了一个关于这个问题的 PR: https://github.com/cucumber/cucumber-js/pull/1198。
如果您觉得它有用,请告诉我。

@aslakhellesoy ,我创建了上述 PR (#1198) 来解决这个问题/功能请求。 你能看一下吗,或者指点我应该联系的人?
抄送: @charlierudolph

任何更新? 也期待拥有它:)

我看到 2 个 PRs @leonardonelson91
我认为他们没有找到实现此功能的最佳方法
https://github.com/cucumber/cucumber-js/pull/1198
https://github.com/cucumber/cucumber-js/pull/1058

@charlierudolph您是否知道如果步骤超时,是否仍应运行针对BeforeStepAfterStep注册的函数?

像这里的其他一些人一样,我正在使用setDefinitionFunctionWrapper来实现屏幕截图,这很好用,除非我无法在测试步骤超时时进入 - 我能做的最好的事情就是为浏览器检测,因此它会在步骤仍处于活动状态时抛出。 我希望为setDefinitionFunctionWrapper进行修复,但也想知道这里的意图是什么。

我希望无论步骤是否通过/失败(由于超时或其他原因),BeforeStep / AfterStep 都会运行

只是为此添加一个额外的用例,这与屏幕截图无关。 我正在测试一个事件驱动的系统,并且测试会导致生成事件。 然后读取这些事件并对系统进行更改。

接下来的步骤验证系统处于预期状态,这需要所有事件都已处理。 我希望能够确保队列已被完全处理,并且在进入下一步之前没有任何处于挂起状态的内容。

目前我正在验证步骤中对事件流进行一些轮询,但将它放入挂钩会很好。 因为在进行下一步之前系统处于稳定状态是普遍存在的要求。

@davidjgoss @charlierudolph请你帮我提供一个 setDefinitionFunctionWrapper 的示例代码来实现截图的事情 BeforeStep/AfterStep?,我正在尝试使用 Nightwatch JS

@RArkasali ,这是我从事的一个项目的一个片段:

import {setDefinitionFunctionWrapper} from "cucumber";

setDefinitionFunctionWrapper(function(fn) {
    return async function(...args) {
        try {
            return await fn.apply(this, args);
        } catch (ex) {
            await this.takeScreenshot();
            throw ex;
        }
    };
});

(其中takeScreenshot是您的自定义World上的一种方法,它可以执行实际的截屏操作。我对守夜人还不够熟悉,不知道那是什么样的,但我相信你会的是。)

因此,如果 step 函数中出现错误(如断言失败),这将截取屏幕截图。 我们返回非错误结果的事实很重要——我有一段时间感到困惑,因为没有处理return "pending"的步骤,直到我意识到我正在吞噬返回值。

希望这可以帮助

大家好,
这个问题的状态如何? 它还需要帮助吗?
我对 BeforeStep 和 AfterStep 感兴趣,因为它可以帮助我拥有一个包含所有步骤名称和其他日志信息的“日志”文件。 它比创建自定义格式化程序要容易一些。

关闭此问题,因为在https://github.com/cucumber/cucumber-js/pull/1416中添加了钩子

此页面是否有帮助?
0 / 5 - 0 等级