是否可以在运行时跳过Cucumber-JVM的场景

Nie*_*dal 6 cucumber-jvm

我想在场景中添加一个标签@skiponchrome,这应该会在使用Chrome浏览器运行Selenium测试时跳过这个场景.这样做的原因是因为某些场景在某些环境中工作而在其他环境中不起作用,这甚至可能不是特定于浏览器测试的,并且可以应用于其他情况,例如OS平台.

示例钩子:

@Before("@skiponchrome") // this works
public void beforeScenario() {
  if(currentBrowser == 'chrome') { // this works
    // Skip scenario code here
  }
}
Run Code Online (Sandbox Code Playgroud)

我知道可以在黄瓜标签中定义〜@ skiponchrome来跳过标签,但我想在运行时跳过标签.这样,当我在特定环境中开始测试运行时,我不必考虑提前跳过哪些步骤.

我想创建一个钩子来捕获标记并跳过场景而不报告失败/错误.这可能吗?

Mik*_*y56 6

我意识到这是对已经回答的问题的后期更新,但我想添加一个由cucumber-jvm 直接支持的选项:

@Before //(cucumber one)
public void setup(){
    Assume.assumeTrue(weAreInPreProductionEnvironment);
}
Run Code Online (Sandbox Code Playgroud)

"如果weAreInPreProductionEnvironment是假的话,情节将被标记为忽​​略(但测试将通过)."

你需要添加

import org.junit.Assume;
Run Code Online (Sandbox Code Playgroud)

与接受的答案的主要区别在于JUnit假设失败的行为就像挂起一样

重要因为修复了一个错误,你需要使用cucumber-jvm版本1.2.5,在撰写本文时,这是最新版本.例如,以上将在cucumber-java8-1.2.3.jar中生成失败而不是pending


小智 5

我真的更喜欢通过为每个环境定义单独的运行配置来明确运行哪些测试.我还想将我使用的标签数量保持在最低限度,以保持配置数量的可管理性.

我不认为单独用标签实现你想要的东西是可能的.您需要编写一个自定义的jUnit测试运行器来代替@RunWith(Cucumber.class).看看Cucumber实现,看看它是如何工作的.您需要根据浏览器或其他运行时条件更改RuntimeOptionsFactory创建的RuntimeOptions以包含/排除标记.

或者,您可以考虑编写一个调用测试套件的小脚本,根据您正在运行的环境构建一个动态包含/排除的标记列表.我认为这是一个更易于维护,更清晰的解决方案.


Mik*_*ler 5

其实真的很简单。如果您深入研究 Cucumber-JVM 和 JUnit 4 源代码,您会发现 JUnit 在运行时很容易跳过(只是未记录)。

看一下 JUnit 4 的以下源代码ParentRunner,它是 Cucumber-JVM 的FeatureRunner(用于Cucumber,默认的 Cucumber runner):

@Override
public void run(final RunNotifier notifier) {
    EachTestNotifier testNotifier = new EachTestNotifier(notifier,
            getDescription());
    try {
        Statement statement = classBlock(notifier);
        statement.evaluate();
    } catch (AssumptionViolatedException e) {
        testNotifier.fireTestIgnored();
    } catch (StoppedByUserException e) {
        throw e;
    } catch (Throwable e) {
        testNotifier.addFailure(e);
    }
}
Run Code Online (Sandbox Code Playgroud)

这就是 JUnit 决定显示什么结果的方式。如果成功,它将显示通过,但@Ignore在 JUnit 中是可能的,那么在这种情况下会发生什么?好吧, anAssumptionViolatedException是由RunNotifier(或FeatureRunner在这种情况下的Cucumber )抛出的。

所以你的例子变成:

@Before("@skiponchrome") // this works
public void beforeScenario() {
  if(currentBrowser == 'chrome') { // this works
    throw new AssumptionViolatedException("Not supported on Chrome")
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您以前使用过 vanilla JUnit 4,您会记得@Ignore当运行程序忽略测试时,它会显示一个可选消息。AssumptionViolatedException携带消息,因此您应该在以这种方式跳过测试后在测试输出中看到它,而不必编写自己的自定义运行程序。


Kar*_*c.K 4

我也遇到了同样的挑战,我需要根据在运行时从应用程序动态获取的标志跳过运行场景,该标志告诉应用程序是否启用了要测试的功能。

这就是我在场景文件中编写逻辑的方式,其中每个步骤都有粘合代码。

我使用了一个独特的标签“@Feature-01AXX”来标记仅当该功能(代码)在应用程序上可用时才需要运行的场景。

因此,对于每个场景,首先检查标签“@Feature-01XX”,如果存在,则检查该功能的可用性,然后才会选择该场景来运行。否则它只会被跳过,Junit 不会将其标记为失败,而是将其标记为通过。因此,如果由于该功能不可用而导致这些测试未运行,最终结果将通过,这很酷......

@Before
public void before(final Scenario scenario) throws Exception {
    /*
        my other pre-setup tasks for each scenario.
    */

    // get all the scenario tags from the scenario head.
    final ArrayList<String> scenarioTags = new ArrayList<>();
    scenarioTags.addAll(scenario.getSourceTagNames());

    // check if the feature is enabled on the appliance, so that the tests can be run.
    if (checkForSkipScenario(scenarioTags)) {
        throw new AssumptionViolatedException("The feature 'Feature-01AXX' is not enabled on this appliance, so skipping");
    }
}

private boolean checkForSkipScenario(final ArrayList<String> scenarioTags) {
    // I use a tag "@Feature-01AXX" on the scenarios which needs to be run when the feature is enabled on the appliance/application
    if (scenarioTags.contains("@Feature-01AXX") && !isTheFeatureEnabled()) { // if feature is not enabled, then we need to skip the scenario.
        return true;
    }
    return false;
}

private boolean isTheFeatureEnabled(){
    /*
        my logic to check if the feature is available/enabled on the application.
        in my case its an REST api call, I parse the JSON and check if the feature is enabled.
        if it is enabled return 'true', else return 'false'
    */
}
Run Code Online (Sandbox Code Playgroud)