English 中文(简体)
在Visual Studio中逐个测试成功,但在一组中失败
原标题:
  • 时间:2008-12-30 13:58:20
  •  标签:

当我在Visual Studio中单独运行我的测试时,它们都能顺利通过。但是,当我一次性运行所有测试时,有些测试通过,有些测试失败。我尝试在每个测试方法之间插入1秒的暂停,但没有成功。

任何想法吗?感谢你的帮助。

最佳回答

你可能有一些共享数据。检查正在使用的类中的静态成员变量,这意味着一个测试设置了一个值,导致后续的测试失败。

您还可以调试单元测试。根据您使用的框架,您应该能够运行框架工具作为调试启动应用程序,将编译的程序集路径作为参数传递。

问题回答

很可能在一个测试中进行的一些修改/实例化会影响其他测试。这表明测试设计不良并缺乏适当的隔离。

每个人可能都是正确的,一些共享日期在测试之间被修改。但请注意 MS测试执行顺序。简单地在测试之间暂停并不是解决方案。每个测试在一个单独的线程上以它自己的测试类实例执行。

根据其他回复,看起来你有一个单例或全局变量导致了这种交互。

我使用过的其他单元测试框架都会努力确保测试无论是单独运行还是作为“运行所有”子选项的一部分,都可以产生相同的结果。其目标是防止一个测试由于副作用(例如,一个测试使类的静态状态处于未经另一个测试预期的配置状态)而对另一个测试产生影响。VS 单元测试框架似乎没有提供这种隔离。我有两个建议来最小化这些问题。首先,如果一个类具有状态(有任何非静态方法),则优先使用非静态类。创建一个单例的这个类并将其保持状态信息,这些信息原本是在静态类中保留的。其次,如果您决定使用具有静态状态的静态类,请编写一个将静态状态设置回“空”(例如,设置所有静态属性为 null/zero/等等)的静态方法。在每个单元测试的结束时调用它以撤销测试对静态状态的任何影响。(这显然不够优雅,但如果适度使用,它可以是可行的。)或者做我计划要做的——找一个提供跨测试隔离的单元测试框架。

尽管我的问题最终成为了线程问题,但我也遇到了这个问题。在我的情况下,我正在模拟HttpContext对象,因为测试依赖于它的存在。然而,我在ClassInitialize方法中设置了这个,认为它将像下面那样用于每个方法:

[ClassInitialize]
public static void ClassInit(TestContext testContext)
{
    HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
}

然而,事实证明类中的每个测试方法都在单独的线程中运行。因此,我不得不将以下代码添加到每个依赖它的测试方法中以解决问题。

[TestMethod]
public void TestMethod1()
{
    HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
    ...
}

[TestMethod]
public void TestMethod2()
{
    HttpContext.Current = new HttpContext(new HttpRequest(null, "http://tempuri.org", null), new HttpResponse(null));
    ...
}

See link for more information on this. http://blogs.msdn.com/b/nnaderi/archive/2007/02/17/explaining-execution-order.aspx

我在这里面临类似的问题,这是我解决它的方法:

  1. Copy the code of the second test inside the first test (after it).
  2. Try to test the first test. The first test will probably fails, and then you can debug the first test (step by step) to find the static/shared variable or logic that makes the problem.

In my case, I had an Environment variable set with:
Environment.SetEnvironmentVariable("KEY", "value");

The implementation code for a few other tests was assuming a default value, and if the test(s) with the above line were executed first, those failed. The solution is to clean up with the following (at the end of each unit test, or in a special method for the same purpose - TestCleanup in MS/VSTest): Environment.SetEnvironmentVariable("KEY", null);
Though redundant, it is best practice to also set the environment variable to any value previously assumed by (the failing) tests to be default. Do this at the top of those unit tests (the Arrange step).





相关问题
热门标签