对于单元测试、集成测试大部分开发的朋友都懒得去写,因为这要耗费精力去设计去开发,做完项目模块直接postman 调用测试(当然这是一个选择,开发也中经常用到),但是如果测试需要多样化数据,各种场景模拟这样postman测试就暴露了他的局限性,下面我将Net6下没有使用Startup以及NET6以前版本使用Startup的集成测试(单元测试雷同)做一个梳理

1.新建测试项目

2.使用到的类库

Xunti与xunit.runner.visualstudio创建测试项目是自带

Xunit.DependencyInjection 这是一个测试注入的扩展:github地址:https://github.com/pengweiqhca/Xunit.DependencyInjection

Xunit.Extensions.Ordering 这是一个排序执行测试方法的扩展,因为有些方法是需要按照顺序执行,如获取图形验证码-->发送手机验证码-->到获取Token这是一个有序的过程,如果没有按照顺序执行肯定是不对的,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需要自己手工创建,区别在于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" };
}

4.创建测试类测试方法:

需要注意的是api接口测试中url忽略host与端口,默认端口配置请查阅https://github.com/pengweiqhca/Xunit.DependencyInjection文档,UnitTest2中的测试方法是带有数据集合的测试方法,及测试方法是执行多次的,测试方法中的参数数据就是由MemberData(nameof(ReadFile)),其中数据方法ReadFile必须是 public static ReadFile要不然会有报错

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.排序执行测试方法:

使用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")]

6.运行测试项目:

在vs中运行测试项目中右键可以看到运行和调试测试项目运行比较简单,如果在服务器上需要使用dotnet test运行测试,注意配置文件要与服务器的匹配,将项目整体目录拷贝到服务器,cd 到测试项目目录下执行 dotnet test,有多少个接口瞬间测试完毕,而且在项目后续迭代更新的时候,只需要执行以下就可以测试所有的接口。

Net6 Xunit 集成测试的更多相关文章

  1. .net core + xunit 集成测试

    xunit地址:https://github.com/xunit/xunit 一.利用请求来测试接口,主要是测试webapi控制器方法 ①添加xunit项目 ,然后引用我们的主项目,nuget: Mi ...

  2. 如何在ASP.NET 5和XUnit.NET中进行LocalDB集成测试

    今天继续昨天的话题--单元测试,不过是在ASP.NET 5中的单元测试. 在当前的Visual Studio 2015 CTP6中,MSTest是不支持对ASP.NET 5项目进行单元测试的.因而,要 ...

  3. Asp.Net Core 轻松学-利用xUnit进行主机级别的网络集成测试

    前言     在开发 Asp.Net Core 应用程序的过程中,我们常常需要对业务代码编写单元测试,这种方法既快速又有效,利用单元测试做代码覆盖测试,也是非常必要的事情:但是,但我们需要对系统进行集 ...

  4. 体验 ASP.NET Core 集成测试三剑客:xUnit.net、TestServer、EF Core InMemory

    这是昨天解决的一个问题,针对一个 web api 的客户端代理类写集成测试,既要测试 web api,又要测试 web api 客户端. 测试 web api,就要在运行测试时自动启动 web api ...

  5. .netcore持续集成测试篇之开篇简介及Xunit基本使用

    系列目录 为了支持跨平台,微软为.net平台提供了.net core test sdk,这样第三方测试框架诸如Nunit,Xunit等只需要按照sdk提供的api规范进行开发便可以被dotnet cl ...

  6. 使用xunit对asp.net core webapi进行集成测试

    新项目我们采用前后端分离,后端采用asp.net core webapi, 如何对后端代码进行自动化测试呢,有以下几种方案: 1. 单元测试,目前这个方案对我们来说难度很大,抛开时间的问题,单元测试对 ...

  7. .netcore持续集成测试篇之Xunit数据驱动测试一

    系列目录 Nunit里提供了丰富的数据测试功能,虽然Xunit里提供的比较少,但是也能满足很多场景下使用了,如果数据场景非常复杂,Nunit和Xunit都是无法胜任的,有不少测试者选择自己编写一个数据 ...

  8. .netcore持续集成测试篇之Xunit结合netcore内存服务器发送post请求

    系列目录 Web项目中,很多与用户数据交互的请求都是Post请求,想必大家都用过HttpClient构造过post请求,这里并不对HttpClient做详细介绍,只介绍一些常用的功能.并结合AutoF ...

  9. ASP.NET Core 中文文档 第五章 测试(5.2)集成测试

    原文: Integration Testing 作者: Steve Smith 翻译: 王健 校对: 孟帅洋(书缘) 集成测试确保应用程序的组件组装在一起时正常工作. ASP.NET Core支持使用 ...

  10. 使用xUnit,EF,Effort和ABP进行单元测试(C#)

    返回总目录<一步一步使用ABP框架搭建正式项目系列教程> 本篇目录 介绍 创建测试项目 准备测试基类 创建第一个测试 测试异常 在测试中使用仓储 测试异步方法 小结 介绍 在这篇博客中,我 ...

随机推荐

  1. locky勒索样本分析

    前段时间收到locky样本,分析之后遂做一个分析. 样本如下所示,一般locky勒索的先决条件是一个js的脚本,脚本经过了复杂的混淆,主要用于下载该样本文件并运行,. 解密 样本本身进行了保护,通过i ...

  2. Linux启动新进程的几种方法汇总

    有时候,我们需要在自己的程序(进程)中启动另一个程序(进程)来帮助我们完成一些工作,那么我们需要怎么才能在自己的进程中启动其他的进程呢?在Linux中提供了不少的方法来实现这一点,下面就来介绍一个这些 ...

  3. 自定义Image自动切换图像控件

    做这么一个控件,图片自动切换,形成动画效果. 随便的码码,码完发现东西太少了,不过还算完善. public class MyPictureBox : PictureBox { Timer timer ...

  4. Python处理JSON

    从开源中国的博客搬来,合并博客 一.JSON是什么? JSON是一种轻量级的数据交换格式 二.Python处理JSON的思维 其实很容易理解,无非是将数据编成JSON格式数据和吧JSON格式的数据解析 ...

  5. jqgrid使用简单记录

    我要为id为jqGrid的table使用jqgrid插件. $("#jqGrid").jqGrid({ url: 'data/test.json', mtype: "GE ...

  6. python读取bin文件并下发串口

    # coding:utf-8import time, serialfrom struct import *import binascii file = open('E:\\1.bin', 'rb')i ...

  7. UIActivityIndicatorView的详细使用(加载菊花)

    UIActivityIndicatorView实例提供轻型视图,这些视图显示一个标准的旋转进度轮.当使用这些视图时,最重要的一个关键词是小.20×20像素是大多数指示器样式获得最清楚显示效果的大小.只 ...

  8. Spring+thymeleaf

    1.导入jar包 2.配置 3.标签使用 th:text th:utext th:object th:if th:switch th:case th:each="person:userlis ...

  9. poj 1523Tarjan算法的含义——求取割点可以分出的连通分量的个数

    poj 1523Tarjan算法的含义——求取割点可以分出的连通分量的个数 题目大意:如题目所示 给你一些关系图——连通图,想要问你有没有个节点,损坏后,可以生成几个互相独立的网络(也就是连通分量), ...

  10. VMware 导出镜像文件供 Virtual Box 使用

    1. 问题描述 Windows 系统安装的 VMware 里的安装配置好的虚拟机需要拷贝到 MAC 的 Virtual Box 中. 需要将 VMware 中的虚拟机导出为镜像文件供 Virtual ...