Cucumber jvm 单体DI用皮电容器

Cucumber jvm 单体DI用皮电容器,cucumber-jvm,Cucumber Jvm,我正在尝试将picocontainer用于DI,但仍然多次实例化我的共享对象,而不是将其作为单个对象自动管理。这里有一个例子来说明。类ASTEP和BSTEP通过其构造函数接收SharedObject实例。我希望picocontainer将它作为一个单例进行管理:根据Cucumber文档,只实例化一次。相反,我看到它为ASTEP实例化了一次,为BSTEP实例化了一次: Running my.domain.CucumberRunTest INFO [main] (CucumberHooks.jav

我正在尝试将picocontainer用于DI,但仍然多次实例化我的共享对象,而不是将其作为单个对象自动管理。这里有一个例子来说明。类ASTEP和BSTEP通过其构造函数接收SharedObject实例。我希望picocontainer将它作为一个单例进行管理:根据Cucumber文档,只实例化一次。相反,我看到它为ASTEP实例化了一次,为BSTEP实例化了一次:

Running my.domain.CucumberRunTest
 INFO [main] (CucumberHooks.java:15) - Executing before()
 INFO [main] (SharedObject.java:11) - SharedObject - instantiated
 INFO [main] (ASteps.java:21) - Executing a_step_one()
 INFO [main] (ASteps.java:26) - Executing a_step_two()
 INFO [main] (ASteps.java:31) - Executing a_step_three()
 INFO [main] (CucumberHooks.java:20) - Executing after()
 INFO [main] (CucumberHooks.java:15) - Executing before()
 INFO [main] (SharedObject.java:11) - SharedObject - instantiated
 INFO [main] (BSteps.java:23) - Executing b_step_one()
 INFO [main] (BSteps.java:28) - Executing b_step_two()
 INFO [main] (BSteps.java:33) - Executing b_step_three()
 INFO [main] (CucumberHooks.java:20) - Executing after()
我做错了什么?代码如下:

package my.domain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class ASteps {

final Logger log = LoggerFactory.getLogger(getClass());
SharedObject sharedObject;

public ASteps(SharedObject sharedObject) {
this.sharedObject = sharedObject;
}

@Given("^A step one$")
public void a_step_one() {
log.info("Executing a_step_one()");
}

@When("^A step two$")
public void a_step_two() {
log.info("Executing a_step_two()");
}

@Then("^A step three$")
public void a_step_three() {
log.info("Executing a_step_three()");
}
}

************************

package my.domain;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;

public class BSteps {

final Logger log = LoggerFactory.getLogger(getClass());
SharedObject sharedObject;

public BSteps(SharedObject sharedObject) {
this.sharedObject = sharedObject;
}

@Given("^B step one$")
public void b_step_one() {
log.info("Executing b_step_one()");
}

@When("^B step two$")
public void b_step_two() {
log.info("Executing b_step_two()");
}

@Then("^B step three$")
public void b_step_three() {
log.info("Executing b_step_three()");
}
}

************************

package my.domain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cucumber.api.java.After;
import cucumber.api.java.Before;

public class CucumberHooks {

final Logger log = LoggerFactory.getLogger(getClass());

@Before
public void before() {
log.info("Executing before()");
}

@After
public void after() {
log.info("Executing after()");

}
}

*********************

package my.domain;

import org.junit.runner.RunWith;

import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
public class CucumberRunTest {

}

**********************

package my.domain;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SharedObject {

final Logger log = LoggerFactory.getLogger(getClass());

public SharedObject() {
log.info("SharedObject - instantiated");
}
}

pico容器的缓存在两个场景之间,在场景结束时处理世界

这在很大程度上是按照设计进行的,以避免场景之间的状态泄漏,并将它们隔离,这样测试的顺序就不会影响结果


如果您确实希望在场景A和场景B之间保持状态,则您需要自己在pico容器之外处理SharedObject,或者您可以明确这两个场景之间的依赖关系–例如,使用。

pico容器的缓存在两个场景之间,当世界在场景结束时被处理掉

这在很大程度上是按照设计进行的,以避免场景之间的状态泄漏,并将它们隔离,这样测试的顺序就不会影响结果


如果您确实希望在场景A和场景B之间保持状态,您需要自己在pico容器之外处理SharedObject,或者您可以明确这两个场景之间的依赖关系–例如,使用。

我希望现在回答您的问题还不算太晚

事实上,你可以得到你想要的。 我看到您还希望有一个浏览器实例。 要做到这一点,必须使用静态对象。 我创建了一个小类,以避免在每次测试之间打开/关闭驱动程序。它由picocontainer管理。在stepDefinition类中,必须实现相同的构造函数

以下是一个示例:

public class myStepDefinition{
    private Drivers context;
    public myStepDefinition(Drivers context){
        this.context = context;
        // whatever you want to do
    }
}

public class Drivers {
    private static boolean initialized = false;
    private static WebDriver driver;

    @Before
    public void initialize(){
        if (!initialized){
            initialized = true;
            driver = new FirefoxDriver();
            driver.manage().window().maximize();
            driver.get("http://www.myurl.url");
        }
    }

    public static WebDriver getDriver(){
        return driver;
    }
}
请记住,每次测试通过或失败后,您必须返回登录页面或起始页面

问候,


尼古拉斯

我希望现在回答你的问题还不算太晚

事实上,你可以得到你想要的。 我看到您还希望有一个浏览器实例。 要做到这一点,必须使用静态对象。 我创建了一个小类,以避免在每次测试之间打开/关闭驱动程序。它由picocontainer管理。在stepDefinition类中,必须实现相同的构造函数

以下是一个示例:

public class myStepDefinition{
    private Drivers context;
    public myStepDefinition(Drivers context){
        this.context = context;
        // whatever you want to do
    }
}

public class Drivers {
    private static boolean initialized = false;
    private static WebDriver driver;

    @Before
    public void initialize(){
        if (!initialized){
            initialized = true;
            driver = new FirefoxDriver();
            driver.manage().window().maximize();
            driver.get("http://www.myurl.url");
        }
    }

    public static WebDriver getDriver(){
        return driver;
    }
}
请记住,每次测试通过或失败后,您必须返回登录页面或起始页面

问候,


尼古拉斯

谢谢塞巴斯蒂安,这非常有用。在这种情况下,我认为使用picocontainer没有多大价值,我可以用普通的旧局部变量得到相同的结果。我正在创建一个测试自动化框架,并希望为不同类型的资源定义不同的范围:场景范围的资源,例如WebDriver实例,或执行范围的资源,例如执行配置、DB连接和其他不可变或昂贵的资源。我仍然需要了解整个生命周期。你知道有什么好的资源吗?或者源代码是我最好的选择吗?@Pablo我恐怕一个都不知道——我通常会查看jvm源代码。然而,它们写得很好,所以有点容易理解。看看CucumbersScenarioRun,这是一个场景的神奇之处。谢谢塞巴斯蒂安,这非常有用。在这种情况下,我认为使用picocontainer没有多大价值,我可以用普通的旧局部变量得到相同的结果。我正在创建一个测试自动化框架,并希望为不同类型的资源定义不同的范围:场景范围的资源,例如WebDriver实例,或执行范围的资源,例如执行配置、DB连接和其他不可变或昂贵的资源。我仍然需要了解整个生命周期。你知道有什么好的资源吗?或者源代码是我最好的选择吗?@Pablo我恐怕一个都不知道——我通常会查看jvm源代码。然而,它们写得很好,所以有点容易理解。看看CucumbersScenarioRun,这是一个场景的神奇之处。