如何在NUnit中自动并行运行两个测试实现跨地址空间Socket通信?
实现跨进程并行测试的自动化方案
要实现单个测试触发两个独立地址空间的Test1和Test2并行运行,核心思路是在主测试中启动两个独立的NUnit测试进程,分别执行Test1和Test2。这样两个测试会运行在不同进程中,拥有各自的地址空间,完全满足真实网络通信的模拟需求。
具体步骤:
- 标记独立测试为显式执行:给Test1和Test2加上
[Explicit]属性,避免它们被常规测试套件自动执行,只能通过指定命令触发。 - 主测试中启动独立进程:在主测试方法里,通过
Process.Start()调用dotnet test(或nunit-console.exe),分别指定运行Test1和Test2。 - 同步与结果验证:等待两个测试进程完成,通过临时文件、命名管道等方式收集测试结果,在主测试中完成断言。
代码示例:
定义独立的Test1和Test2:
using NUnit.Framework; using System.IO; using System.Net; using System.Net.Sockets; namespace YourTestNamespace { [TestFixture] public class NetworkProtocolTests { // 测试服务器角色,仅显式触发 [Test, Explicit] public void Test1_ServerSide() { var listener = new TcpListener(IPAddress.Loopback, 8888); listener.Start(); using var client = listener.AcceptTcpClient(); using var stream = client.GetStream(); // 读取客户端数据,验证协议逻辑 var buffer = new byte[1024]; var bytesRead = stream.Read(buffer, 0, buffer.Length); var receivedData = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead); // 模拟响应 var response = System.Text.Encoding.UTF8.GetBytes("ACK:" + receivedData); stream.Write(response, 0, response.Length); // 将验证结果写入临时文件 File.WriteAllText(Path.Combine(Path.GetTempPath(), "server_result.txt"), receivedData == "PROTOCOL_TEST_DATA" ? "ServerValidationPassed" : "ServerValidationFailed"); listener.Stop(); } // 测试客户端角色,仅显式触发 [Test, Explicit] public void Test2_ClientSide() { using var client = new TcpClient(); client.Connect(IPAddress.Loopback, 8888); using var stream = client.GetStream(); // 发送协议测试数据 var testData = System.Text.Encoding.UTF8.GetBytes("PROTOCOL_TEST_DATA"); stream.Write(testData, 0, testData.Length); // 读取响应 var buffer = new byte[1024]; var bytesRead = stream.Read(buffer, 0, buffer.Length); var response = System.Text.Encoding.UTF8.GetString(buffer, 0, bytesRead); // 将验证结果写入临时文件 File.WriteAllText(Path.Combine(Path.GetTempPath(), "client_result.txt"), response == "ACK:PROTOCOL_TEST_DATA" ? "ClientValidationPassed" : "ClientValidationFailed"); } } }
主测试(触发跨进程并行执行):
using NUnit.Framework; using System.Diagnostics; using System.IO; using System.Reflection; namespace YourTestNamespace { [TestFixture] public class AutomatedCrossProcessTest { [Test] public void RunCrossProcessProtocolTest() { // 初始化临时文件路径 var serverResultPath = Path.Combine(Path.GetTempPath(), "server_result.txt"); var clientResultPath = Path.Combine(Path.GetTempPath(), "client_result.txt"); // 清理旧文件 File.Delete(serverResultPath); File.Delete(clientResultPath); // 获取测试项目工作目录 var workingDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); // 启动服务器测试进程 var serverProcess = Process.Start(new ProcessStartInfo { FileName = "dotnet", Arguments = $"test --filter FullyQualifiedName={typeof(NetworkProtocolTests).FullName}.Test1_ServerSide", WorkingDirectory = workingDir, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }); // 启动客户端测试进程(延迟1秒确保服务器已启动,可根据实际调整) System.Threading.Thread.Sleep(1000); var clientProcess = Process.Start(new ProcessStartInfo { FileName = "dotnet", Arguments = $"test --filter FullyQualifiedName={typeof(NetworkProtocolTests).FullName}.Test2_ClientSide", WorkingDirectory = workingDir, RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }); // 等待两个进程完成 serverProcess?.WaitForExit(); clientProcess?.WaitForExit(); // 读取结果并断言 Assert.That(File.Exists(serverResultPath), Is.True, "Server test did not generate result"); Assert.That(File.Exists(clientResultPath), Is.True, "Client test did not generate result"); var serverResult = File.ReadAllText(serverResultPath); var clientResult = File.ReadAllText(clientResultPath); Assert.That(serverResult, Is.EqualTo("ServerValidationPassed")); Assert.That(clientResult, Is.EqualTo("ClientValidationPassed")); // 清理临时文件 File.Delete(serverResultPath); File.Delete(clientResultPath); } } }
注意事项:
- 端口冲突处理:如果需要多次运行,建议通过命令行参数动态传递端口号,避免硬编码端口导致冲突。
- 进程同步优化:示例中用
Thread.Sleep()做简单同步,生产环境可以用更可靠的方式(比如让服务器监听端口成功后写入标记文件,客户端检测到标记再启动)。 - 结果传递方式:除了临时文件,还可以用命名管道、共享内存或本地HTTP接口传递结果,效率更高。
- 异常处理:实际代码中要添加进程启动失败、文件读取失败的异常捕获逻辑,确保测试稳定性。
内容的提问来源于stack exchange,提问作者user4779
相关产品推荐
相关产品推荐

