简体   繁体   English

Cucumber - Java8 - 在 lambda 表达式中使用 @Before

[英]Cucumber - Java8 - using @Before with lambda expressions

I have a Java selenium project set up using cucumber.我有一个使用黄瓜设置的 Java selenium 项目。 Step definitions are in a set of files that reuse code from a BaseDefinitions file, as follows:步骤定义位于一组重用 BaseDefinitions 文件中的代码的文件中,如下所示:

(Example curtailed to first @Given statement): (示例缩减为第一个@Given 语句):

public class GoogleDefinitions {

    private BaseDefinitions baseDefinitions;
    private WebDriver driver;

    public GoogleDefinitions (BaseDefinitions baseDefinitions) {
        this.baseDefinitions = baseDefinitions;
        this.driver = baseDefinitions.getDriver();
    }

    @Given("^I visit the Google search page$")
    public void iVisitTheGoogleSearchPage() {
        GoogleSearchHomepage googleSearchHomepage = new GoogleSearchHomepage(driver);
        googleSearchHomepage.visit();
    }
}

The BaseDefinitions file (short version) looks as follows: BaseDefinitions 文件(简短版本)如下所示:

public class BaseDefinitions {

    private WebDriver driver;


    @Before
    public void setUp(Scenario scenario) throws Exception {
        String path = getClass()
                .getClassLoader()
                .getResource("chromedriver.exe")
                .getPath();
        System.setProperty("webdriver.chrome.driver", path);
        driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }

    @After
    public void teardown() {
        driver.close();
        try {
            driver.quit();
        }
        catch(Exception e) {
            System.out.println("Caught driver error on quit.");
        }
    }

    public WebDriver getDriver() {
        return driver;
    }
}

This works fine - glue code etc is all set up correctly.这很好用 - 胶水代码等都设置正确。 However, with updates, Cucumber is now generating lambda expressions rather than the format used before.但是,通过更新,Cucumber 现在生成 lambda 表达式,而不是以前使用的格式。 I am confused as to how to implement these.我对如何实现这些感到困惑。

  • If I implement them in the constructor (as discussed here ), then the @Before statement of the BaseDefinitions file is only executed after the test when I run the feature - this is of no use.如果我在构造函数中实现它们(如这里所讨论的),那么 BaseDefinitions 文件的 @Before 语句仅在我运行该功能时在测试之后执行 - 这没有用。
  • If I put them in a method, as shown here , when I run the feature file it runs the @Before statement but does not find the step definitions.如果我把它们放在一个方法,如图所示这里,当我运行的特征文件运行的@Before声明,但没有找到步骤定义。

Below is an example with the lambdas implemented in a method.下面是在方法中实现的 lambda 表达式的示例。 When I run this it gives me You can implement missing steps with the snippets below: :当我运行它时,它给了我You can implement missing steps with the snippets below: ::

public class lambdaTestDefinitions implements En {
    private BaseDefinitions baseDefinitions;
    private WebDriver driver;

    public lambdaTestDefinitions(BaseDefinitions baseDefinitions) {
        this.baseDefinitions = baseDefinitions;
        this.driver = baseDefinitions.getDriver();
    }

    private void testLambdaSteps () {
        Given("I try to navigate to www.google.co.uk", () -> {
            driver.get("http://www.google.co.uk");
        });

        Then("I should be on the Google home page", () -> {
            // Write code here that turns the phrase above into concrete actions
            Assert.assertEquals(driver.getCurrentUrl(), "http://www.google.co.uk");
        });
    }
}

Clearly I am missing something - how do I get this to work?显然我错过了一些东西 - 我如何让它发挥作用?

EDIT: Here is my build.gradle.编辑:这是我的 build.gradle。 From what I can see I am not using the Java8 version of Cucumber, which I don't really understand either:从我所看到的,我没有使用 Cucumber 的 Java8 版本,我也不太明白:

