我们有一些代码需要从三个不同的角度进行测试:
是否共享项目之间的功能文件是实现这一目标的最佳方法,还是存在更明智的方法?
- 内部调用
- Web服务
- Web应用程序
是否共享项目之间的功能文件是实现这一目标的最佳方法,还是存在更明智的方法?
(感谢邮件列表中的Oliver Friedrich)
您需要为您想要为步骤变化的每个选项创建一个程序集,因此一个用于内部,一个用于Web服务和一个用于WebApp。您告诉specflow有关所有不同程序集的配置,如下所示:
<specFlow>
<stepAssemblies>
<stepAssembly assembly="Tests.API" />
<stepAssembly assembly="Tests.UI" />
</stepAssemblies>
</specFlow>
在您的常见测试步骤中,您有一些[BeforeTestRun]
步骤,该步骤选择要从中加载步骤的程序集:
[Binding]
public class TestRunSetup {
// this method needs to be static
[BeforeTestRun]
public static void BeforeTestRun()
{
if (RunApiTests()) // <-- implement this method to choose whether to run the tests via your chosen method
{
Assembly.Load("Tests.API");
}
else
{
Assembly.Load("Tests.UI");
}
}
}
(感谢来自邮件列表的Gáspár Nagy)
尝试在构建期间 生成测试。我不确定这样做的确切方式,但这是我们可以研究的一个领域。
(感谢来自邮件列表的Dan Mork)
如果您使用 SpecFlow 的依赖注入功能,则可以创建用于执行所需调用的接口,并在一组常规步骤中使用此接口。然后,您可以有 3 个实现该接口的实现:一个调用内部服务,一个调用 Web 服务,以及一个操作 Web 应用程序。所有剩下的工作就是将正确的接口实现注入到 SpecFlow 步骤文件中,可以通过以下方式完成:
// the abstract concept of the system that could be implemented with
Selenium, HttpClient, etc.
public interface IDocument
{
string Title { get;}
void Load();
}
// the steps that are executed when the scenarios from your feature
file are executed
[Binding]
public class Steps
{
private readonly IDocument _document;
public Steps(IDocument document)
{
_document = document;
}
[Given("something")]
public void GivenSomething()
{
// set up given state
}
[When("I view the document")]
public void WhenIViewTheDocument()
{
_document.Load();
}
[Then(@"the title should be ""(.*)""")]
public void Then(string title)
{
Assert.ArEqual(_document.Title, title);
}
}
// this is where the magic happens - get the dependency injection
// container and register an IDocument implementation
[Binding]
public class Dependencies
{
private readonly IObjectContainer _objectContainer;
public Dependencies(IObjectContainer objectContainer)
{
_objectContainer = objectContainer;
}
[BeforeScenario]
public void RegisterDocumentInterfaces()
{
// register the correct IDocument implementation - UI or API
}
}
BeforeScenarioAttribute
中添加tag参数ScopeAttribute
是可扩展的,您可以创建一个子类,并提供自己的逻辑来确定是否执行BeforeScenarioAttribute
方法。app.config
files for your different environments.in every app.config configure the right stepassemblies
(comment/delete the one not needed)
<specFlow>
<stepAssemblies>
<stepAssembly assembly="Tests.API" />
<!--stepAssembly assembly="Tests.UI" /-->
</stepAssemblies>
</specFlow>
Assembly.Load
,因为声明一个stepAssembly将会将引用作为bindingAssembly传递给NUnit(请参见此处)。我认为这实际上是三个不同的测试,因此在我的想法中应该有三组功能文件。但是,如果您真的不想走这条路,那么您可以做一些类似于指定示例表格的事情,例如:
Scenario Outline: Testing app
Given I have performed a call to my service using <application>
When I do something
Then this happens
Examples:
|Application|
| web service |
| web application |
| direct call |
我不确定我是否正确地理解了你想要的内容,但这可能是你正在寻找的:
Scenario Outline: Multiple approaches to test same code
Given I am using <ApproachToCallCode>
When I do something
Then I expect this result
Scenarios: Approaches
|ApproachToCallCode|
|Internal |
|WebService |
|WebApp |
那么,你可以在给定的方法中使用条件语句吗?我不确定这是否是最好的方法,但它应该能够工作。
步骤不限于特定功能,只要步骤相同或至少有一些相同的措辞,或者您在步骤定义方法中添加额外属性,那么它们可以在其他场景或功能中重复使用。
根据情况,我会将它们编写为额外的场景或功能。