java - 钩子(Hook) @Before 和 @after 在开始时被调用两次

标签 java junit automated-tests cucumber hook

我对自动化测试和 Cucumber 也很陌生。我编写了一个简单的 cucumber-Junit 示例,包含三种场景。

我期望在每个场景开始时调用 @Before ,并在每个场景之后调用 @After 。因此,由于存在三种情况,它们总共应该只执行三次。

当我运行以下步骤定义时,首先调用@Before,然后调用@After,然后再次调用@Before,然后场景1,然后@After,然后@Before,然后场景2,然后@After,然后直接场景3。因此没有@Before@After分别在场景3之前和之后调用。另一方面,它们在第一个场景执行之前被调用两次。知道我在这里做错了什么吗?我的 Hook 项目中没有任何 .rb 文件。

我的@Before包含:System.out.println("Setup Performed");我的@After包含System.out.println("CleanUp Performed");

import cucumber.api.PendingException;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

public class CalculatorSteps {
    private Calculator calculator;

    @Before
    public void setUp() {
        calculator = new Calculator();
        System.out.println("Setup Performed...");
    }

    //Scenario : add two numbers - With regular expression
    @Given("^I have a calculator$")
    public void i_have_a_calculator() {
        assertNotNull(calculator);
    }

    @When("^I add (\\d+) and (\\d+)$")
    public void i_add(int arg1, int arg2) {
        calculator.add(arg1, arg2);
    }

    @Then("^the result should be (\\d+)$")
    public void the_result_should_be(int result) {
        assertEquals(result, calculator.getResult());
    }

    //Scenario : Subtract one number from another - With regular expression

    @Given("^I have a calculatorr$")
    public void i_have_a_calculator1() throws Throwable {
        assertNotNull(calculator);
    }

    @When("^I subtract (\\d+.\\d+) from (\\d+.\\d+)$")
    public void i_subtract_from(int arg1, int arg2) {
    calculator.subtract(arg1, arg2);
    }

    @Then("^the result should be (\\d+.\\d+)$")
    public void the_result_should_be1(double result1) {
        assertEquals(result1, calculator.getresult1(), 0.5);
    } 

    @After
    public void cleanUp() {
        System.out.println("CleanUp Performed...");
    }
}

功能文件如下所示:

    Feature: Calculator
      I use Calculator instead of calculating myself

      #Scenario: Add two numbers
        #Given I have a calculator
        #When I add 2 and 3
        #Then the result should be 5

     @smokeTest
      Scenario Outline: Add two numbers
        Given I have a calculator
            When I add <num1> and <num2>
        Then the result should be <ans>

        Examples:
        | num1 | num2 | ans |
        | 2    | 3    | 5   |
        | 4    | 5    | 9   |

      @regressionTest
      Scenario: Subtract one number from another
        Given I have a calculator
        When I subtract 2.5 from 7.5
        Then the result should be 5.0

输出如下:

    Feature: Calculator
      I use Calculator instead of calculating myself
    Setup Performed...
    CleanUp Performed...
    Setup Performed...

      Scenario Outline: Add two numbers # src/test/java/cucumber/junit/maven/cucumber_jvm/maven/calculatorFeature.feature:19
        Given I have a calculator       # CalculatorSteps.i_have_a_calculator()
        When I add 2 and 3              # CalculatorSteps.i_add(int,int)
        Then the result should be 5     # CalculatorSteps.the_result_should_be(int)
    CleanUp Performed...
    Setup Performed...

      Scenario Outline: Add two numbers # src/test/java/cucumber/junit/maven/cucumber_jvm/maven/calculatorFeature.feature:20
        Given I have a calculator       # CalculatorSteps.i_have_a_calculator()
        When I add 4 and 5              # CalculatorSteps.i_add(int,int)
        Then the result should be 9     # CalculatorSteps.the_result_should_be(int)
    CleanUp Performed...

      #@regressionTest
      Scenario: Subtract one number from another # src/test/java/cucumber/junit/maven/cucumber_jvm/maven/calculatorFeature.feature:23
        Given I have a calculator                # CalculatorSteps.i_have_a_calculator()
        When I subtract 2.5 from 7.5             # CalculatorSteps.i_subtract_from(int,int)
        Then the result should be 5.0            # CalculatorSteps.the_result_should_be1(double)

    3 Scenarios (3 passed)
    9 Steps (9 passed)
    0m0,074s

在尝试了 counter 和 @DaveyDaveDave 代码后,输出如下所示: 开头的计数器行的打印位置不正确,但至少可以正确执行。但我仍然想知道为什么在最后一个 Subtract 场景中它不执行 @Before@Given@After

Feature: Calculator
  I use Calculator instead of calculating myself
