xUnit测试的顺序执行

Posted cmliu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了xUnit测试的顺序执行相关的知识,希望对你有一定的参考价值。

cmliu

1,演示环境:windows 10企业版+Visual Studio 2019;.NET Core3.1;xUnit 2.4.1;.NET Standard 2.0.3

2,日期:2020/03/20

3,场景描述:测试调用目标微服务的暴露的某个模块的接口;需要按顺序执行创建表,查询表,修改表,删除表接口;

   本文只粘贴了核心的代码,详细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:UsersAdministrator.nugetpackagesxunit.extensibility.core2.4.1lib
etstandard1.1xunit.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测试的顺序执行的主要内容,如果未能解决你的问题,请参考以下文章

如何根据当前平台跳过 xUnit 中的特定测试

如何为 xunit 集成测试编写 GraphQL 变异查询

如何使用 XUnit 对 Web API 控制器进行单元测试

Net Core:在Xunit Test中对AppService、Repository等执行所有依赖注入

无法使用 .NET Core 运行 xUnit 测试

无法使用 .NET Core 运行 xUnit 测试