本篇内容主要讲解“Net6 Xunit集成测试问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Net6 Xunit集成测试问题怎么解决”吧!
Xunti与xunit.runner.visualstudio创建测试项目是自带
Xunit.Extensions.Ordering 这是一个排序执行测试方法的扩展,因为有些方法是需要按照顺序执行,如获取图形验证码-->发送手机验证码-->到获取Token这是一个有序的过程,如果没有按照顺序执行肯定是不对的。
就是将要测试项目的所有注入重新注入测试项目(Program.cs)中和Startup中的所有东东全部注入,NET6中默认取消了Startup类,那么就要手工全部将这些注入再测试项目中添加一次,注入的时候有些是不兼容的做一下小的改动就行,因为https://github.com/pengweiqhca/Xunit.DependencyInjection的注入还是停留在NET5以下版本的,哦对了,还有中间件也是需要在测试项目中添加的,
3.1 NET5 以下,测试项目中的Startup需要自己手工创建,区别在于NET5项目有Startup注入的时候不用手动写很多东西,测试项目直接从项目中的Startup查找注入,
public class Startup
{
// custom host build
public void ConfigureHost(IHostBuilder hostBuilder)
{
hostBuilder
.ConfigureHostConfiguration(builder =>
{
builder.AddJsonFile("appsettings.json", true);
})
.ConfigureWebHostDefaults(builder =>
{
builder.UseStartup<Dx.H5.Service.Startup>();//此处为项目中的startup,不是测试项目中的startup
builder.UseTestServer();
builder.ConfigureServices(services =>
{
services.AddSingleton(sp => sp.GetRequiredService<IHost>()
.GetTestClient()
);
});
})
;
}
// add services need to injection
// ConfigureServices(IServiceCollection services)
// ConfigureServices(IServiceCollection services, HostBuilderContext hostBuilderContext)
// ConfigureServices(HostBuilderContext hostBuilderContext, IServiceCollection services)
public void ConfigureServices(IServiceCollection services)
{
// ready check
//services.AddHostedService<ReadyCheckHostedService>();
}
public void Configure(ILoggerFactory loggerFactory, ITestOutputHelperAccessor outputHelperAccessor)
{
loggerFactory.AddProvider(new XunitTestOutputLoggerProvider(outputHelperAccessor));
}
}
3.2 NET6 ,测试项目中的Startup需要自己手工创建,NET6 项目取消了Startup那么就需要手工搬移所有的注入,需要注意的是Startup中的ConfigureServices不支持重载,也就是你只能用一个ConfigureServices方法,见如下示例,还有测试日志的注入,但是在测试项目中使用ILogger<>好像是有问题的,有时日志不打印, 使用private readonly ITestOutputHelperAccessor _testOutputHelperAccessor; 替代ILogger<>,直接在测试类构造函数中注入就行
public class Startup
{
const string DefaultCorsPolicyName = "Default";
public void ConfigureHost(IHostBuilder hostBuilder) =>
hostBuilder.ConfigureWebHost(webHostBuilder => webHostBuilder
.UseTestServer()
.Configure(Configure)
.UseUrls("http://*:17890","http://*:17880")
.ConfigureServices(services =>
{
services.AddSingleton(sp => sp.GetRequiredService<IHost>()
.GetTestClient()
);
})
)
.ConfigureAppConfiguration(lb => lb.AddJsonFile("appsettings.json", false, true));
public void ConfigureServices(IServiceCollection services, HostBuilderContext context)
{
services.AddControllers();
services.AddEndpointsApiExplorer();
services.AddSwaggerGen();
services.AddHttpClient();
}
public void Configure(ILoggerFactory loggerFactory, ITestOutputHelperAccessor accessor) =>
loggerFactory.AddProvider(new XunitTestOutputLoggerProvider(accessor));
////public void ConfigureHost(IHostBuilder hostBuilder) { }
//public void ConfigureServices(IServiceCollection services)
//{
//}
//public IHostBuilder CreateHostBuilder(AssemblyName assemblyName)
//{
// return new HostBuilder();
//}
private void Configure(IApplicationBuilder app)
{
//if (app.Environment.IsDevelopment())
//{
// app.UseSwagger();
// app.UseSwaggerUI();
//}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints
.MapControllers();
endpoints.MapGet("/hb/generatetoken", context =>
{
return context.Response.WriteAsync(GenerateToken(context));
});
});
}
string GenerateToken(HttpContext httpContext)
{
return "dfdfdfdfd";
}
}
public static IEnumerable<object?[]> ReadFile()
{
yield return new object[] { "123"};
yield return new object[] { "456" };
}
需要注意的是api接口测试中url忽略host与端口,默认端口配置请查阅https://github.com/pengweiqhca/Xunit.DependencyInjection文档,UnitTest2中的测试方法是带有数据集合的测试方法,及测试方法是执行多次的,测试方法中的参数数据就是由MemberData(nameof(ReadFile)),其中数据方法ReadFile必须是 public staticReadFile要不然会有报错
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Xunit;
using Xunit.DependencyInjection;
using Xunit.Extensions.Ordering;
using static WebApiXunit.Controllers.WeatherForecastController;
namespace Xunit.WebApiTest
{
[Order(1)]
public class UnitTest1
{
private HttpClient _client;
private ILogger<UnitTest1> _logger;
//private readonly ITestOutputHelperAccessor _testOutputHelperAccessor;
public UnitTest1(
//ITestOutputHelperAccessor testOutputHelperAccessor
ILogger<UnitTest1> logger,
HttpClient client
)
{
_logger = logger;
_client = client;
}
[Order(1)]
[Fact(DisplayName = "1")]
public async Task Test1()
{
var c = new MyClass();
c.Name = "1";
c.Description = "e";
using var request = new HttpRequestMessage(HttpMethod.Post, "WeatherForecast/hb/post/add");
var content = JsonConvert.SerializeObject(c);
request.Content = new StringContent(content);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var resp = await _client.SendAsync(request);
//var resp=await _client.GetAsync("/hb/generatetoken");
_logger.LogInformation("成功");
if (resp.IsSuccessStatusCode)
{
var str = await resp.Content.ReadAsStringAsync();
Assert.True(true);
return;
}
Assert.True(false);
}
[Order(2)]
[Fact(DisplayName = "2")]
public async Task Test2()
{
var c = new MyClass();
c.Name = "1";
c.Description = "e";
using var request = new HttpRequestMessage(HttpMethod.Post, "WeatherForecast/hb/post/add");
var content = JsonConvert.SerializeObject(c);
request.Content = new StringContent(content);
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var resp = await _client.SendAsync(request);
//var resp=await _client.GetAsync("/hb/generatetoken");
//_testOutputHelperAccessor.Output.WriteLine("");
_logger.LogInformation("成功");
if (resp.IsSuccessStatusCode)
{
var str = await resp.Content.ReadAsStringAsync();
Assert.True(true);
return;
}
Assert.True(false);
}
}
[Order(2)]
public class UnitTest2
{
private HttpClient _client;
private ILogger<UnitTest2> _logger;
public UnitTest2(
ILogger<UnitTest2> logger,
HttpClient client
)
{
_logger = logger;
_client = client;
}
[Theory]
[MemberData(nameof(ReadFile))]
public async Task Test2(string name)
{
_logger.LogInformation(name);
Assert.True(true);
}
public static IEnumerable<object?[]> ReadFile()
{
yield return new object[] { "123"};
yield return new object[] { "456" };
}
}
}
使用Xunit.Extensions.Ordering进行排序执行测试方法时:首先在测试项目中新建一个AssemblyInfo.cs加入如下内容,主要没有类名及命名空间,其中[assembly: TestFramework("Xunit.Extensions.Ordering.TestFramework", "Xunit.Extensions.Ordering")]是一个按照集合进行排序的使用,但是他与已有xunit assembly冲突,暂时么有找到解决方法,所以该排序功能暂时不支持,类中的[Order(2)]为第一优先级排序顺序,方法中的[Order(2)]即在类的顺序下再排序
using Xunit;
using Xunit.Extensions.Ordering;
[assembly: CollectionBehavior(DisableTestParallelization = true)]
//[assembly: TestFramework("Xunit.Extensions.Ordering.TestFramework", "Xunit.Extensions.Ordering")]
[assembly: TestCaseOrderer("Xunit.Extensions.Ordering.TestCaseOrderer", "Xunit.Extensions.Ordering")]
[assembly: TestCollectionOrderer("Xunit.Extensions.Ordering.CollectionOrderer", "Xunit.Extensions.Ordering")]
using Xunit;
using Xunit.Extensions.Ordering;
[assembly: CollectionBehavior(DisableTestParallelization = true)]
//[assembly: TestFramework("Xunit.Extensions.Ordering.TestFramework", "Xunit.Extensions.Ordering")]
[assembly: TestCaseOrderer("Xunit.Extensions.Ordering.TestCaseOrderer", "Xunit.Extensions.Ordering")]
[assembly: TestCollectionOrderer("Xunit.Extensions.Ordering.CollectionOrderer", "Xunit.Extensions.Ordering")]
在vs中运行测试项目中右键可以看到运行和调试测试项目运行比较简单,如果在服务器上需要使用dotnet test运行测试,注意配置文件要与服务器的匹配,将项目整体目录拷贝到服务器,cd 到测试项目目录下执行 dotnet test,有多少个接口瞬间测试完毕,而且在项目后续迭代更新的时候,只需要执行以下就可以测试所有的接口。
到此,相信大家对“Net6 Xunit集成测试问题怎么解决”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。