xUnit 是否支持“相同的测试,不同的设置”?或者我如何编写在本地运行的开发测试,并在管道中测试部署?

pla*_*ixo 5 c# testing integration-testing xunit

TL;DR:按照标题:我如何运行相同的测试但有不同的设置?

我正在使用 C#、Visual Studio 工作,通过 Azure DevOps(nee VSTS)部署到 Azure 中的 WebApp。

正在开发的软件在 Azure 中配置资源,并在 Azure Active Directory 中配置身份。

这意味着我有这样的测试:

[Fact]
public void ShouldCreateAzureDevOpsProject()
{
   _azureDevOpsHelper.GetAzureDevOpsProject(_projectName).Should().NotBe(null);
}

[Fact]
public void ShouldPutDefaultFileInRepo()
{ 
  _azureDevOpsHelper.GetDefaultFileFromRepo(_projectName).Should().NotBe(null);
}

[Fact]
public void ShouldEnableAllMicrosoftResourceProviders()
{
   _azureSubscriptionHelper.GetMicrosoftResourceProviders().Select(x => x.RegistrationState).Should().NotContain("NotRegistered");
}
Run Code Online (Sandbox Code Playgroud)

我想在编写代码时对代码运行这些测试。该代码在我的笔记本电脑上运行,因此设置(我目前在 xUnit Fixture 中)是:

new EngineOrchestrator.EngineOrchestrator().RequestInstance(userSuppliedConfiguration);
Run Code Online (Sandbox Code Playgroud)

但这些测试同样适用于在我们的部署管道中运行,以在部署到我们的测试环境后检查回归情况。出于这些目的,设置将涉及创建 HTTP 客户端并访问应用程序的端点。

要点是,无论设置如何,测试都是相同的。在“本地”和“管道”情况下,要测试的值均来自 json 配置文件;隔离是通过在部署期间为测试添加不同的配置文件来实现的。

换一种方式; 我正在尝试弄清楚如何封装该设置,以便两个不同的设置可以共享相同的测试。这与夹具等的作用相反,多个测试可以共享相同的设置。

我努力了:

  • 根据运行测试的机器切换“设置”
if (Environment.MachineName.StartsWith("Plavixo"))
{
    new EngineOrchestrator.EngineOrchestrator().RequestInstance(userSuppliedConfiguration);
}
else
{
    HttpEngineHelper.RunOrchestrator(userSuppliedConfiguration, authenticationDetails);
}
Run Code Online (Sandbox Code Playgroud)

这是我当前的解决方案,但它感觉很脆弱,并且使测试工件变得巨大,因为它必须包含能够更新引擎的所有源代码,即使它要在构建机器上运行。

  • 将测试抽象化,并继承到在构造函数中具有特定设置的具体类。
public class LocalBootstrap : BootstrapTests.BootstrapTests
{
   public LocalBootstrap():base()
      {
         //do specific setup here
Run Code Online (Sandbox Code Playgroud)
public abstract class BootstrapTests
{
   [Fact]
   public void ShouldCreateAzureDevOpsProject()
Run Code Online (Sandbox Code Playgroud)

这种方法是有效的,但是设置在每个测试之前运行,这是有道理的:“xUnit.net 为每个运行的测试创建一个测试类的新实例,因此放置到该类的构造函数中的任何代码将为每个测试运行测试类。”

  • 使夹具变得抽象

夹具运行一次并在测试之间共享。我尝试使装置变得抽象,并为我的每个设置提供一个具体的类。

xUnit 抛出 System.AggregateException :类固定类型只能定义单个公共构造函数。这是由已作为“按设计”关闭的github 问题引用的

  • 在本地主机上运行我的本地测试

这是我要调查的下一个选择。这是一个好主意吗?

还有其他我应该尝试的事情吗?

pla*_*ixo 5

我最终找到了一个适合我们的解决方案。解决方案的关键是使测试变得抽象,并从该抽象类继承几个捕获我想要的设置的具体类。这是我们现在所拥有的简化图。 在此输入图像描述

我们仍然使用固定装置,因为我们希望 Arrange 代码和 Act 代码只运行一次。

这种安排对我们来说非常有效,因为我们可以通过多种设置(我们有 Bootstrap 和 Full)以及多种调用样式(远程运行与本地运行)来运行相同的测试。我们打算为 Greenfield 和 Brownfield 添加更多设置(这与我们的代码之前是否运行过有关)。