關于Net6?Xunit?集成測試的問題
對于單元測試、集成測試大部分開發(fā)的朋友都懶得去寫,因為這要耗費精力去設計去開發(fā),做完項目模塊直接postman 調用測試(當然這是一個選擇,開發(fā)也中經常用到),但是如果測試需要多樣化數(shù)據(jù),各種場景模擬這樣postman測試就暴露了他的局限性,下面我將Net6下沒有使用Startup以及NET6以前版本使用Startup的集成測試(單元測試雷同)做一個梳理
1.新建測試項目

2.使用到的類庫

Xunti與xunit.runner.visualstudio創(chuàng)建測試項目是自帶
Xunit.DependencyInjection 這是一個測試注入的擴展:github地址:https://github.com/pengweiqhca/Xunit.DependencyInjection
Xunit.Extensions.Ordering 這是一個排序執(zhí)行測試方法的擴展,因為有些方法是需要按照順序執(zhí)行,如獲取圖形驗證碼-->發(fā)送手機驗證碼-->到獲取Token這是一個有序的過程,如果沒有按照順序執(zhí)行肯定是不對的,github地址:https://github.com/tomaszeman/Xunit.Extensions.Ordering
3.注入
就是將要測試項目的所有注入重新注入測試項目(Program.cs)中和Startup中的所有東東全部注入,NET6中默認取消了Startup類,那么就要手工全部將這些注入再測試項目中添加一次,注入的時候有些是不兼容的做一下小的改動就行,因為https://github.com/pengweiqhca/Xunit.DependencyInjection的注入還是停留在NET5以下版本的,哦對了,還有中間件也是需要在測試項目中添加的,
3.1 NET5 以下,測試項目中的Startup需要自己手工創(chuàng)建,區(qū)別在于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需要自己手工創(chuàng)建,NET6 項目取消了Startup那么就需要手工搬移所有的注入,需要注意的是Startup中的ConfigureServices不支持重載,也就是你只能用一個ConfigureServices方法,見如下示例,還有測試日志的注入,但是在測試項目中使用ILogger<>好像是有問題的,有時日志不打印, 使用private readonly ITestOutputHelperAccessor _testOutputHelperAccessor; 替代ILogger<>,直接在測試類構造函數(shù)中注入就行
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" };
}4.創(chuàng)建測試類測試方法:
需要注意的是api接口測試中url忽略host與端口,默認端口配置請查閱https://github.com/pengweiqhca/Xunit.DependencyInjection文檔,UnitTest2中的測試方法是帶有數(shù)據(jù)集合的測試方法,及測試方法是執(zhí)行多次的,測試方法中的參數(shù)數(shù)據(jù)就是由MemberData(nameof(ReadFile)),其中數(shù)據(jù)方法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" };
}
}
}5.排序執(zhí)行測試方法:
使用Xunit.Extensions.Ordering進行排序執(zhí)行測試方法時:首先在測試項目中新建一個AssemblyInfo.cs加入如下內容,主要沒有類名及命名空間,其中[assembly: TestFramework("Xunit.Extensions.Ordering.TestFramework", "Xunit.Extensions.Ordering")]是一個按照集合進行排序的使用,但是他與已有xunit assembly沖突,暫時么有找到解決方法,所以該排序功能暫時不支持,類中的[Order(2)]為第一優(yōu)先級排序順序,方法中的[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")]6.運行測試項目:
在vs中運行測試項目中右鍵可以看到運行和調試測試項目運行比較簡單,如果在服務器上需要使用dotnet test運行測試,注意配置文件要與服務器的匹配,將項目整體目錄拷貝到服務器,cd 到測試項目目錄下執(zhí)行 dotnet test,有多少個接口瞬間測試完畢,而且在項目后續(xù)迭代更新的時候,只需要執(zhí)行以下就可以測試所有的接口。
到此這篇關于Net6 Xunit 集成測試的文章就介紹到這了,更多相關Net6 Xunit 集成測試內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
asp.net下實現(xiàn)支持文件分塊多點異步上傳的 Web Services
asp.net下實現(xiàn)支持文件分塊多點異步上傳的 Web Services...2007-04-04
Entity?Framework實現(xiàn)數(shù)據(jù)遷移
本文詳細講解了Entity?Framework實現(xiàn)數(shù)據(jù)遷移的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03
asp.net下實現(xiàn)輸入數(shù)字的冒泡排序
.net下實現(xiàn)輸入數(shù)字的冒泡排序2010-03-03
.NET?Core使用Autofac容器的DI依賴注入,IOC控制反轉及AOP切面編程
本文詳細講解了.NET?Core使用Autofac容器的DI依賴注入,IOC控制反轉及AOP切面編程,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-02-02
在Global.asax文件里實現(xiàn)通用防SQL注入漏洞程序(適應于post/get請求)
可使用Global.asax中的Application_BeginRequest(object sender, EventArgs e)事件來實現(xiàn)表單或者URL提交數(shù)據(jù)的獲取,獲取后傳給SQLInjectionHelper類ValidUrlData方法來完成檢查2013-01-01
ASP.NET通過自定義函數(shù)實現(xiàn)對字符串的大小寫切換功能
這篇文章主要介紹了ASP.NET通過自定義函數(shù)實現(xiàn)對字符串的大小寫切換功能的方法,給出了兩個簡單的實現(xiàn)方法,涉及asp.net字符串轉換操作的相關技巧,需要的朋友可以參考下2015-07-07
.Net?Core應用增強型跨平臺串口類庫CustomSerialPort()詳解
本文詳細講解了.Net?Core應用增強型跨平臺串口類庫CustomSerialPort(),文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-01-01

