xUnit测试的顺序执行总结
cmliu
1,演示环境:windows 10企业版+Visual Studio 2019;.NET Core3.1;xUnit 2.4.1;.NET Standard 2.0.3
3,场景描述:前几年在写单元测试时,经常要实现从数据库增删改查的流水线式的单元测试代码;每次修改业务逻辑或者代码后,只要一次运行,就可以把核心功能逻辑调试完;这个过程中会新增数据,还要在结束时把新增的数据删除
这中间就涉及到了顺序测试的;
解决这个问题有两种方式:1,自己写控制执行顺序的执行方法;2,使用xUnit的顺序执行接口;3,自己写jmeter脚本
刚好最近又有个东西要写测试;于是就把.NET Core下使用xUnit顺序执行的这方面的小东西做了个小总结
场景是这样的,调用目标微服务的暴露的某个模块的接口;需要按顺序执行创建表,查询表,修改表,删除表接口;
本文只粘贴了核心的代码,详细demo代码地址可以前往github下载:https://github.com/SaorenXi/XunitTestDemo.git
4,思路:在xUnit的xunit.core程序集中的Xunit.Sdk命名空间下;有一个用于控制执行顺序的接口:ITestCaseOrderer
如下代码为原程序集定义:
#region 程序集 xunit.core, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c
// C:\Users\Administrator\.nuget\packages\xunit.extensibility.core\2.4.1\lib\netstandard1.1\xunit.core.dll
#endregion using System.Collections.Generic;
using Xunit.Abstractions; namespace Xunit.Sdk
{
//
// 摘要:
// A class implements this interface to participate in ordering tests for the test
// runner. Test case orderers are applied using the Xunit.TestCaseOrdererAttribute,
// which can be applied at the assembly, test collection, and test class level.
public interface ITestCaseOrderer
{
//
// 摘要:
// Orders test cases for execution.
//
// 参数:
// testCases:
// The test cases to be ordered.
//
// 返回结果:
// The test cases in the order to be run.
IEnumerable<TTestCase> OrderTestCases<TTestCase>(IEnumerable<TTestCase> testCases) where TTestCase : ITestCase;
}
}
5,为了做方法顺序控制;定义一个名为OrderAttribute属性标签,标签上有个名为Sort的int型属性,用于标记方法的顺序;如下定义(示例是定义在:XUnitTest.Orders命名空间下)
using System; namespace XUnitTest.Orders
{
/// <summary>
/// 测试方法的执行顺序
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class OrderAttribute : Attribute
{
/// <summary>
/// 顺序
/// </summary>
public int Sort { get; set; }
public OrderAttribute(int sort)
{
this.Sort = sort;
}
}
}
6,实现ITestCaseOrderer接口(//按照Order标签上的Sort属性,从小到大的顺序执行),如下定义(示例定义在:SchemaTest命名空间下)
using System.Collections.Generic;
using System.Linq;
using Xunit.Abstractions;
using Xunit.Sdk;
using XUnitTest.Orders; namespace SchemaTest
{
/// <summary>
/// 单元测试的排序策略
/// </summary>
public class TestOrders : ITestCaseOrderer
{
/// <summary>
/// 执行顺序
/// </summary>
/// <typeparam name="TTestCase"></typeparam>
/// <param name="testCases"></param>
/// <returns></returns>
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
{
string typeName = typeof(OrderAttribute).AssemblyQualifiedName; ;
var result = testCases.ToList();
result.Sort((x, y) =>
{
var xOrder = x.TestMethod.Method.GetCustomAttributes(typeName)?.FirstOrDefault();
if (xOrder == null)
{
return 0;
}
var yOrder = y.TestMethod.Method.GetCustomAttributes(typeName)?.FirstOrDefault();
if (yOrder == null)
{
return 0;
}
var sortX = xOrder.GetNamedArgument<int>("Sort");
var sortY = yOrder.GetNamedArgument<int>("Sort");
//按照Order标签上的Sort属性,从小到大的顺序执行
return sortX - sortY;
});
return result;
}
}
}
7,使用;在目标的单元测试类上打上标签使用顺序执行实现类的标签;如下定义(示例中的目标类为:SchemaTest命名空间下的SchemaApiTest类)
//省略其他代码
using Xunit;
using XUnitTest.Orders; namespace SchemaTest
{
//[TestCaseOrderer("ITestCaseOrderer的实现类名称", "ITestCaseOrderer的实现类所在的程序集名称")]
[TestCaseOrderer("SchemaTest.TestOrders", "SchemaTest")]
public class SchemaApiTest
{
//省略其他代码
}
}
8,在目标的测试方法上打上Order标签,定义执行顺序,如下定义(示例使用的是mock数据和接口)
using Xunit;
using XUnitTest.Orders; namespace SchemaTest
{
[TestCaseOrderer("SchemaTest.TestOrders", "SchemaTest")]
public class SchemaApiTest
{
private string _testSchemaCode = $"xunittest123";
private static SchemaDTO _schemaDto = null; /// <summary>
/// 创建记录
/// </summary>
[Fact, Order(1)]
public void AddSchema()
{
var response = new MockClient().AddSchema(new SchemaDTO
{
SchemaCode = _testSchemaCode,
Name = "哈哈"
});
Assert.True(response);
} /// <summary>
/// 查询刚刚创建的记录
/// </summary>
[Fact, Order(2)]
public void GetSchema()
{
var response = new MockClient().GetSchema(_testSchemaCode);
//临时记录
_schemaDto = response;
Assert.NotNull(response);
Assert.Equal(_testSchemaCode, response.SchemaCode);
Assert.Equal("哈哈", response.Name);
} /// <summary>
/// 更新刚刚创建的数据记录
/// </summary>
[Fact, Order(3)]
public void UpdateSchema()
{
_schemaDto.Name = "jiujiu";
var response = new MockClient().UpdateSchema(_schemaDto);
Assert.True(response);
} /// <summary>
/// 查询更新后的记录
/// </summary>
[Fact, Order(4)]
public void GetAfterUpdatedSchema()
{
var response = new MockClient().GetSchema(_testSchemaCode);
Assert.NotNull(response);
Assert.Equal(_testSchemaCode, response.SchemaCode);
Assert.Equal("jiujiu", response.Name);
} /// <summary>
/// 删除记录
/// </summary>
[Fact, Order(5)]
public void RemoveSchema()
{
var response = new MockClient().RemoveSchema(_testSchemaCode);
Assert.True(response);
}
}
}
9,测试
xUnit测试的顺序执行总结的更多相关文章
- {MySQL的逻辑查询语句的执行顺序}一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析
MySQL的逻辑查询语句的执行顺序 阅读目录 一 SELECT语句关键字的定义顺序 二 SELECT语句关键字的执行顺序 三 准备表和数据 四 准备SQL逻辑查询测试语句 五 执行顺序分析 一 SEL ...
- TestNG-详解preserve-order的作用与测试case的执行顺序
在TestNG xml配置文件中,关于<test>的配置里面,有一个属性叫preserve-order,一开始以为这个属性可以用来控制测试case(那些被@Test注解标注的方法)的执行顺 ...
- js的并行加载以及顺序执行
重新温习了下这段内容,发现各个浏览器的兼容性真的是搞大了头,处理起来很是麻烦. 现在现总结下并行加载多个js的方法: 1,对于动态createElement('script')的方式,对所有浏览器都是 ...
- testng xml中按顺序执行java类
如红字部份,将安顺序执行4个类 <?xml version="1.0" encoding="UTF-8"?><suite name=" ...
- C#之使用AutoResetEvent实现线程的顺序执行
前几天一朋友问我如何实现线程的顺序执行,说真的,虽然看过CLR这本书,也把线程部分拜读了两遍,但是这个问题出来之后还是没有一个思路.今天在搜索资料的时候无意中再次看到AutoResetEvent这个东 ...
- <转载>linux gcc编译器中使用gdb单步调试程序,程序不是顺序执行的。
原文地址http://blog.csdn.net/abc78400123/article/details/6779108 在用gdb调试,使用s 或n单步执行程序时,发现程序不是按顺序运行的,有时莫名 ...
- js函数整合队列顺序执行插件
前言 在日常开发中,也许我们会遇到这样的一个问题.我们利用[发布订阅模式](如果不了解的可以直接访问此链接www.cnblogs.com/xiaoxiaokun- )去执行[发布]事件时,遇到函数内部 ...
- 多命令顺序执行,dd命令,管道|,grep,通配符,其他特殊符号
多命令顺序执行:命令1;命令2 命令之间没有逻辑关系 命令1&&命令2 命令1执行正确才执行命令2,命令1执行错误不会执行命令2 命令1||命令2 命令执行错误才执行命令2,命令1执行 ...
- XUnit测试框架-Python unittest
选择 语言选择 本次个人作业我选择的语言是Python,了解学习Python有一段时间了但是一直没有练习,所以这次玩蛇,使用的版本是Python3.6. 开发工具选择 我选择的IDE是Pycharm, ...
随机推荐
- Django中的异常
DJango除了会抛出Python的标准异常外还有一些框架自带的异常. 1. Django核心异常 在django.core.exceptions中:| ObjectDoesNotExist | Fi ...
- C#LeetCode刷题之#160-相交链表(Intersection of Two Linked Lists)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3824 访问. 编写一个程序,找到两个单链表相交的起始节点. 例如 ...
- HTML实例-02-京东顶部导航条
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...
- 什么是c/c++编译
GCC是什么 GNU Compiler Collection的缩写,一开始是c语言的编译器,但现今可以支持多种语言的编译工作,也支持了多个硬件平台的编译.总而言之,主流的c语言编译器就是这个gcc了. ...
- .Net MVC5(.Net Framework 4.0+)多语言解决方案
最近项目需要做多语言,原先是2种语言(中文/英文),现在又要加一种语言,成了3种.那么原来的方式肯定不适用了,只能升级解决方案. 原来的写法,使用三目表达式,按照当前全局变量的语言类型,返回不同的语言 ...
- 初识ABP vNext(4):vue用户登录&菜单权限
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 登录 菜单权限 运行测试 最后 前言 上一篇已经创建好了前后端项目,本篇开始编码部分. 开始 几乎所有的系统都绕不开登 ...
- 解决VS Code安装golang相关插件失败问题
解决VS Code安装golang相关插件失败问题 VSCode作为一款优秀的编辑器,基本上前端开发,Python,markdown都可以用,真正是开发过程中的好帮手,所以学习go也当仁不让的要用vs ...
- js中的寄生组合继承
function inheritProperty(subType, superType) { function F(){} F.prototype = superType.prototype; sup ...
- openstack nova 创建虚机流程
1文件 nova.api.openstack.coumpute.servers1函数 def create(self, req, body):1调用 (instances, resv_id) = se ...
- 获取元素top值,屏幕滚动到当前元素
var top = $(this).offset().top; $('html , body').animate({scrollTop: top-100},10);