简体   繁体   English

黄瓜测试用例一起运行时会失败,但是当我单独运行它们时它们会通过

[英]Cucumber test cases fail when run together, but they pass when I run them individually

I am using Spring with Cucumber (and IntelliJ and Gradle). 我正在将Spring与Cucumber(以及IntelliJ和Gradle)一起使用。 My test case fails when run together and passes when run individually. 我的测试用例一起运行时失败,而单独运行时通过。 (The fails 2 out of 3 times, sometimes it works...) (3次中有2次失败,有时它可以工作...)

I also tried to quarantine the problematic Scenario or Senario combinations, but no luck... I tried introducing @After and @Before hooks to reset the value of of the account value... I even tried switching the position of senarios, nothing helps... 我也尝试隔离有问题的Scenario或Senario组合,但是没有运气...我尝试引入@After和@Before挂钩来重置帐户值的值...我什至尝试切换senarios的位置,没有任何帮助...

I really hope someone can help me with this problem 我真的希望有人可以帮助我解决这个问题

The features: 特点:

Feature: Cash Withdrawal
  Scenario: Successful withdrawal from an account in credit
    Given my account has been credited with $100.00
    When I withdraw $20
    Then $20 should be dispensed
    And the balance of my account should be $80.00
  Scenario: Unsuccessful withdrawal due to technical fault
    Given my account is in credit
    But the cash slot has developed a fault
    When I request some of my money
    Then I should see an out-of-order message
    And $0 should be dispensed
    And the balance of my account should be unchanged
  Scenario: Unsuccessful withdrawal due to insufficient ATM funds
    Given my account is in credit
    And the ATM contains $10
    When I withdraw $20
    Then I should see an ask-for-less-money message
    And $0 should be dispensed
    And the balance of my account should be unchanged

And my stepdefinitions: 和我的stepdefinitions:

public class AccountSteps {

    @Autowired
    Account account;

    private Money originalBalance;

    @Given("^my account has been credited with (\\$\\d+\\.\\d+)$")
    public void myAccountHasBeenCreditedWith$(
            @Transform(MoneyConverter.class) Money amount)
            throws Throwable {
        account.credit(amount);
    }

    @Given("^my account is in credit$")
    public void myAccountIsInCredit$() throws Throwable {
        originalBalance = new Money(30, 00);
        account.credit(originalBalance);
    }

    @Then("^the balance of my account should be unchanged$")
    public void theBalanceOfMyAccountShouldBeUnchanged() throws Throwable {

        checkBalanceIs(originalBalance);
    }

    @Then("^the balance of my account should be (\\$\\d+\\.\\d+)$")
    public void theBalanceOfMyAccountShouldBe$(
            @Transform(MoneyConverter.class) Money amount) throws Throwable {

        checkBalanceIs(amount);
    }

    private void checkBalanceIs(Money amount) throws Throwable {
        int timeoutMilliSecs = 3000;
        int pollIntervalMilliSecs = 100;

        while (!account.getBalance().equals(amount) && timeoutMilliSecs > 0) {
            Thread.sleep(pollIntervalMilliSecs);
            timeoutMilliSecs -= pollIntervalMilliSecs;
        }

        Assert.assertEquals(
                "Incorrect account balance -",
                amount,
                account.getBalance());
    }
}

public class CashSlotSteps {

    @Autowired
    TestCashSlot cashSlot;

    @Given("^\\$(\\d+) should be dispensed$")
    public void $ShouldBeDispensed(int dollars) throws Throwable {
        Assert.assertEquals("Incorrect amount dispensed -", dollars,
                cashSlot.getContents());
    }

    @Given("^the cash slot has developed a fault$")
    public void theCashSlotHasDevelopedAFault() throws Throwable {
        cashSlot.injectFault();
    }

    @Given("^the ATM contains \\$(\\d+)$")
    public void theATMContains$(int dollars) throws Throwable {
        cashSlot.load(dollars);
    }
}

public class TellerSteps {

    @Autowired
    private Account account;

    @Autowired
    private AtmUserInterface teller;

    @When("^I withdraw \\$(\\d+)$")
    public void iWithdraw$(int amount) throws Throwable {
        teller.withdrawFrom(account, amount);
    }