@Before Count is: 0
@Given Count is: 1
@After Count is: 2
@Before Count is: 3

  @smokeTest
  Scenario Outline: Add two numbers # src/test/java/cucumber/junit/maven/cucumber_jvm/maven/calculatorFeature.feature:19
    Given I have a calculator       # CalculatorSteps.i_have_a_calculator()
    When I add 2 and 3              # CalculatorSteps.i_add(int,int)
    Then the result should be 5     # CalculatorSteps.the_result_should_be(int)
@Given Count is: 4
@After Count is: 5
@Before Count is: 6

  @smokeTest
  Scenario Outline: Add two numbers # src/test/java/cucumber/junit/maven/cucumber_jvm/maven/calculatorFeature.feature:20
    Given I have a calculator       # CalculatorSteps.i_have_a_calculator()
    When I add 4 and 5              # CalculatorSteps.i_add(int,int)
    Then the result should be 9     # CalculatorSteps.the_result_should_be(int)
@After Count is: 7

  @regressionTest
  Scenario: Subtract one number from another # src/test/java/cucumber/junit/maven/cucumber_jvm/maven/calculatorFeature.feature:23
    #Given I have a calculator
    When I subtract 2.5 from 7.5             # CalculatorSteps.i_subtract_from(int,int)
    Then the result should be 5.0            # CalculatorSteps.the_result_should_be1(double)

3 Scenarios (3 passed)
8 Steps (8 passed)
0m0,072s

最佳答案

我认为该功能按照您期望的顺序执行,这只是输出如何以及何时出现的问题。

我刚刚复制并粘贴了您的源代码,并添加了一个 counter 变量,当我运行它时,我看到以下输出:

Setup Performed... 0
In given...1
...CleanUp Performed... 2
Setup Performed... 3
In given...4
...CleanUp Performed... 5
Setup Performed... 6
In given...7
...CleanUp Performed... 8

换句话说,数字表明这些事情的顺序正在按照您的预期发生。

如果这有助于说服您,我创建了以下 RequiresSetupCalculator,如果在执行操作之前尚未设置它,或者如果我们尝试在之前没有调用 cleanUp 的情况下运行设置,它会引发异常。

public class RequiresSetupCalculator {
  private static RequiresSetupCalculator instance;

  private int result = 0;
  private double result1 = 0;

  private boolean isSetup;

  private RequiresSetupCalculator() {
  }

  public static synchronized RequiresSetupCalculator setup() {
    if (instance == null) {
        instance = new RequiresSetupCalculator();
    }

    if (instance.isSetup) {
        throw new RuntimeException("I have already been set up");
    }

    instance.isSetup = true;

    return instance;
  }

  public void cleanUp() {
    if (!isSetup) {
        throw new RuntimeException("I wasn't set up in the first place");
    }

    isSetup = false;
  }

  public void add(final int arg1,
                final int arg2) {
    if (!isSetup) {
        throw new RuntimeException("I haven't been set up, no calculating for you!");
    }

    result = arg1 + arg2;
  }

  public int getResult() {
    if (!isSetup) {
        throw new RuntimeException("I haven't been set up, no calculating for you!");
    }

    return result;
  }

  public void subtract(final int arg1,
                     final int arg2) {
    if (!isSetup) {
        throw new RuntimeException("I haven't been set up, no calculating for you!");
    }

    result1 = arg2 - arg1;
  }

  public double getresult1() {
    if (!isSetup) {
        throw new RuntimeException("I haven't been set up, no calculating for you!");
    }

    return result1;
  }
}

要对此进行测试,如果将上述内容与现有的 Calculator 一起复制到新类中,则修改 CalculatorSteps 以使用 RequiresSetupCalculator 并在测试的 @Before@After 方法中调用 setupcleanUp 方法,如下所示:

public class CalculatorSteps {
  private RequiresSetupCalculator calculator;

  @Before
  public void setUp() {
    calculator = RequiresSetupCalculator.setup();
    System.out.println("Setup Performed...");
  }

  ... (existing test steps unchanged)...

  @After
  public void cleanUp() {
    System.out.println("CleanUp Performed...");
    calculator.cleanUp();
  }
}

现在,当您运行测试时,如果它仍然通过,我想我们可以确定 @Before 方法在每个测试之前运行一次且仅一次,并且 @After 方法在每个测试之后运行一次且仅一次。

对我来说,这是成功的。如果您在运行测试时抛出异常,那么就会发生一些奇怪的事情,但我相当有信心您会得到与我相同的结果。

关于java - 钩子(Hook) @Before 和 @after 在开始时被调用两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45484026/

相关文章:

java - Selenium WebDriver 的密码键盘问题

Java计算器崩溃了

java - 有没有办法自动化 junit bean 属性测试?

java - 线程 "main"java.lang.NoClassDefFoundError : junit/textui/ResultPrinter 中的异常

java - 从自动化测试套件中排除一些 JUnit 测试

c# - 自动生成 .NET 单元测试

node.js - 如何使用 local.example.js ENV 运行测试

Java For 循环错误

java - 如何使用关键帧更改 JavaFX 标签的文本填充?

java - Android 中的设备到设备通信