tro*_*oig 40 java cucumber cucumber-jvm
要在步骤之间传递变量,我现在做的事情如下:
Feature: Demo
Scenario: Create user
Given User creation form management
When Create user with name "TEST"
Then User is created successfully
Run Code Online (Sandbox Code Playgroud)
带有步骤定义的Java类:
public class CreateUserSteps {
private String userName;
@Given("^User creation form management$")
public void User_creation_form_management() throws Throwable {
// ...
}
@When("^Create user with name \"([^\"]*)\"$")
public void Create_user_with_name(String userName) throws Throwable {
//...
this.userName = userName;
}
@Then("^User is created successfully$")
public void User_is_created_successfully() throws Throwable {
// Assert if exists an user with name equals to this.userName
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果在步骤之间共享信息是好的做法吗?或者更好地将功能定义为:
Then User with name "TEST" is created successfully
Run Code Online (Sandbox Code Playgroud)
我是黄瓜jvm的新手,如果这是一个没脑子的问题,那就很抱歉.
任何帮助,将不胜感激.谢谢
Ped*_*pez 33
为了分享您需要使用世界的步骤之间的共性.在Java中,它并不像Ruby那样清晰.
引用黄瓜的创造者.
"世界"的目的有两个:
1)在场景之间隔离状态.
2)在场景中的步骤定义和挂钩之间共享数据.
如何实现这是特定于语言的.例如,在ruby中,
self步骤定义中的隐式变量指向当前场景的World对象.默认情况下,这是Object的一个实例,但如果您使用World钩子,它可以是您想要的任何内容.在Java中,您有许多(可能已连接)World对象.
与Cucumber-Java中的World相同的是具有hook或stepdef注释的所有对象.换句话说,任何带有@ Before,@ After,@ Given等注释方法的类都将针对每个场景实例化一次.
这实现了第一个目标.要实现第二个目标,您有两种方法:
a)对所有步骤定义和挂钩使用单个类
b)使用由责任[1]划分的几个类,并使用依赖注入[2]将它们相互连接.
选项a)快速分解,因为您的步骤定义代码变得混乱.这就是人们倾向于使用b)的原因.
[1] https://github.com/cucumber/cucumber/wiki/Step-Organization
[2] PicoContainer,Spring,Guice,Weld,OpenEJB,Needle
可用的依赖注入模块是:
原帖在这里https://groups.google.com/forum/#!topic/cukes/8ugcVreXP0Y.
希望这可以帮助.
可以使用实例变量在类中定义的步骤之间共享数据.如果您需要在不同类的步骤之间共享数据,您应该查看DI集成(PicoContainer是最简单的).
在您显示的示例中,我会询问是否有必要在场景中显示"TEST".用户称为TEST的事实是偶然的细节,使得场景的可读性降低.为什么不在Create_user_with_name()中生成随机名称(或硬代码)?
我想说的是,有理由在步骤之间共享信息,但我认为在这种情况下情况并非如此。如果您通过测试步骤传播用户名,那么从该功能中并不清楚发生了什么。我认为最好在场景中具体说明预期的内容。我可能会做这样的事情:
Feature: Demo
Scenario: Create user
Given User creation form management
When Create user with name "TEST"
Then A user named "TEST" has been created
Run Code Online (Sandbox Code Playgroud)
然后,您的实际测试步骤可能类似于:
@When("^Create user with name \"([^\"]*)\"$")
public void Create_user_with_name(String userName) throws Throwable {
userService.createUser(userName);
}
@Then("^A user named \"([^\"]*)\" has been created$")
public void User_is_created_successfully(String userName) throws Throwable {
assertNotNull(userService.getUser(userName));
}
Run Code Online (Sandbox Code Playgroud)
小智 5
在纯 java 中,我只使用一个单例对象,该对象创建一次并在测试后清除。
public class TestData_Singleton {
private static TestData_Singleton myself = new TestData_Singleton();
private TestData_Singleton(){ }
public static TestData_Singleton getInstance(){
if(myself == null){
myself = new TestData_Singleton();
}
return myself;
}
public void ClearTestData(){
myself = new TestData_Singleton();
}
Run Code Online (Sandbox Code Playgroud)
这是我的方式:我用 spring 定义了一个自定义场景范围\每个新场景都会有一个新的上下文
\n\nFeature @Dummy\n Scenario: zweites Scenario\n When Eins\n Then Zwei\nRun Code Online (Sandbox Code Playgroud)\n\n1:使用弹簧
\n\n<properties>\n<cucumber.version>1.2.5</cucumber.version>\n<junit.version>4.12</junit.version>\n</properties>\n\n<!-- cucumber section -->\n\n\n<dependency>\n <groupId>info.cukes</groupId>\n <artifactId>cucumber-java</artifactId>\n <version>${cucumber.version}</version>\n <scope>test</scope>\n</dependency>\n<dependency>\n <groupId>info.cukes</groupId>\n <artifactId>cucumber-junit</artifactId>\n <version>${cucumber.version}</version>\n <scope>test</scope>\n</dependency>\n<dependency>\n <groupId>junit</groupId>\n <artifactId>junit</artifactId>\n <version>${junit.version}</version>\n <scope>test</scope>\n</dependency>\n\n <dependency> \n <groupId>info.cukes</groupId> \n <artifactId>cucumber-spring</artifactId> \n <version>${cucumber.version}</version> \n <scope>test</scope> \n </dependency> \n\n\n<!-- end cucumber section -->\n\n<!-- spring-stuff -->\n<dependency> \n <groupId>org.springframework</groupId> \n <artifactId>spring-test</artifactId> \n <version>4.3.4.RELEASE</version> \n <scope>test</scope> \n </dependency> \n\n <dependency> \n <groupId>org.springframework</groupId> \n <artifactId>spring-context</artifactId> \n <version>4.3.4.RELEASE</version> \n <scope>test</scope>\n </dependency> \n <dependency> \n <groupId>org.springframework</groupId> \n <artifactId>spring-tx</artifactId> \n <version>4.3.4.RELEASE</version> \n <scope>test</scope>\n </dependency> \n <dependency> \n <groupId>org.springframework</groupId> \n <artifactId>spring-core</artifactId> \n <version>4.3.4.RELEASE</version> \n <scope>test</scope>\n <exclusions> \n <exclusion> \n <groupId>commons-logging</groupId> \n <artifactId>commons-logging</artifactId> \n </exclusion> \n </exclusions> \n </dependency> \n <dependency> \n <groupId>org.springframework</groupId> \n <artifactId>spring-beans</artifactId> \n <version>4.3.4.RELEASE</version> \n <scope>test</scope>\n </dependency> \n\n <dependency> \n <groupId>org.springframework.ws</groupId> \n <artifactId>spring-ws-core</artifactId> \n <version>2.4.0.RELEASE</version> \n <scope>test</scope>\n </dependency> \nRun Code Online (Sandbox Code Playgroud)\n\n2:构建自定义范围类
\n\nimport org.springframework.context.annotation.Scope;\nimport org.springframework.stereotype.Component;\n\n@Component\n@Scope(scopeName="scenario")\npublic class ScenarioContext {\n\n public Scenario getScenario() {\n return scenario;\n }\n\n public void setScenario(Scenario scenario) {\n this.scenario = scenario;\n }\n\n public String shareMe;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n3:stepdef中的用法
\n\n@ContextConfiguration(classes = { CucumberConfiguration.class })\npublic class StepdefsAuskunft {\n\nprivate static Logger logger = Logger.getLogger(StepdefsAuskunft.class.getName());\n\n@Autowired\nprivate ApplicationContext applicationContext;\n\n// Inject service here : The impl-class need @Primary @Service\n// @Autowired\n// IAuskunftservice auskunftservice;\n\n\npublic ScenarioContext getScenarioContext() {\n return (ScenarioContext) applicationContext.getBean(ScenarioContext.class);\n}\n\n\n@Before\npublic void before(Scenario scenario) {\n\n ConfigurableListableBeanFactory beanFactory = ((GenericApplicationContext) applicationContext).getBeanFactory();\n beanFactory.registerScope("scenario", new ScenarioScope());\n\n ScenarioContext context = applicationContext.getBean(ScenarioContext.class);\n context.setScenario(scenario);\n\n logger.fine("Context f\xc3\xbcr Scenario " + scenario.getName() + " erzeugt");\n\n}\n\n@After\npublic void after(Scenario scenario) {\n\n ScenarioContext context = applicationContext.getBean(ScenarioContext.class);\n logger.fine("Context f\xc3\xbcr Scenario " + scenario.getName() + " gel\xc3\xb6scht");\n\n}\n\n\n\n@When("^Eins$")\npublic void eins() throws Throwable {\n System.out.println(getScenarioContext().getScenario().getName());\n getScenarioContext().shareMe = "demo"\n // you can save servicecall here\n}\n\n@Then("^Zwei$")\npublic void zwei() throws Throwable {\n System.out.println(getScenarioContext().getScenario().getName());\n System.out.println(getScenarioContext().shareMe);\n // you can use last service call here\n}\n\n\n@Configuration\n @ComponentScan(basePackages = "i.am.the.greatest.company.cucumber")\n public class CucumberConfiguration {\n }\nRun Code Online (Sandbox Code Playgroud)\n\n范围类别
\n\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.springframework.beans.factory.ObjectFactory;\nimport org.springframework.beans.factory.config.Scope;\n\n\npublic class ScenarioScope implements Scope {\n\n\n private Map<String, Object> objectMap = Collections.synchronizedMap(new HashMap<String, Object>());\n\n /** (non-Javadoc)\n * @see org.springframework.beans.factory.config.Scope#get(java.lang.String, org.springframework.beans.factory.ObjectFactory)\n */\n public Object get(String name, ObjectFactory<?> objectFactory) {\n if (!objectMap.containsKey(name)) {\n objectMap.put(name, objectFactory.getObject());\n }\n return objectMap.get(name);\n\n }\n\n /** (non-Javadoc)\n * @see org.springframework.beans.factory.config.Scope#remove(java.lang.String)\n */\n public Object remove(String name) {\n return objectMap.remove(name);\n }\n\n /** (non-Javadoc)\n * @see org.springframework.beans.factory.config.Scope#registerDestructionCallback(java.lang.String, java.lang.Runnable)\n */\n public void registerDestructionCallback(String name, Runnable callback) {\n // do nothing\n }\n\n /** (non-Javadoc)\n * @see org.springframework.beans.factory.config.Scope#resolveContextualObject(java.lang.String)\n */\n public Object resolveContextualObject(String key) {\n return null;\n }\n\n /** (non-Javadoc)\n * @see org.springframework.beans.factory.config.Scope#getConversationId()\n */\n public String getConversationId() {\n return "VolatileScope";\n }\n\n /**\n * vaporize the beans\n */\n public void vaporize() {\n objectMap.clear();\n }\n\n\n}\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
65950 次 |
| 最近记录: |