buildscript {
    repositories {
        mavenCentral()
    }
}

plugins {
    id 'java'
    //id "com.github.spacialcircumstances.gradle-cucumber-reporting" version "0.1.2"
}

group 'org.myorg'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
    jcenter()
}

project.ext {
    cucumberVersion = '4.0.0'
}

dependencies {
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.5.1'
    testCompile group: 'junit', name: 'junit', version: '4.12'
    testCompile 'io.cucumber:cucumber-java:' + cucumberVersion
    testCompile 'io.cucumber:cucumber-junit:' + cucumberVersion
    testCompile group: 'com.browserstack', name: 'browserstack-local-java', version:'1.0.1'
    testCompile group: 'io.cucumber', name: 'cucumber-picocontainer', version: '2.1.0'
    testCompile group: 'org.hamcrest', name: 'hamcrest-all', version: '1.3'
    testCompile group: 'org.testng', name: 'testng', version: '6.9.10'
    testCompile 'io.github.prashant-ramcharan:courgette-jvm:3.1.0'
}

test {
    systemProperties System.getProperties()
    ignoreFailures = true

    systemProperty "localBrowser", System.getProperty("localBrowser")
    systemProperty "browserstackLocal", System.getProperty("browserstackLocal")
    systemProperty "browser", System.getProperty("browser")
    testLogging.showStandardStreams = true

    test.outputs.upToDateWhen {false}
}

This works fine - glue code etc is all set up correctly.这很好用 - 胶水代码等都设置正确。 However, with updates, Cucumber is now generating lambda expressions rather than the format used before.但是,通过更新,Cucumber 现在生成 lambda 表达式,而不是以前使用的格式。

You've added cucumber-java8 instead of cucumber-java to your dependencies.您已将cucumber-java8而不是cucumber-java到您的依赖项中。

If I put them in a method, as shown here, when I run the feature file it runs the @Before statement but does not find the step definitions.如果我将它们放在一个方法中,如此处所示,当我运行功能文件时,它会运行 @Before 语句,但找不到步骤定义。

That only works for some frameworks that extend Cucumber.这只适用于一些扩展 Cucumber 的框架。 The eclipse plugin however supports both notations.然而,eclipse 插件支持这两种表示法。

If I implement them in the constructor (as discussed here), then the @Before statement of the BaseDefinitions file is only executed after the test when I run the feature - this is of no use.如果我在构造函数中实现它们(如这里所讨论的),那么 BaseDefinitions 文件的 @Before 语句仅在我运行该功能时在测试之后执行 - 这没有用。

You are confusing the execution of the cucumber steps with the creation of the step definition.您将黄瓜步骤的执行与步骤定义的创建混淆了。 The creation of the step definition happens before any steps are invoked on it.步骤定义的创建发生在对其调用任何步骤之前。 this.driver = baseDefinitions.getDriver(); is called when creating GoogleDefinitions so always before the method that creates the driver.在创建GoogleDefinitions时调用,所以总是在创建驱动程序的方法之前调用。

Instead you should delay the call until the step is invoked.相反,您应该延迟调用,直到调用该步骤。

public class lambdaTestDefinitions implements En {
    public lambdaTestDefinitions(BaseDefinitions baseDefinitions) {

        Given("I try to navigate to www.google.co.uk", () -> {
            baseDefinitions.getDriver().get("http://www.google.co.uk");
        });

        Then("I should be on the Google home page", () -> {
            // Write code here that turns the phrase above into concrete actions
            assertEquals(baseDefinitions.getDriver().getCurrentUrl(), "http://www.google.co.uk");
        });
    }
}

You may also be interested in investigating the PicoContainers life cycle .您可能还对研究PicoContainers 生命周期感兴趣。 You can use Startable and Disposable .您可以使用StartableDisposable They can help you setup things that need to be setup before Cucumber starts a scenario.他们可以帮助您设置在 Cucumber 开始场景之前需要设置的内容。

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM