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

发布于 2024-09-10 19:05:22 字数 1158 浏览 14 评论 0原文

我有一个奇怪的问题。我有一个单元测试一直陷入运行模式。当我在调试中运行相同的测试时,没有断点,测试每次都会通过。

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

在连接代码中的某个位置,我检查是否存在套接字异常。发生这种情况时,用户会在对话框中看到一些选择,而连接代码则通过 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() 方法运行它的线程吗?因此,即使我从断开连接代码返回一个值,套接字实际上并没有真正断开连接?

I have an odd problem. I have a unit test that keeps getting stuck in Run Mode. When I run the same test in Debug, with no breakpoints, the test passes every time.

Basically, it is a socket connection test. I first disconnect a socket, and then try to reconnect, and I am trying to check if the reconnection was successful.

Somewhere in the connect code, I check if there was a socket exception. When this happens, the user is presented with some choices in a dialog, while the connection code hangs via an AutoResetEvent, waiting for a decision.

It is this AutoResetEvent that hangs the system. It must be provided by code in the unit test.
But my question is, how come this passes in Debug mode? Is there something special about debug mode whereby AutoResetEvents are automatically set by Visual Studio?

EDIT

It was indeed a race condition. I added a delay in the code after my disconnect code, and it works now. But it still strikes me as odd that there is a race condition to begin with. Let me elaborate by pasting some of the code.

This is the test code:

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());

The reason this strikes me, is that I am waiting for a return on the diconnect code, before calling the connect code. The last part of the disconnect code looks like this:

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

Is it be because Socket.Shutdown(), and/or Socket.Close() methods run it threads? Thus, even though I am returning a value from my disconnect code, the socket isn't actually truly disconnected?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

魂牵梦绕锁你心扉 2024-09-17 19:05:22

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

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

It sounds like a race condition. Debug code usually runs a lot of extra stuff 'under the hood', and that difference in timing is probably throwing your tests off.

Of course without seeing code, we really can't help you very much.

〃温暖了心ぐ 2024-09-17 19:05:22

最有可能是因为线程竞争。它们对时序非常敏感,并且调试构建中的时序会有所不同。你可以使用象棋这样的工具来练习这样的错误。

但首先使用“工具”+“附加到进程”。 Debug + Break All、Debug + Windows + Threads 并查看线程调用堆栈。您也许能够看到争用或死锁的原因。

Most likely because of a threading race. They are very sensitive to timing and the timing in the Debug build will be different. You can use a tool like CHESS to exercise bugs like that.

But use Tools + Attach to Process first. Debug + Break All, Debug + Windows + Threads and look at the thread call stacks. You might be able to see the cause of the race or deadlock.

请帮我爱他 2024-09-17 19:05:22

有一次遇到类似的问题,我比较了两个日期,并期望一个日期接一个日期,但由于执行得那么快,他们收到了相同的时间戳。

Had a similar issue once where I compared two dates, and expected one date after the other, but because it was executed that fast, they received the same timestamp.

风筝在阴天搁浅。 2024-09-17 19:05:22

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

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

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

This test is telling you that your code is not properly isolated from the socket library you are using. The code that you are testing should not have to depend upon certain artifacts with-in this library. You need to add an abstraction between the socket library that takes the artifacts into acoount.

The reason I say this is, is what if the socket actually disconnects 123,251 times < 100 mSecs, but the 123,252nd time disconnecting takes 101 mSecs.

I would highly recommend that almost all your unit-testing code not use threading. I look at threading calls of any type in my unit tests as a code smell. usually where I want to see threading issues is at the integration level.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文