Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有一种方法可以计算忽略初始化时间的测试方法的运行时间?_C#_Unit Testing_Visual Studio 2013 - Fatal编程技术网

C# 是否有一种方法可以计算忽略初始化时间的测试方法的运行时间?

C# 是否有一种方法可以计算忽略初始化时间的测试方法的运行时间?,c#,unit-testing,visual-studio-2013,C#,Unit Testing,Visual Studio 2013,这是一个介于StackOverflow和SuperUser之间的灰色地带。由于我怀疑答案可能涉及到与代码相关的解决方案,例如创造性地使用秒表,我将在这里提问 我正在使用Visual Studio 2013对依赖实体框架数据模型的控制器执行单元测试。测试资源管理器在一个简短的列表中很好地显示了我的测试结果及其经过的时间 不过,我发现我的控制器单元测试所花的时间比我预期的要长得多。我开始怀疑这是由于我用来创建模拟(使用Moq,但这并不重要)实体模型的初始化代码造成的 果不其然,显示初始化例程包含在经

这是一个介于StackOverflow和SuperUser之间的灰色地带。由于我怀疑答案可能涉及到与代码相关的解决方案,例如创造性地使用
秒表
,我将在这里提问

我正在使用Visual Studio 2013对依赖实体框架数据模型的控制器执行单元测试。测试资源管理器在一个简短的列表中很好地显示了我的测试结果及其经过的时间

不过,我发现我的控制器单元测试所花的时间比我预期的要长得多。我开始怀疑这是由于我用来创建模拟(使用Moq,但这并不重要)实体模型的初始化代码造成的

果不其然,显示初始化例程包含在经过的时间中是一件小事

[TestClass]
public class InitializeTest
{
    [TestInitialize]
    public void Initialize()
    {
        Thread.Sleep(10000);
    }

    [TestMethod]
    public void TestInitializeRuntime()
    {
        Assert.Inconclusive();
    }
}
这在测试资源管理器中产生了以下输出:

这使得由我的模拟实体模型支持的测试的运行时间变得非常无用,因为初始化代码通常消耗测试运行时间的95%以上。每种方法看起来都很慢,但事实并非如此


是否有替代配置或代码的创造性使用(如前面提到的秒表),允许我仅报告测试方法的运行时间,不包括初始化或清理测试所花费的时间?

您遇到的问题是单元测试不允许更改时间或数据输出-它们只是执行并完成


一种方法是违反单元测试标准,使用静态引用和静态构造函数来准备支持数据——虽然在技术上没有保证,但VS 2013确实在同一AppDomain中执行所有单元测试(尽管通过给定的
TestClass的单独实例执行)你的测试应该以回答问题为目标。问题如下:
1.我的代码是否按预期运行?
2.我的代码是否按预期执行

但是,与其依赖测试框架的内部工作来处理代码(它特别不适合的任务),不如考虑编写测试特定代码和/或例程的性能的测试。p> 例如,您可以编写一个测试方法,启动秒表,执行一些工作,停止秒表,并测量操作所用的时间。然后,您应该能够断言测试没有超过预期的最大持续时间,如果超过了,您会将其视为失败的测试

通过这种方式,您不是在测量测试基础结构的不可预测性能,而是在测试代码的性能


此外,正如Aravol所建议的,您可以通过在一个测试中填充Moq来预先加载测试设置的成本,因为静态构造函数是在执行任何新的
或实例方法之前执行的。

我今天发现了一种在MSTest中处理昂贵初始化的方法,而不会导致测试报告速度变慢。我发布这个答案以供考虑,但没有接受它,因为它确实有一种温和的代码味道

MSTest每次运行测试时都会创建测试类的新实例。由于这种行为,在实例构造函数中编写的代码在每个测试中发生一次。这与
[TestInitialize]
方法的行为类似,但有一个例外:MSTest在创建测试类实例之后和执行
[TestInitialize]
例程之前开始计时单元测试

作为这种MSTest特定行为的结果,可以将应该从自动生成的计时统计信息中省略的初始化代码放入构造函数中

演示我的意思,考虑下面的测试和生成的输出。

测试:

public class ConstructorTest
{
    public ConstructorTest()
    {
        System.Threading.Thread.Sleep(10000);
    }

    [TestMethod]
    public void Index()
    {
    }

    [TestMethod]
    public void About()
    {
    }
}
输出:

public class ConstructorTest
{
    public ConstructorTest()
    {
        System.Threading.Thread.Sleep(10000);
    }

    [TestMethod]
    public void Index()
    {
    }

    [TestMethod]
    public void About()
    {
    }
}

我的想法:

public class ConstructorTest
{
    public ConstructorTest()
    {
        System.Threading.Thread.Sleep(10000);
    }

    [TestMethod]
    public void Index()
    {
    }

    [TestMethod]
    public void About()
    {
    }
}
上面的代码肯定会产生我想要的效果;然而,尽管使用构造函数或
[TestInitialize]
方法来处理初始化是非常困难的,但我必须假设后者存在于这个框架中是有充分理由的

可能有这样一种情况,即在计算中包含初始化时间的报告可能很有用,例如在估计一组大型测试应该消耗多少实时时间时

里奇·特纳(Rich Turner)关于时间敏感型操作如何值得使用带有断言的秒表的讨论也值得承认(我也投了赞成票)。另一方面,我将VisualStudio提供的自动生成的计时报告视为一个有用的工具,用于识别失控的测试,而无需在每个测试中编写计时样板代码

总之,我很高兴找到了一个解决方案,并对这里讨论的备选方案表示赞赏


干杯

我不认为在很多情况下实际上需要长时间的测试初始化。想知道海报的例子中包括了什么样的操作是很有意思的

将TestInit的函数分离为ClassInit需要一些创造性(早些时候有人建议使用构造函数……类似的事情,但该代码块中的错误将以完全不同的方式报告)。例如,如果每个测试都需要从文件中读取的字符串列表,则可以按以下方式拆分:

1) ClassInit-读取文件,将字符串捕获到数组中(较慢的部分) 2) TestInit—将数组的元素复制到每个测试都可以访问的列表中(快速部分)

我反对使用静态来解决测试性能问题,因为它会破坏每个测试之间的隔离

我也反对使用秒表之类的东西来判断自己的性能。。。运行测试会生成一个报告,因此该报告的观察者应该识别