VS 2010 Test Runner错误“测试运行时,代理进程已停止。”


101

在Visual Studio 2010中,我有许多单元测试。当我一次使用测试列表运行多个测试时,有时会针对一个或多个测试显示以下错误:

测试正在运行时,代理进程已停止。

决不会同一测试失败,如果我再次尝试运行测试,它将成功。

在Connect上发现了此错误报告,这似乎是相同的问题,但没有提供解决方案。

有人看到过这种行为吗?我该如何避免呢?

编辑

我仍在遇到此错误,在相同软件/硬件设置下的许多同事也是如此。到目前为止,我已经评估了答案,但是并不能解决问题。我开始为解决这个问题提供悬赏。


我得到同样的东西。我挖了进去,但没有解决方案至今
马克

有什么消息吗?同样的问题在这里...
Peter Gfader

@Peter,请参阅下面我的评论可接受的答案。那是我的解决方案,但我不知道您的问题是否相似。
driis

我有一个未捕获的异常相同的行为。当我在构建服务器上运行Visual Studio并获得一个Assert-Window时,该异常对我可见。由于存在断言窗口,因此测试无法继续进行。

Answers:


41

我刚刚遇到了类似的问题:有些测试失败,并且在不同的测试运行中它们是不同的。我不知道发生这种情况的确切原因,但是当我在一个类中添加了终结器时,它才开始发生。当我禁用终结器时,问题消失了。当我打开finalizer时,问题又回来了。

现在,我不知道该如何克服。


16
谢谢-这个答案使我找到了解决方案。我只有几种类型的终结器,而且肯定的是,删除它们也解决了问题。经过进一步的研究,我发现一个终结器存在一个细微的错误,该错误仅在构造函数中引发异常时才发生,并且终结器尝试终结未完全构造的对象。结论:如果类型的终结器中发生异常,并且该终结器在所有测试完成之前运行,则Visual Studio会给出我所遇到的错误;否则,将出现错误。没有任何进一步的解释,并经过随机测试。
driis 2010年

6
我的代码中没有终结器/析构函数...〜MyClass()并得到相同的错误。Resharper的运行测试都是绿色的
Peter Gfader 2010年

6
终结器中未捕获异常的问题是后台任务中未捕获异常的一种特殊情况,可以通过某些测试来启动或调度(也许隐式)后台任务,即使测试已完成,该异常也可以继续执行。
satorg

1
与Peter一样,Resharper的测试跑步者给了我绿色。VS 2010测试运行程序在带有析构函数的类上失败。
RyBolt 2010年

1
我不小心在Dispose()方法中编写了一个无限递归循环,这也导致了这种情况。
罗伯特

88

该消息是由与正在执行的测试线程不同的线程上异常引起的。到目前为止,所有答案都归结为这个简单的解释。在这种情况下,Visual Studio中的一个已知错误是不显示任何明智的信息。

如果正在执行的测试线程以外的线程抛出异常,Visual Studio的测试运行程序将完全阻塞:它被吞没,没有输出,没有机会进行拦截和调试,除了被认为是您单位的烧毁的闷烧烂摊子之外,什么也没有测试。


我也发生了同样的事情-我的测试产生了一个单独的线程,这出现了异常。在线程内部捕获异常至少可以让我打印该异常并知道发生了什么。但是请注意不要将Assert.Fail()放在线程的catch块中,这会引发一个单独的异常,使您回到开始的位置。
凯尔·克鲁

4
对我来说同样的事情,除了堆栈溢出,与Java相比,在C#中更难追踪...
John Gardner

确实,当我开始使用Thread对象并调用Abort()停止它们时,我注意到了这种情况。
espaciomore

1
async void在测试期间调用的方法引发异常时,也会发生这种情况
Mathias Becher

1
请注意,trx可能包含错误信息,您可以通过在文本编辑器中或在Visual Studio中打开它,然后在“ 测试结果”窗口中单击“ 测试运行错误”超链接来查看它。
Ohad Schneider

16

我遇到了这个问题,事实证明这是我的代码中的一个问题,测试框架无法正确捕获。偶然的重构让我留下了以下代码:

public void GetThingy()
{
    this.GetThingy();
}

当然,这是无限递归,并导致了StackOverflowException(我想)。这是令人恐惧的:“测试运行时,代理进程已停止。”

快速代码检查向我显示了问题,现在我的测试运行良好。希望这会有所帮助-可能值得检查代码以查找问题,或者可以将一些内容提取到控制台应用程序中并检查其是否正常工作。


3
这不是问题所在(我知道是因为每次失败都会导致不同的测试失败),但是感谢您抽出宝贵的时间来回答。
driis

6
+1,因为这是此问题的许多有效答案之一。我的一个类的静态方法中的SO异常导致了此问题。
彼得·拉康伯(Peter T. LaComb)2011年

6
+1,我也看到了。调试测试(在VS 11中)可以很快找到问题所在。
杰里米·麦基

同意杰里米。如果调试单元测试,则它应在引发异常的位置停止。但是,如果您仅运行单元测试,则它们都将带有绿灯。很奇怪
安德鲁·史蒂芬斯

8

通过查看测试结果文件(/TestResults/*.trx),我能够找到问题的根源。它提供了后台线程中发生的异常的完整详细信息,一旦我解决了该异常,“停止...”错误消失了。

以我为例,我在单元测试中无意中启动了GUI,最终导致引发System.ComponentModel.InvalidAsynchronousStateException。

所以我的.trx文件包含:

   <RunInfo computerName="DT-1202" outcome="Error" timestamp="2013-07-29T13:52:11.2647907-04:00">
    <Text>One of the background threads threw exception: 
System.ComponentModel.InvalidAsynchronousStateException: An error occurred invoking the method.  The destination thread no longer exists.
at System.Windows.Forms.Control.WaitForWaitHandle(WaitHandle waitHandle)
at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)
at System.Windows.Forms.Control.Invoke(Delegate method, Object[] args)
at System.Windows.Forms.Control.Invoke(Delegate method)
...
</Text>
  </RunInfo>

它没有提供有关导致错误的测试的任何信息,但确实向我显示了异常在哪里,这非常有用。


5

该消息通常在测试过程崩溃时生成,并且可能在后台线程上出现未处理的异常,发生堆栈溢出或显式调用Process.GetCurrentProcess().Kill()or 时发生Environment.Exit。另一个可能的原因是非托管代码中的访问冲突。

没有人提到过事件日志中可能还有其他信息。通常,您不会获得有关导致测试失败的大量信息,但是,如果在后台线程上发生未处理的异常,则测试框架会使用源VSTTExecution将详细信息写入应用程序事件日志。如果没有任何信息写入事件日志,则很可能是上面列出的其他原因之一。


4

就我而言,解决方案是通过检查“ 输出窗口”解决的。

'QTAgent32.exe'(托管(v4.0.30319)):已加载'C:\ TestResults \ bdewey_XXXXXX072 2011-01-11 17_00_40 \ Out \ MyCode.dll',已加载符号。E,9024,9,2011/01/11,17:00:46.827,XXXXX072 \ QTAgent32.exe,未处理的异常被捕获,通过Watson报告:[异常消息]

就我而言,我有一个FileSystemWatcher,它在一个单独的线程上引发了一个错误。


您是如何解决的?我正在使用M $中的一些示例代码,将FileSystemWatcher包装在服务中,并围绕该服务创建了WF工作流。我得到了很多……
ekkis 2013年

就我而言,两次测试均失败。当我转到“ 输出”窗格并选择“ 测试”时,它提到“一个后台线程引发了异常” ...实际上,有9个NullReferenceExceptions正在堆栈跟踪中等待着我。谢谢,这非常有帮助!
Qwertie

3

我在删除时遇到了相同的问题并解决了

Environment.Exit(0);

因此,我很确定,当您的测试或被测方法导致执行过程终止时,会发生此错误。


2

感谢您发布问题。我只是遇到了这个问题,并找出了您可能会遇到的原因。

可能发生了异步异常

在测试设置期间,我创建一个对象,该对象将线程池中的工作线程排队。如果我足够快地进行调试,那么我的代码就会通过。

如果工作线程启动并在测试设置完成之前出现错误,那么我将无故中止。

如果工作线程在测试开始后开始并且出现错误,那么我得到的结果是:错误-测试运行时代理进程已停止。

重要说明:这是我在多个测试中都使用的组件。如果测试框架遇到太多此类错误,它将中止其余测试。

希望这可以帮助


谢谢你的回答。我知道异步异常可能会导致类似于我所看到的事情,但是我几乎可以肯定情况并非如此。代码是针对Web应用的,我们不会异步执行任何操作。另外,似乎哪个测试失败是随机的。
driis

2

我向测试器〜ClassName(){}中添加了try / catch块,这些块是在测试中涉及的任何类中定义的。这为我解决了问题。

~MyClass()
{
    try
    {
        // Some Code
    }
    catch (Exception e)
    {
        // Log the exception so it's not totally hidden
        // Console.WriteLine(e.ToString());
    }
}

2

要找出引发异常的位置,请单击“测试结果”窗口中感叹号图标旁边的“测试运行错误”超链接。打开带有堆栈跟踪的窗口。

这对于查找错误很有帮助!


1

我遇到了同样的问题,这是由非托管资源的终结器(文件写入器由于某种原因而无法正确处置)引起的。

将终结器代码包装在吞下异常的try-catch中后,问题消失了。我不建议像这样吞下异常,因此,找出为什么首先发生异常显然是明智的。


1

我曾经在奇怪的情况下发生过这种情况,而罪魁祸首几乎总是变成线程。

奇怪的是,所有测试在开发机器上都能正常工作,然后在构建服务器上随机失败。

经过仔细检查,结果发现尽管测试在开发箱中被列为通过,但仍引发了异常。异常被抛出在一个单独的线程上,该线程没有被错误捕获。

异常详细信息正在针对测试跟踪进行记录,因此我们能够确定需要修改哪些代码/测试。

希望这对某人有帮助。


0

就我而言,我有一些WCF服务的单元测试。该WCF服务正在启动2个计时器。
这些计时器引起副作用。
->我默认禁用这些计时器,一切正常!

顺便说一句:我使用WCFMock伪造WCF服务,因此我在WCF服务周围进行了“真实的”单元测试


0

这个错误也是由我的终结器引起的。
终结器实际上是在调用一些未被模拟的数据库代码。花了我一段时间才找到它,因为它不是我写的一门课,而且对它的引用也有很多课。


0

我遇到了类似的问题,其中TestInitialize中的测试失败,并且我的另一个项目中的ddl也在运行代码。我收到如上所述的错误消息,并且如果我尝试调试测试,则该测试只是中止而没有任何异常详细信息。

我怀疑问题可能是我其他项目中的dll来自Visual Studio 2012项目,而我正在VS2010项目中运行测试,和/或两个项目的UnitTestFramwork dll版本不匹配。


0

也可以由TestClass的构造方法中的异常或Stackoverflow触发此问题。


0

由于此错误可能有许多不同的原因,因此我想添加另一个原因以确保该线程的完整性。

如果您的所有测试都如OP所述中止,则原因可能是项目配置错误。在我的情况下,目标框架设置为.NET Framework 3.5。通过项目属性页(“ 应用程序”标签)将其设置为更高版本可以解决此问题。


0

通过查看Windows事件查看器中的Windows日志 > 应用程序日志条目,我能够确定是什么导致了我的问题。在测试炸毁时查找条目。我有一个类似于以下内容的错误条目:

QTAgent32_40.exe, PID 10432, Thread 2) AgentProcess:CurrentDomain_UnhandledException: IsTerminating : System.NullReferenceException: Object reference not set to an instance of an object.
   at XXX.YYY.ZZZ.cs:line 660
   at XXX.YYY.AAA.Finalize() in C:\JenkinsSlave\workspace\XXX.YYY.AAA.cs:line 180

实际上,这是从类终结器调用的方法中的空引用异常。


0

对于任何碰到这个老问题并且想知道从线程中抛出什么的人,这里有个提示。使用Task.Run(而不是Thread.Start)可以更可靠地报告子线程异常。简而言之,代替此:

Thread t = new Thread(FunctionThatThrows);
t.Start();
t.Join();

做这个:

Task t = Task.Run(() => FunctionThatThrows());
t.Wait();

而且您的错误日志应该更加有用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.