首先,我是SpecFlow的新手。
我有一个功能文件,我已经/想要自动使用MSTest作为功能测试运行,涉及完全设置的服务器,数据访问...... 为此,我必须使用SpecFlow的'Given'块中的数据配置服务器,然后启动它。我还必须将一些文件复制到测试的输出目录。
在非SpecFlow功能测试中,我使用ClassInitialize属性从TestContext获取TestDeploymentDir;像这样的东西:
[ClassInitialize]
public static void ClassSetup(TestContext context)
{
TargetDataDeploymentRoot = context.TestDeploymentDir;
}
现在使用SpecFlow我不再使用此属性,因为SpecFlow本身使用它。 确实存在一些新属性,例如 BeforeFeature ,它的行为类似但是它不会将TestContext作为参数传递。
我只需要访问TestContext的TestDeploymentDir,以便在真正推出我的功能测试服务器之前复制一些文件 - 没有SpecFlow就可以轻松实现,但使用SpecFlow几乎不可能。
如何处理这个问题?
有可能吗?
非常感谢您的建议!
罗伯特
环境:
答案 0 :(得分:3)
为了能够访问TestContext中的值,您必须为添加的每个方案文件创建分部类。
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
/// <summary>
/// Partial class for TestContext support.
/// </summary>
public partial class DistributionFeature
{
/// <summary>
/// Test execution context.
/// </summary>
private TestContext testContext;
/// <summary>
/// Gets or sets test execution context.
/// </summary>
public TestContext TestContext
{
get
{
return this.testContext;
}
set
{
this.testContext = value;
//see https://github.com/techtalk/SpecFlow/issues/96
this.TestInitialize();
FeatureContext.Current["TestContext"] = value;
}
}
}
然后,您可以使用
从步骤访问部署目录var testContext = (TestContext)FeatureContext.Current["TestContext"];
var deploymentDir = testContext.TestDeploymentDir;
如果您有太多场景,那么您可能必须使用T4自动创建此类文件。
答案 1 :(得分:3)
您可以创建插件并自定义IUnitTestGeneratorProvider实现。以下内容应该将该行添加到MSTest的类初始化。
// It's very important this is named Generator.SpecflowPlugin.
namespace MyGenerator.Generator.SpecflowPlugin
{
public class MyGeneratorProvider : MsTest2010GeneratorProvider
{
public MyGeneratorProvider(CodeDomHelper codeDomHelper)
: base(codeDomHelper)
{
}
public override void SetTestClassInitializeMethod(TestClassGenerationContext generationContext)
{
base.SetTestClassInitializeMethod(generationContext);
generationContext.TestClassInitializeMethod.Statements.Add(new CodeSnippetStatement(
@"TargetDataDeploymentRoot = context.TestDeploymentDir;"));
}
}
[assembly: GeneratorPlugin(typeof(MyGeneratorPlugin))]
public class MyGeneratorPlugin : IGeneratorPlugin
{
public void RegisterDependencies(ObjectContainer container)
{
}
public void RegisterCustomizations(ObjectContainer container, SpecFlowProjectConfiguration generatorConfiguration)
{
container.RegisterTypeAs<MyGeneratorProvider, IUnitTestGeneratorProvider>();
}
public void RegisterConfigurationDefaults(SpecFlowProjectConfiguration specFlowConfiguration)
{
}
}
}
并在App.config文件中引用它:
<specFlow>
<plugins>
<add name="MyGenerator" type="Generator"/>
</plugins>
</specFlow>
下次重新保存.feature文件时,ClassInitialize中生成的代码应设置TargetDataDeploymentDirectory。
我必须做类似的事情。这是我的工作代码https://github.com/marksl/Specflow-MsTest和博文http://codealoc.wordpress.com/2013/09/30/bdding-with-specflow/
答案 2 :(得分:2)
从SpecFlow 2.2.1开始,TestContext可通过Context Injection获得。 (https://github.com/techtalk/SpecFlow/pull/882)
您可以直接从容器中获取它:
public class MyStepDefs
{
private readonly TestContext _testContext;
public MyStepDefs(TestContext testContext) // use it as ctor parameter
{
_testContext = testContext;
}
[BeforeScenario()]
public void BeforeScenario()
{
//now you can access the TestContext
}
}
或通过上下文注入:
forEach
答案 3 :(得分:-1)
有一个FeatureContext以及更常用的 ScenarioContext。当然,区别在于FeatureContext 在执行完整功能时存在 ScenarioContext仅在场景中存在。
例如:
添加到上下文中:
ScenarioContext.Current.Add("ObjectName", myObject);
得到:
var myObject = ScenarioContext.Current.Get<object>("ObjectName");
您可以详细了解here。