使用 XUnit.NET 的集成测试 - 无法使用应用程序根定位解决方案根
Integration Tests using XUnit.NET - Solution root could not be located using application root
我在解决方案中有两个项目。
- Web API 使用 .NET Core 3.1
- 使用 XUnit.NET 和 .NET Core 3.1 的集成测试,此项目引用了 Web API 项目
示例集成测试 class 在这里。
public class CustomersControllerTests : IClassFixture<WebApplicationFactory<WebAPIProject.Startup>>
{
public CustomersControllerTests(WebApplicationFactory<WebAPIProject.Startup> factory)
{
_httpClient = factory.CreateClient();
_customerRepository = factory.Services.GetService<ICustomerRepository>();
}
}
我使用以下文章开发了集成测试。
https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-3.1
所有测试 运行 在 Visual Studio 中都很好。
因此,集成测试项目被放入 Azure DevOps 管道。
这是代理作业中的任务。
- 下载管道工件任务(从构建管道下载构建工件)
- Visual Studio 测试平台安装程序任务
- Visual Studio 测试任务
所有测试在执行过程中都失败了,这里是其中一个测试的堆栈跟踪。
System.InvalidOperationException : Solution root could not be located using application root D:\a\r1\a\_ReleaseManagement.API.IntegrationTests-CI\drop\ReleaseManagement.IntegrationTests\Release\.
[xUnit.net 00:00:06.59] Stack Trace:
at Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.UseSolutionRelativeContentRoot(IWebHostBuilder builder, String solutionRelativePath, String applicationBasePath, String solutionName)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.SetContentRoot(IWebHostBuilder builder)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.<EnsureServer>b__20_0(IWebHostBuilder webHostBuilder)
at Microsoft.Extensions.Hosting.GenericHostWebHostBuilderExtensions.ConfigureWebHost(IHostBuilder builder, Action`1 configure)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient()
/home/vsts/work/1/s/src/UnitTests/ReleaseManagement.IntegrationTests/Api/CustomersControllerTests.cs(29,0): at ReleaseManagement.IntegrationTests.Api.CustomersControllerTests..ctor(WebApplicationFactory`1 factory)
2020-11-27T09:54:43.4381123Z ##[error][xUnit.net 00:00:06.59] ReleaseManagement.IntegrationTests.Api.CustomersControllerTests.CreateCustomer_Success [FAIL]
构建管道定义 -
steps:
- task: UseDotNet@2
displayName: "Use .NET Core SDK $(netCoreVersion)"
inputs:
version: $(netCoreVersion)
- task: DotNetCoreCLI@2
displayName: 'Restore project dependencies'
inputs:
command: 'restore'
projects: '**/ABC.IntegrationTests/ABC.IntegrationTests.csproj'
- task: DotNetCoreCLI@2
displayName: 'Build API Integration Tests - $(buildConfiguration)'
inputs:
command: 'build'
arguments: '--configuration $(buildConfiguration) --no-restore --output $(Build.ArtifactStagingDirectory)\ABC.IntegrationTests\Release'
projects: '**/ABC.IntegrationTests/ABC.IntegrationTests.csproj'
- task: PublishBuildArtifacts@1
displayName: 'Publish build artifact: drop'
condition: succeeded()
发布管道定义-
steps:
- task: DotNetCoreCLI@2
displayName: 'dotnet test'
inputs:
command: test
arguments: '_ABC.API.IntegrationTests-CI\drop\ABC.IntegrationTests\Release\ABC.IntegrationTests.dll'
关于如何解决此问题以便可以在 azure devops 管道中执行测试的任何帮助?
基本上“WebApplicationFactory”需要“WebApplicationFactoryContentRootAttribute”来找到根,所以阅读更多here。
试试这个 fix
或者这个 one
根据错误日志,在dotnet test的过程中,需要引用build的源文件。但是当机器上不存在时,就会失败。
/home/vsts/work/1/s/src/UnitTests/ReleaseManagement.IntegrationTests/Api/CustomersControllerTests.cs(29,0): at ReleaseManagement.IntegrationTests.Api.CustomersControllerTests..ctor(WebApplicationFactory`1 factory)
要解决这个问题,您可以尝试以下方法:
1.Integrate 在 Same 构建管道中构建和测试。
- 如果要在不同的流水线中拆分构建和测试,需要注意以下几点。
您需要确保构建和发布管道使用的是相同 Microsoft 托管的代理。 (从你的日志来看,他们使用的是不同类型的代理)
您需要在发布管道中添加回购源。然后在Release管道中添加复制文件任务和dotnet restore任务。
发布神器:
发布任务
解释:
复制文件任务用于将文件源复制到构建代理源目录路径。您可以查看发布错误日志中的特定路径。
例如:Build sourcepath: D:\a\s
Release Pipeline 将文件复制到D:\a\s
dotnet restore 任务用于恢复源文件所需的包。在 dotnet 测试中,它可能需要一些包。
3.You 可以创建 Self-hosted agent。然后您可以直接运行在自托管代理上构建和测试而无需其他设置。
我已进行以下更改以解决发布的问题。
- 将MainSolution.sln文件复制到发布构建/发布文件夹
- 如下所示创建了一个 CustomWebApplicationRepository
public class CustomWebApplicationFactory : WebApplicationFactory
{
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseContentRoot(AppContext.BaseDirectory);
base.ConfigureWebHost(builder);
}
}
在集成测试中使用 CustomWebApplicationFactory。
public class 客户控制器测试:IClassFixture
{
public CustomersControllerTests(CustomWebApplicationFactory 工厂)
{
_httpClient = factory.CreateClient();
_customerRepository = factory.Services.GetService();
}
}
我在解决方案中有两个项目。
- Web API 使用 .NET Core 3.1
- 使用 XUnit.NET 和 .NET Core 3.1 的集成测试,此项目引用了 Web API 项目
示例集成测试 class 在这里。
public class CustomersControllerTests : IClassFixture<WebApplicationFactory<WebAPIProject.Startup>>
{
public CustomersControllerTests(WebApplicationFactory<WebAPIProject.Startup> factory)
{
_httpClient = factory.CreateClient();
_customerRepository = factory.Services.GetService<ICustomerRepository>();
}
}
我使用以下文章开发了集成测试。
https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-3.1
所有测试 运行 在 Visual Studio 中都很好。 因此,集成测试项目被放入 Azure DevOps 管道。
这是代理作业中的任务。
- 下载管道工件任务(从构建管道下载构建工件)
- Visual Studio 测试平台安装程序任务
- Visual Studio 测试任务
所有测试在执行过程中都失败了,这里是其中一个测试的堆栈跟踪。
System.InvalidOperationException : Solution root could not be located using application root D:\a\r1\a\_ReleaseManagement.API.IntegrationTests-CI\drop\ReleaseManagement.IntegrationTests\Release\.
[xUnit.net 00:00:06.59] Stack Trace:
at Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.UseSolutionRelativeContentRoot(IWebHostBuilder builder, String solutionRelativePath, String applicationBasePath, String solutionName)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.SetContentRoot(IWebHostBuilder builder)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.<EnsureServer>b__20_0(IWebHostBuilder webHostBuilder)
at Microsoft.Extensions.Hosting.GenericHostWebHostBuilderExtensions.ConfigureWebHost(IHostBuilder builder, Action`1 configure)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(Uri baseAddress, DelegatingHandler[] handlers)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient()
/home/vsts/work/1/s/src/UnitTests/ReleaseManagement.IntegrationTests/Api/CustomersControllerTests.cs(29,0): at ReleaseManagement.IntegrationTests.Api.CustomersControllerTests..ctor(WebApplicationFactory`1 factory)
2020-11-27T09:54:43.4381123Z ##[error][xUnit.net 00:00:06.59] ReleaseManagement.IntegrationTests.Api.CustomersControllerTests.CreateCustomer_Success [FAIL]
构建管道定义 -
steps:
- task: UseDotNet@2
displayName: "Use .NET Core SDK $(netCoreVersion)"
inputs:
version: $(netCoreVersion)
- task: DotNetCoreCLI@2
displayName: 'Restore project dependencies'
inputs:
command: 'restore'
projects: '**/ABC.IntegrationTests/ABC.IntegrationTests.csproj'
- task: DotNetCoreCLI@2
displayName: 'Build API Integration Tests - $(buildConfiguration)'
inputs:
command: 'build'
arguments: '--configuration $(buildConfiguration) --no-restore --output $(Build.ArtifactStagingDirectory)\ABC.IntegrationTests\Release'
projects: '**/ABC.IntegrationTests/ABC.IntegrationTests.csproj'
- task: PublishBuildArtifacts@1
displayName: 'Publish build artifact: drop'
condition: succeeded()
发布管道定义-
steps:
- task: DotNetCoreCLI@2
displayName: 'dotnet test'
inputs:
command: test
arguments: '_ABC.API.IntegrationTests-CI\drop\ABC.IntegrationTests\Release\ABC.IntegrationTests.dll'
关于如何解决此问题以便可以在 azure devops 管道中执行测试的任何帮助?
基本上“WebApplicationFactory”需要“WebApplicationFactoryContentRootAttribute”来找到根,所以阅读更多here。
试试这个 fix 或者这个 one
根据错误日志,在dotnet test的过程中,需要引用build的源文件。但是当机器上不存在时,就会失败。
/home/vsts/work/1/s/src/UnitTests/ReleaseManagement.IntegrationTests/Api/CustomersControllerTests.cs(29,0): at ReleaseManagement.IntegrationTests.Api.CustomersControllerTests..ctor(WebApplicationFactory`1 factory)
要解决这个问题,您可以尝试以下方法:
1.Integrate 在 Same 构建管道中构建和测试。
- 如果要在不同的流水线中拆分构建和测试,需要注意以下几点。
您需要确保构建和发布管道使用的是相同 Microsoft 托管的代理。 (从你的日志来看,他们使用的是不同类型的代理)
您需要在发布管道中添加回购源。然后在Release管道中添加复制文件任务和dotnet restore任务。
发布神器:
发布任务
解释:
复制文件任务用于将文件源复制到构建代理源目录路径。您可以查看发布错误日志中的特定路径。
例如:Build sourcepath: D:\a\s
Release Pipeline 将文件复制到D:\a\s
dotnet restore 任务用于恢复源文件所需的包。在 dotnet 测试中,它可能需要一些包。
3.You 可以创建 Self-hosted agent。然后您可以直接运行在自托管代理上构建和测试而无需其他设置。
我已进行以下更改以解决发布的问题。
- 将MainSolution.sln文件复制到发布构建/发布文件夹
- 如下所示创建了一个 CustomWebApplicationRepository
public class CustomWebApplicationFactory : WebApplicationFactory
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.UseContentRoot(AppContext.BaseDirectory);
base.ConfigureWebHost(builder);
}
}
在集成测试中使用 CustomWebApplicationFactory。
public class 客户控制器测试:IClassFixture
{ public CustomersControllerTests(CustomWebApplicationFactory 工厂) { _httpClient = factory.CreateClient(); _customerRepository = factory.Services.GetService();
} }