繁体   English   中英

单元测试通过调试,但在运行时挂起

[英]Unit-test passes in Debug, but hangs when Run

我有一个奇怪的问题。 我有一个单元测试,它总是卡在“运行模式”下。 当我在Debug中运行相同的测试且没有断点时,该测试每次都会通过。

基本上,这是套接字连接测试。 我首先断开套接字,然后尝试重新连接,然后尝试检查重新连接是否成功。

在连接代码中的某个地方,我检查是否有套接字异常。 发生这种情况时,会在对话框中为用户提供一些选择,而连接代码会通过AutoResetEvent挂起,等待决策。

正是这个AutoResetEvent挂起了系统。 它必须由单元测试中的代码提供。 但是我的问题是,这如何在调试模式下通过? 通过Visual Studio自动设置AutoResetEvents的调试模式有什么特别之处吗?

编辑

确实,这是比赛条件。 我在断开连接代码之后在代码中添加了一个延迟,现在它可以工作了。 但这仍然让我感到奇怪,因为这里有一个比赛条件。 让我通过粘贴一些代码来详细说明。

这是测试代码:

MySystem.FindEquipment(new List<string>(1) { "192.1.1.243:28000" });
MySystem.ConstructSystem();
MySystem.IsConstructedFlag.WaitOne();
Assert.AreEqual(1, MySystem.CommunicationController.HardwareIPList.Count);

PFFrame frame1 = MySystem.Frames["0.x.x"];

Assert.IsTrue(frame1.Disconnect());
Thread.Sleep(100);
Assert.IsTrue(frame1.Connect());

令我震惊的原因是,我在调用连接代码之前正在等待diconnect代码的返回。 断开连接代码的最后一部分如下所示:

lclSocket.Shutdown(SocketShutdown.Both);
lclSocket.Close();
OnSocketDisconnected(new PFSocketConnectionEventArgs(ipEp));
return true;

是因为Socket.Shutdown()和/或Socket.Close()方法在线程上运行它吗? 因此,即使我从断开连接代码返回一个值,套接字实际上并没有真正断开连接?

听起来像是比赛条件。 调试代码通常在“幕后”运行许多额外的东西,并且时间上的差异可能会导致测试失败。

当然,如果没有看到代码,我们真的无法为您提供很大帮助。

最有可能是由于线程竞赛。 它们对时序非常敏感,并且Debug版本中的时序会有所不同。 您可以使用CHESS之类的工具来执行此类错误。

但是请先使用工具+附加到流程。 调试+全部破坏,调试+ Windows +线程,然后查看线程调用堆栈。 您也许可以查看比赛或僵局的原因。

曾经有一个类似的问题,我比较了两个日期,并期望一个日期之后的另一个日期,但是由于执行速度如此之快,他们收到了相同的时间戳。

该测试告诉您您的代码未与所使用的套接字库正确隔离。 您正在测试的代码不必依赖于此库中的某些工件。 您需要在套接字库之间添加一个抽象,以将工件放入acoount中。

我说这的原因是,如果套接字实际上断开123,251次<100 mSecs,但是第123,252次断开需要101 mSecs。

我强烈建议几乎所有的单元测试代码都不要使用线程。 我将单元测试中任何类型的线程调用视为代码气味。 通常,我希望看到线程问题的地方是集成级别。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM