我对自动化测试和 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
方法中调用 setup
和 cleanUp
方法,如下所示:
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/