我想在每个SpecFlow测试的开头添加相同的行。
此行指定了一些随时间变化的场景列表,因此不可能为每个测试维护此列表。
例如:
Given I have set my site theme to <MyTheme>
|Theme Names|
|Theme 1 |
|Theme 2 |
|Theme 3 |
|Theme 4 |
|Theme 5 |
我希望每个主题都重复此测试。主题列表不是一成不变的,应该保存在一个地方。
到目前为止,我已成功设法创建Generator Plugin
,我计划在生成测试类之前立即使用此插件更改SpecFlow功能。但是,我无法在此上下文中看到编辑方案的方法。
是否可以从IUnitTestGeneratorProvider
的实现中获取和设置方案文本?
我没有开始使用这种方法,所以如果有人可以提出更好的方法来做到这一点,那么我也会接受。
如果我的某些术语出错了,我会道歉 - 我只是刚开始使用SpecFlow。
我添加此部分是为了澄清我实际上在追求的内容。
假设我有一个包含800个测试的测试套件。我们有业务要求在每个可用主题上运行800个测试中的每一个。可用主题列表可以随时更改,将此列表保留在多个位置是不可行的。
因此,例如,如果我进行了以下两项测试:
示例A:
Given I set context to < site >
Given I go to base url
When I type <username> in username field
When I type <password> in password field
When I click login button
Examples:
| site | username | password |
| MySuperSite | chris | mypassword |
| MySuperSite2 | chris2 | mypassword |
Given I am logged in
Given I go to base url
When I click logout button
Then I am logged out
我可以简单地手动将这些测试更改为:
例B:
Given I am using the < theme > theme
Given I set context to < site >
Given I go to base url
When I type <username> in username field
When I type <password> in password field
When I click login button
Examples:
| site | username | password | theme |
| MySuperSite | chris | mypassword | theme1 |
| MySuperSite2 | chris2 | mypassword | theme1 |
| MySuperSite | chris | mypassword | theme2 |
| MySuperSite2 | chris2 | mypassword | theme2 |
| MySuperSite | chris | mypassword | theme3 |
| MySuperSite2 | chris2 | mypassword | theme3 |
Given I am using the < theme > theme
Given I am logged in
Given I go to base url
When I click logout button
Then I am logged out
Examples:
| theme |
| theme1 |
| theme2 |
| theme3 |
这有一些问题:
theme2
,那么有人必须完成每个测试并将其从示例表中删除(在上面的示例中不是太糟糕,但是我们的成像是> 800次测试)< / LI>
目的:
我希望能够让我们的测试人员以Example A
的方式编写测试,但如果他们以Example B
的风格编写,那么测试本身就会编译成测试结果。
我已经为specflow创建了一个生成器插件,其中包含拦截测试创建的视图,然后以编程方式添加行Given I am using the < theme > theme
,然后根据需要更新或添加任何示例数据。但是,我似乎无法从这里做到这一点。
任何人都可以告诉我这是否可行,如果是的话,我应该怎么做呢?
答案 0 :(得分:5)
好的,我想出来了。它花了几个步骤:
在浏览GitHub上的源代码后,我发现UnitTestFeatureGenerator
似乎是负责将specflow文件转换为单元测试的类。
然后我创建了一个继承自UnitTestFeatureGenerator
的新类,并从基类中隐藏了GenerateUnitTestFixture
方法。
在我的GenerateUnitTestFixture
类的主体中,然后在移交base.GenerateUnitTestFixture
之前添加场景中所需的额外步骤以生成单元测试。这是它的要点:
public class MultiThemeUnitTestFeatureGenerator : UnitTestFeatureGenerator, IFeatureGenerator
{
public MultiThemeUnitTestFeatureGenerator(IUnitTestGeneratorProvider testGeneratorProvider, CodeDomHelper codeDomHelper, GeneratorConfiguration generatorConfiguration, IDecoratorRegistry decoratorRegistry)
: base(testGeneratorProvider, codeDomHelper, generatorConfiguration, decoratorRegistry)
{}
public new CodeNamespace GenerateUnitTestFixture(Feature feature, string testClassName, string targetNamespace)
{
foreach (var scenario in feature.Scenarios)
{
scenario.Steps.Insert(0, new Given {Text = "Given I have <Theme> set as my current theme"});
//add any other steps you need....
}
return base.GenerateUnitTestFixture(feature, testClassName, targetNamespace);
}
}
一旦我完成了所有这些设置,我需要一种方法来告诉specflow使用我的新类而不是当前注册的UnitTestFeatureGenerator
。这是一个复杂的工作,因为文档几乎只是说“即将推出”。谢天谢地,我found an excellent blog post which outlines all the pitfalls.
我的IGeneratorPlugin
实现如下:
public class MultiThemeGeneratorPlugin : IGeneratorPlugin
{
public void RegisterDependencies(ObjectContainer container)
{}
public void RegisterCustomizations(ObjectContainer container, SpecFlowProjectConfiguration generatorConfiguration)
{
container.RegisterTypeAs<MultiThemeFeatureGeneratorProvider, IFeatureGeneratorProvider>("default");
}
public void RegisterConfigurationDefaults(SpecFlowProjectConfiguration specFlowConfiguration)
{}
}
注意我注册IFeatureGeneratorProvider
而不是IFeatureGenerator
。我必须创建一个IFeatureGeneratorProvider
的实现,它返回我感兴趣的IFeatureGenerator
实现的实例:
public class MultiThemeFeatureGeneratorProvider : IFeatureGeneratorProvider
{
private readonly ObjectContainer _container;
public MultiThemeFeatureGeneratorProvider(ObjectContainer container)
{
_container = container;
}
public int Priority
{
get { return int.MaxValue; }
}
public bool CanGenerate(Feature feature)
{
return true;
}
public IFeatureGenerator CreateGenerator(Feature feature)
{
return _container.Resolve<MultiThemeUnitTestFeatureGenerator>();
}
}
答案 1 :(得分:1)
我无法想到一种简单的方法,但我的方法可能是从测试中排除主题,但让构建服务器在已经设置主题的环境中运行测试(通过环境变量或通过一些配置文件或类似文件)然后运行整个套件n次,每个主题一次。
所以我希望场景看起来像这样
Given I am using the currently configured theme
Given I am logged in
Given I go to base url
When I click logout button
Then I am logged out
其中第一步从配置文件或环境变量中读取主题,并设置测试以使用该主题。
一旦构建服务器运行了这些测试,它就会将config / environment变量更改为下一个主题并再次运行该套件。
这使您能够在单个位置(在构建服务器上或在BS用于发现主题的文件中)指定主题,并使用每个主题运行测试。它还可以为您提供一些性能优势,因为您可以在构建服务器上并行化测试,因为每个测试步骤都是不同的测试步骤,并且每个测试步骤可以在不同的计算机上独立运行。
对于开发人员,您只能一次测试一个主题,并且必须手动更改config / env变量以更改为不同的主题,这可能并不理想。
其他人可能会更好地了解如何以您想象的方式做到这一点,手指交叉