refactor:单元测试策略修改

1. 撤回到测试按照规定顺序执行,原因是不同的测试方法会操作相同的文件目录,不按照顺序的并发执行会导致冲突,还有,单元测试是从微小功能递增到复杂功能,按照顺序执行有助于问题排查
2. 每个测试case 仍然是独立的。
This commit is contained in:
zerlei 2024-07-31 11:59:21 +08:00
parent 78d9e68fea
commit bff3e114fc
3 changed files with 83 additions and 21 deletions

View file

@ -1,24 +1,36 @@
using Common; using Common;
using Xunit; using XUnit.Project.Attributes;
/*using Newtonsoft.Json;*/ /*using Newtonsoft.Json;*/
namespace ServerTest; namespace ServerTest;
/// <summary>
/// xUnit将会对每个测试方法创建一个测试上下文IClassFixture可以用来创建类中共享测试上下文
///
/// XUnit 的测试方法不是按照顺序执行,所以注意对象状态
///
/// 一般单元测试,每个测试函数应当是独立的,不让它们按照顺序执行,在一般情况下是最好的做法,参考
/// https://learn.microsoft.com/en-us/dotnet/core/testing/unit-testing-best-practices
/// 目前涉及到一些文件的同步所以按照顺序执行相对较好这使用了xUnit的方法使它们按照顺序执行
/// </summary>
///
[TestCaseOrderer(
ordererTypeName: "XUnit.Project.Orderers.PriorityOrderer",
ordererAssemblyName: "ServerTest"
)]
public class DirFileOpTest : IDisposable public class DirFileOpTest : IDisposable
{ {
private readonly FilesSeed filesSeed = new(); private readonly FilesSeed filesSeed = new();
public void Dispose() public void Dispose()
{ {
//filesSeed.Dispose(); filesSeed.Dispose();
GC.SuppressFinalize(this); GC.SuppressFinalize(this);
} }
/// <summary> /// <summary>
/// 测试文件目录写入和提取 /// 测试文件目录写入和提取
/// </summary> /// </summary>
[Fact] [Fact, TestPriority(0)]
public void FileDirWriteExtract() public void FileDirWriteExtract()
{ {
filesSeed.NewDir.WriteByThisInfo(filesSeed.fileDirOp); filesSeed.NewDir.WriteByThisInfo(filesSeed.fileDirOp);
@ -34,7 +46,7 @@ public class DirFileOpTest : IDisposable
/// <summary> /// <summary>
/// 测试文件差异比较 /// 测试文件差异比较
/// </summary> /// </summary>
[Fact] [Fact, TestPriority(1)]
public void FileDirDiff() public void FileDirDiff()
{ {
var cDDir = filesSeed.NewDir.Diff(filesSeed.OldDir); var cDDir = filesSeed.NewDir.Diff(filesSeed.OldDir);
@ -49,7 +61,7 @@ public class DirFileOpTest : IDisposable
/// <summary> /// <summary>
/// 测试同步是否成功 /// 测试同步是否成功
/// </summary> /// </summary>
[Fact] [Fact, TestPriority(2)]
public void SyncFileDir() public void SyncFileDir()
{ {
filesSeed.OldDir.WriteByThisInfo(filesSeed.fileDirOp); filesSeed.OldDir.WriteByThisInfo(filesSeed.fileDirOp);
@ -63,7 +75,7 @@ public class DirFileOpTest : IDisposable
/// <summary> /// <summary>
/// 测试文件合并 /// 测试文件合并
/// </summary> /// </summary>
[Fact] [Fact, TestPriority(3)]
public void DirsCombine() public void DirsCombine()
{ {
filesSeed.OldDir.CombineJustObject(filesSeed.DiffDir); filesSeed.OldDir.CombineJustObject(filesSeed.DiffDir);
@ -73,18 +85,18 @@ public class DirFileOpTest : IDisposable
Assert.True(filesSeed.OldDir.IsEqual(filesSeed.NewDir), "合并结果不一致!"); Assert.True(filesSeed.OldDir.IsEqual(filesSeed.NewDir), "合并结果不一致!");
} }
[Fact] // [Fact]
public void Tt() // public void Tt()
{ // {
filesSeed.NewDir.WriteByThisInfo(filesSeed.fileDirOp); // filesSeed.NewDir.WriteByThisInfo(filesSeed.fileDirOp);
var c = new FileDirOpForPack(filesSeed.NewDir.FormatedPath, filesSeed.TestPath + "/"); // var c = new FileDirOpForPack(filesSeed.NewDir.FormatedPath, filesSeed.TestPath + "/");
c.FinallyCompress(); // c.FinallyCompress();
var d = new FileDirOpForUnpack( // var d = new FileDirOpForUnpack(
filesSeed.TestPath + "/", // filesSeed.TestPath + "/",
filesSeed.TestPath + "/", // filesSeed.TestPath + "/",
c.SyncId // c.SyncId
); // );
d.FirstUnComparess(); // d.FirstUnComparess();
} // }
} }

View file

@ -0,0 +1,41 @@
using Xunit.Abstractions;
using Xunit.Sdk;
using XUnit.Project.Attributes;
namespace XUnit.Project.Orderers;
public class PriorityOrderer : ITestCaseOrderer
{
public IEnumerable<TTestCase> OrderTestCases<TTestCase>(
IEnumerable<TTestCase> testCases) where TTestCase : ITestCase
{
string assemblyName = typeof(TestPriorityAttribute).AssemblyQualifiedName!;
var sortedMethods = new SortedDictionary<int, List<TTestCase>>();
foreach (TTestCase testCase in testCases)
{
int priority = testCase.TestMethod.Method
.GetCustomAttributes(assemblyName)
.FirstOrDefault()
?.GetNamedArgument<int>(nameof(TestPriorityAttribute.Priority)) ?? 0;
GetOrCreate(sortedMethods, priority).Add(testCase);
}
foreach (TTestCase testCase in
sortedMethods.Keys.SelectMany(
priority => sortedMethods[priority].OrderBy(
testCase => testCase.TestMethod.Method.Name)))
{
Console.WriteLine(testCase);
yield return testCase;
}
}
private static TValue GetOrCreate<TKey, TValue>(
IDictionary<TKey, TValue> dictionary, TKey key)
where TKey : struct
where TValue : new() =>
dictionary.TryGetValue(key, out TValue? result)
? result
: (dictionary[key] = new TValue());
}

View file

@ -0,0 +1,9 @@
namespace XUnit.Project.Attributes;
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class TestPriorityAttribute : Attribute
{
public int Priority { get; private set; }
public TestPriorityAttribute(int priority) => Priority = priority;
}