    @Given("^I request some of my money$")
    public void iRequestSomeOfMyMoney() {
        int dollarsRequested = 10;
        teller.withdrawFrom(account, dollarsRequested);
    }

    @Then("^I should see an out-of-order message$")
    public void iShouldSeeAnOutOfOrderMessage() throws Throwable {
        Assert.assertTrue(
                "Expected error message not displayed",
                teller.isDisplaying("Out of order"));
    }

    @Then("^I should see an ask-for-less-money message$")
    public void iShouldSeeAnAskForLessMoneyMessage() throws Throwable {
        Assert.assertTrue(
                "Expected error message not displayed",
                teller.isDisplaying("Insufficient ATM funds"));
    }
}

You are obviously mutating a variable which is shared between two tests which is not getting reset. 您显然正在变异一个变量,该变量在两个未重置的测试之间共享。

This is usually 通常是

  1. A static mutable variable 静态可变变量
  2. A member variable on a singleton service 单例服务上的成员变量

I'm not sure how you are managing your services but if using spring you might want to investigate @DirtiesContext for case 2. Eg: 我不确定您如何管理服务,但是如果使用spring,则可能需要研究案例2的@DirtiesContext 。例如:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={...}) 
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class MyTest { ... }

Further info here 这里的更多信息

I have some hooks, for this example. 对于这个例子,我有一些勾子。 To delete the account. 删除帐户。

public class ResetHooks {
    @Before(order = 1)
    public void reset() {
        System.setProperty("webdriver.gecko.driver","C:\\...\\geckodriver.exe");
        if (!Base.hasConnection()) {
            Base.open(
                    "com.mysql.jdbc.Driver",
                    "jdbc:mysql://localhost/bank",
                    "user", "password");
        }

        Account.deleteAll();

        TransactionQueue.clear();
    }

}

-------------edit---------- - - - - - - -编辑 - - - - -

My Cumcumber xml for spring: 我的春季Cumcumber xml:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config/>

    <context:component-scan base-package="hooks, nicebank, support" />

    <bean class="support.AtmUserInterface" scope="cucumber-glue" />
    <bean class="support.TestCashSlot" scope="cucumber-glue" />

    <bean class="support.AccountFactory" factory-method="createTestAccount"
          lazy-init="true" scope="cucumber-glue" />

    <bean class="org.openqa.selenium.support.events.EventFiringWebDriver"
          scope="cucumber-glue" destroy-method="close">
        <constructor-arg>
            <bean class="org.openqa.selenium.firefox.FirefoxDriver"
                  scope="cucumber-glue"/>
        </constructor-arg>
    </bean>
</beans>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 JUnit测试在一起运行时失败,但是单独传递 - JUnit tests fail when run together, but pass individually 春季单元测试失败为组,但单独通过 - Spring-run Unit Tests Fail as Group, but Pass Individually [qaf]当我使用testng xml运行Z1441F19754335CA6ZEA8测试案例时如何与spring集成 - [qaf]how to integrate with spring when I use testng xml to run cucumber test case JUnit 测试只有在我一一运行时才能通过。 可能是错误的线程 - JUnit tests pass only when I run them one by one. Probably incorrect threading 运行测试时排除 SpringApplicationRunListener - Exclude SpringApplicationRunListener when run test 尝试运行Spring Boot Web测试用例时获取异常。 例外情况:java.lang.NoClassDefFoundError:AsyncRequestTimeoutException - Getting Exception when Trying to run Spring Boot Web test cases. Excpetions : java.lang.NoClassDefFoundError: AsyncRequestTimeoutException 同时运行Spring测试用例不是顺序的 - Run Spring test cases concurrently not sequentially 我使用resttemplate来测试我的Web服务,但是当我运行测试时,我与应用程序有错误连接 - I use resttemplate to test my web service but when I run the test I have an error connection to the application 我运行作业时springBatch中的ItemReadListener无法运行 - ItemReadListener in springBatch not run when I run job 尝试使用Spring运行jUnit测试时出现NoSuchFieldError - NoSuchFieldError when trying to run a jUnit test with Spring
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM