NewLife/X

优化测试用例等待与资源释放提升效率

缩短多处 Thread.Sleep/Task.Delay 等待时长,提高测试执行速度。日志相关测试改为轮询检测文件生成与内容写入,增强健壮性。DeferredQueueTests 增加 Commit 调用,确保资源释放。NetServerTests 优化客户端连接释放,增加超时与 finally 中 Stop/Dispose,防止资源泄漏。TimerXTests 等多处移除或缩短无用等待,缓存与 Add/Replace 测试超时设置同步优化,保证测试高效且稳定。
石头 authored at 2026-09-01 16:22:05
c917736
Tree
1 Parent(s) 2c5e6af
Summary: 8 changed files with 92 additions and 35 deletions.
Modified +1 -1
Modified +5 -5
Modified +25 -2
Modified +26 -7
Modified +0 -3
Modified +11 -0
Modified +18 -8
Modified +6 -9
Modified +1 -1
diff --git a/XUnitTest.Core/Caching/ICacheContractTests.cs b/XUnitTest.Core/Caching/ICacheContractTests.cs
index 98ea733..72dafa1 100644
--- a/XUnitTest.Core/Caching/ICacheContractTests.cs
+++ b/XUnitTest.Core/Caching/ICacheContractTests.cs
@@ -75,7 +75,7 @@ public class ICacheContractTests
         cache.Set(key, "will_expire", 1); // 1 秒过期
         Assert.Equal("will_expire", cache.Get<String>(key));
 
-        await Task.Delay(1500);
+        await Task.Delay(1100);
         // 已过期,不应返回值
         var val = cache.Get<String>(key);
         Assert.Null(val);
Modified +5 -5
diff --git a/XUnitTest.Core/Caching/MemoryCacheTests.cs b/XUnitTest.Core/Caching/MemoryCacheTests.cs
index 75557a3..91d60c8 100644
--- a/XUnitTest.Core/Caching/MemoryCacheTests.cs
+++ b/XUnitTest.Core/Caching/MemoryCacheTests.cs
@@ -77,8 +77,8 @@ public class MemoryCacheTests
         var ic = Cache;
         var key = "Name";
 
-        ic.Set(key, Environment.UserName, 2);
-        var rs = ic.Add(key, Environment.MachineName, 2);
+        ic.Set(key, Environment.UserName, 1);
+        var rs = ic.Add(key, Environment.MachineName, 1);
         Assert.False(rs);
 
         var name = ic.Get<String>(key);
@@ -87,14 +87,14 @@ public class MemoryCacheTests
 
         var old = ic.Replace(key, Environment.MachineName);
         Assert.Equal(Environment.UserName, old);
-        ic.SetExpire(key, TimeSpan.FromSeconds(2));
+        ic.SetExpire(key, TimeSpan.FromSeconds(1));
 
         name = ic.Get<String>(key);
         Assert.Equal(Environment.MachineName, name);
         Assert.NotEqual(Environment.UserName, name);
 
-        Thread.Sleep(2000);
-        rs = ic.Add(key, Environment.MachineName, 2);
+        Thread.Sleep(1100);
+        rs = ic.Add(key, Environment.MachineName, 1);
         Assert.True(rs);
     }
 
Modified +25 -2
diff --git a/XUnitTest.Core/Log/LevelLogTests.cs b/XUnitTest.Core/Log/LevelLogTests.cs
index a79be8f..9bea7a5 100644
--- a/XUnitTest.Core/Log/LevelLogTests.cs
+++ b/XUnitTest.Core/Log/LevelLogTests.cs
@@ -30,8 +30,31 @@ namespace XUnitTest.Log
             log.Error("error");
             log.Fatal("fatal");
 
-            // 等待日志落盘
-            Thread.Sleep(2000);
+            // 日志通过线程池异步写入,通常毫秒级完成;轮询等待(兜底 5s 定时器刷盘路径)
+            var files = new[]
+            {
+                p + $"debug\\{DateTime.Today:yyyy_MM_dd}.log",
+                p + $"info\\{DateTime.Today:yyyy_MM_dd}.log",
+                p + $"warn\\{DateTime.Today:yyyy_MM_dd}.log",
+                p + $"error\\{DateTime.Today:yyyy_MM_dd}.log",
+                p + $"fatal\\{DateTime.Today:yyyy_MM_dd}.log",
+            };
+            var deadline = DateTime.Now.AddSeconds(6);
+            while (DateTime.Now < deadline)
+            {
+                var ok = true;
+                for (var i = 0; i < files.Length; i++)
+                {
+                    if (!File.Exists(files[i].GetFullPath()))
+                    {
+                        ok = false;
+                        break;
+                    }
+                }
+                if (ok) break;
+
+                Thread.Sleep(50);
+            }
 
             var f = p + $"debug\\{DateTime.Today:yyyy_MM_dd}.log";
             Assert.True(File.Exists(f.GetFullPath()));
Modified +26 -7
diff --git a/XUnitTest.Core/Log/TextFileLogTests.cs b/XUnitTest.Core/Log/TextFileLogTests.cs
index 0d7b388..13d6698 100644
--- a/XUnitTest.Core/Log/TextFileLogTests.cs
+++ b/XUnitTest.Core/Log/TextFileLogTests.cs
@@ -59,16 +59,35 @@ public class TextFileLogTests : IDisposable
         var log = TextFileLog.Create(_logDir);
         log.Info("TextFileLogTests: 测试写入消息");
 
-        // 等待异步写入完成
-        Thread.Sleep(6000);
+        // 日志通过线程池异步写入,通常毫秒级完成;轮询等待(兜底 5s 定时器刷盘路径)
+        var content = String.Empty;
+        var deadline = DateTime.Now.AddSeconds(6);
+        while (DateTime.Now < deadline)
+        {
+            var files = Directory.GetFiles(_logDir, "*.log");
+            if (files.Length > 0)
+            {
+                // 日志文件可能被TextFileLog持有锁,使用FileShare.ReadWrite读取
+                try
+                {
+                    using var fs = new FileStream(files[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+                    using var sr = new StreamReader(fs);
+                    content = sr.ReadToEnd();
+                    if (content.Contains("测试写入消息")) break;
+                }
+                catch (IOException) { }
+            }
+
+            Thread.Sleep(50);
+        }
 
-        var files = Directory.GetFiles(_logDir, "*.log");
-        Assert.True(files.Length > 0, "应生成日志文件");
+        var files2 = Directory.GetFiles(_logDir, "*.log");
+        Assert.True(files2.Length > 0, "应生成日志文件");
 
         // 日志文件可能被TextFileLog持有锁,使用FileShare.ReadWrite读取
-        using var fs = new FileStream(files[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
-        using var sr = new StreamReader(fs);
-        var content = sr.ReadToEnd();
+        using var fs2 = new FileStream(files2[0], FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+        using var sr2 = new StreamReader(fs2);
+        content = sr2.ReadToEnd();
         Assert.Contains("测试写入消息", content);
     }
 
Modified +0 -3
diff --git a/XUnitTest.Core/Model/ActorTests.cs b/XUnitTest.Core/Model/ActorTests.cs
index d509082..61570ee 100644
--- a/XUnitTest.Core/Model/ActorTests.cs
+++ b/XUnitTest.Core/Model/ActorTests.cs
@@ -68,9 +68,6 @@ public class ActorTests
         Assert.Equal(1000, actor.Total);
 
         XTrace.WriteLine("TestCount End");
-
-        Thread.Sleep(5000);
-        XTrace.WriteLine("End");
     }
 
     private class TestActor : Actor
Modified +11 -0
diff --git a/XUnitTest.Core/Model/DeferredQueueTests.cs b/XUnitTest.Core/Model/DeferredQueueTests.cs
index 2cf8a78..270e483 100644
--- a/XUnitTest.Core/Model/DeferredQueueTests.cs
+++ b/XUnitTest.Core/Model/DeferredQueueTests.cs
@@ -53,6 +53,11 @@ public class DeferredQueueTests
         // 再次获取应返回同一对象
         var obj2 = queue.GetOrAdd<TestObj>("key1");
         Assert.Same(obj, obj2);
+
+        // GetOrAdd 借出的对象用完必须 Commit,否则销毁时等待 WaitForBusy。
+        // 两次 GetOrAdd 各借出一次,需按调用次数提交
+        queue.Commit("key1");
+        queue.Commit("key1");
     }
 
     [Fact(DisplayName = "GetOrAdd使用工厂方法")]
@@ -63,6 +68,9 @@ public class DeferredQueueTests
         var obj = queue.GetOrAdd<TestObj>("key1", k => new TestObj { Name = k });
         Assert.NotNull(obj);
         Assert.Equal("key1", obj!.Name);
+
+        // GetOrAdd 借出的对象用完必须 Commit,否则销毁时等待 WaitForBusy
+        queue.Commit("key1");
     }
 
     [Fact(DisplayName = "Commit提交")]
@@ -97,6 +105,9 @@ public class DeferredQueueTests
         queue.GetOrAdd<TestObj>("c");
 
         Assert.True(queue.Times >= 3);
+
+        // GetOrAdd 借出的对象用完必须 Commit,否则销毁时等待 WaitForBusy
+        queue.Commit("c");
     }
 
     [Fact(DisplayName = "Name默认值")]
Modified +18 -8
diff --git a/XUnitTest.Core/Net/NetSeverTests.cs b/XUnitTest.Core/Net/NetSeverTests.cs
index 35a9f64..1f5692f 100644
--- a/XUnitTest.Core/Net/NetSeverTests.cs
+++ b/XUnitTest.Core/Net/NetSeverTests.cs
@@ -34,19 +34,29 @@ namespace XUnitTest.Net
 
             server.Start();
 
+            try
             {
                 var uri = new NetUri($"tcp://127.0.0.1:{server.Port}");
-                var client = new TcpClient();
-                client.Connect(uri.EndPoint);
+                using (var client = new TcpClient())
+                {
+                    // 设置接收超时,避免阻塞导致测试挂起
+                    client.ReceiveTimeout = 3000;
 
-                var ns = client.GetStream();
-                ns.Write("Stone@NewLife.com".GetBytes());
+                    client.Connect(uri.EndPoint);
 
-                var buf = new Byte[1024];
-                var rs = ns.Read(buf, 0, buf.Length);
-            }
+                    using var ns = client.GetStream();
+                    ns.Write("Stone@NewLife.com".GetBytes());
 
-            Thread.Sleep(3_000);
+                    var buf = new Byte[1024];
+                    var rs = ns.Read(buf, 0, buf.Length);
+                }
+            }
+            finally
+            {
+                // 确保停止并释放服务器,避免长期占用端口和后台资源
+                server.Stop("UnitTest");
+                server.TryDispose();
+            }
         }
     }
 }
\ No newline at end of file
Modified +6 -9
diff --git a/XUnitTest.Core/Threading/TimerXTests.cs b/XUnitTest.Core/Threading/TimerXTests.cs
index ea75ab0..cec4470 100644
--- a/XUnitTest.Core/Threading/TimerXTests.cs
+++ b/XUnitTest.Core/Threading/TimerXTests.cs
@@ -41,8 +41,6 @@ public class TimerXTests
         Assert.False(timer.Async);
         Assert.False(timer.Absolutely);
 
-        Thread.Sleep(3050);
-
         //Assert.Equal(10, count);
         //Assert.Equal(10, timer.Timers);
     }
@@ -57,7 +55,8 @@ public class TimerXTests
         ms = ms + 100 - timer.NextTick;
         Assert.InRange(ms, 0, 5);
 
-        Thread.Sleep(1000);
+        // 留一点时间让定时器至少触发一次
+        Thread.Sleep(300);
     }
 
     private static void DoSyncTest(Object state)
@@ -80,7 +79,8 @@ public class TimerXTests
         ms = ms + 100 - timer.NextTick;
         Assert.InRange(ms, 0, 5);
 
-        Thread.Sleep(1000);
+        // 留一点时间让定时器至少触发一次
+        Thread.Sleep(300);
     }
 
     private static async Task DoAsyncTest(Object state)
@@ -102,7 +102,8 @@ public class TimerXTests
         var ms = timer.NextTick - Runtime.TickCount64;
         Assert.InRange(ms, 0, 99);
 
-        Thread.Sleep(1000);
+        // 留一点时间让定时器至少触发一次
+        Thread.Sleep(300);
     }
 
     private static async Task DoAbsolutelyTest(Object state)
@@ -126,10 +127,6 @@ public class TimerXTests
 
         var ms = timer.NextTick - Runtime.TickCount64;
         Assert.InRange(ms, 0, 3999 + 1000);
-
-#if DEBUG
-        Thread.Sleep(5500);
-#endif
     }
 
     private static async Task DoCronTest(Object state)