【问题标题】:How does the Visual Studio 2012 test runner apply threading?Visual Studio 2012 测试运行程序如何应用线程?
【发布时间】:2013-02-13 18:41:28
【问题描述】:

每个包含测试的类是否在它自己的线程中运行?还是每个单独的测试都在它自己的线程中运行?如果每个包含测试的类都有自己的线程,这些是同时运行的吗?即,A 类的测试会与 B 类的测试同时运行吗?或者 A 类的测试会运行(每个在自己的线程上),然后是 B 类的测试(每个在自己的线程上)?

【问题讨论】:

标签: mstest visual-studio-test-runner


【解决方案1】:

每个包含测试的类是否在其自己的线程中运行?

没有。所有测试都在同一个线程上运行

或者每个单独的测试是否在它自己的线程中运行?

没有。所有测试都在同一个线程上运行。

如果每个包含测试的类都有自己的线程,这些是否运行 同时?即,A 类的测试会与测试同时运行吗 来自B级?或者 A 类的测试是否会运行(每个都在自己的线程上), 然后是 B 类的测试(每个都在自己的线程上)?

如果您正在创建线程。您拥有他们的并发模型。 vstest 执行器不会同时运行您的。无法保证测试的执行顺序,无论是在给定的测试类内还是不同测试类之间的顺序。

【讨论】:

    【解决方案2】:

    看来它根本不应用线程!我构建了一个包含 3 个单元测试的测试项目,只是使用 Nlog 将信息输出到文件。

    我发现有趣的是,TestClass 为每个测试构建一次。我以为每个类只会构建一次。

    此外,类清理会在所有测试结束时运行。我认为每个班级的清理工作都会在该班级的最后一次测试完成后运行。

    最后,它们都在同一个线程上运行!现在这是出乎意料的。在当今的多核世界中(我的装备有 4 个),我本来希望在图片中看到更多线程。

    每个测试如下所示:

    using System;
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using NLog;
    using System.Threading;
    
    namespace SeeHowTestsUseThreads
    {
        [TestClass]
        public class UnitTest1
        {
            static Logger logger = LogManager.GetCurrentClassLogger();
    
            public UnitTest1()
            {
                logger.Info("Thread {0}: Constructing UnitTest1", Thread.CurrentThread.ManagedThreadId);
            }
    
            [ClassInitialize()]
            public static void MyClassInitialize(TestContext testContext) {
                logger.Info("Thread {0}: UnitTest1 Class Initialize", Thread.CurrentThread.ManagedThreadId);
            }
            [ClassCleanup()]
            public static void MyClassCleanup() {
                logger.Info("Thread {0}: UnitTest1 Class Cleanup", Thread.CurrentThread.ManagedThreadId);
            }
            [TestInitialize()]
            public void MyTestInitialize() {
                logger.Info("Thread {0}: UnitTest1 Test Initialize", Thread.CurrentThread.ManagedThreadId);
            }
    
            [TestCleanup()]
            public void MyTestCleanup() {
                logger.Info("Thread {0}: UnitTest1 Test Cleanup", Thread.CurrentThread.ManagedThreadId);
            }
    
            [TestMethod]
            public void TestMethod1()
            {
                logger.Info("Thread {0}: UnitTest1 TestMethod1 Run", Thread.CurrentThread.ManagedThreadId);
                Assert.Inconclusive();
            }
    
            [TestMethod]
            public void TestMethod2()
            {
                logger.Info("Thread {0}: UnitTest1 TestMethod2 Run", Thread.CurrentThread.ManagedThreadId);
                Assert.Inconclusive();
            }
            [TestMethod]
            public void TestMethod3()
            {
                logger.Info("Thread {0}: UnitTest1 TestMethod3 Run", Thread.CurrentThread.ManagedThreadId);
                Assert.Inconclusive();
            }
            [TestMethod]
            public void TestMethod4()
            {
                logger.Info("Thread {0}: UnitTest1 TestMethod4 Run", Thread.CurrentThread.ManagedThreadId);
                Assert.Inconclusive();
            }
            [TestMethod]
            public void TestMethod5()
            {
                logger.Info("Thread {0}: UnitTest1 TestMethod5 Run", Thread.CurrentThread.ManagedThreadId);
                Assert.Inconclusive();
            }
            [TestMethod]
            public void TestMethod6()
            {
                logger.Info("Thread {0}: UnitTest1 TestMethod6 Run", Thread.CurrentThread.ManagedThreadId);
                Assert.Inconclusive();
            }
        }
    }
    

    这是输出...

    2013-02-14 07:59:42.3879 INFO Thread 10: Constructing UnitTest3
    2013-02-14 07:59:42.3979 INFO Thread 10: UnitTest3 Class Initialize
    2013-02-14 07:59:42.3979 INFO Thread 10: UnitTest3 Test Initialize
    2013-02-14 07:59:42.3979 INFO Thread 10: UnitTest3 TestMethod1 Run
    2013-02-14 07:59:42.3979 INFO Thread 10: UnitTest3 Test Cleanup
    2013-02-14 07:59:42.4220 INFO Thread 10: Constructing UnitTest3
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 Test Initialize
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 TestMethod2 Run
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 Test Cleanup
    2013-02-14 07:59:42.4220 INFO Thread 10: Constructing UnitTest3
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 Test Initialize
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 TestMethod3 Run
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 Test Cleanup
    2013-02-14 07:59:42.4220 INFO Thread 10: Constructing UnitTest3
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 Test Initialize
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 TestMethod4 Run
    2013-02-14 07:59:42.4220 INFO Thread 10: UnitTest3 Test Cleanup
    2013-02-14 07:59:42.4220 INFO Thread 10: Constructing UnitTest3
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest3 Test Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest3 TestMethod5 Run
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest3 Test Cleanup
    2013-02-14 07:59:42.4290 INFO Thread 10: Constructing UnitTest3
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest3 Test Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest3 TestMethod6 Run
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest3 Test Cleanup
    2013-02-14 07:59:42.4290 INFO Thread 10: Constructing UnitTest1
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Class Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 TestMethod1 Run
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Cleanup
    2013-02-14 07:59:42.4290 INFO Thread 10: Constructing UnitTest1
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 TestMethod2 Run
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Cleanup
    2013-02-14 07:59:42.4290 INFO Thread 10: Constructing UnitTest1
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 TestMethod3 Run
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Cleanup
    2013-02-14 07:59:42.4290 INFO Thread 10: Constructing UnitTest1
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 TestMethod4 Run
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Cleanup
    2013-02-14 07:59:42.4290 INFO Thread 10: Constructing UnitTest1
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Initialize
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 TestMethod5 Run
    2013-02-14 07:59:42.4290 INFO Thread 10: UnitTest1 Test Cleanup
    2013-02-14 07:59:42.4440 INFO Thread 10: Constructing UnitTest1
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest1 Test Initialize
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest1 TestMethod6 Run
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest1 Test Cleanup
    2013-02-14 07:59:42.4440 INFO Thread 10: Constructing UnitTest2
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Class Initialize
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Initialize
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 TestMethod1 Run
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Cleanup
    2013-02-14 07:59:42.4440 INFO Thread 10: Constructing UnitTest2
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Initialize
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 TestMethod2 Run
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Cleanup
    2013-02-14 07:59:42.4440 INFO Thread 10: Constructing UnitTest2
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Initialize
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 TestMethod3 Run
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Cleanup
    2013-02-14 07:59:42.4440 INFO Thread 10: Constructing UnitTest2
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Initialize
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 TestMethod4 Run
    2013-02-14 07:59:42.4440 INFO Thread 10: UnitTest2 Test Cleanup
    2013-02-14 07:59:42.4600 INFO Thread 10: Constructing UnitTest2
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest2 Test Initialize
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest2 TestMethod5 Run
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest2 Test Cleanup
    2013-02-14 07:59:42.4600 INFO Thread 10: Constructing UnitTest2
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest2 Test Initialize
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest2 TestMethod6 Run
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest2 Test Cleanup
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest3 Class Cleanup
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest1 Class Cleanup
    2013-02-14 07:59:42.4600 INFO Thread 10: UnitTest2 Class Cleanup
    

    【讨论】:

    • 当时我并没有意识到这一点。不过我现在肯定会在我所有的日志记录中使用它。
    【解决方案3】:

    另外请注意,如果您的单元测试是线程安全的,您可以选择应用线程并让测试并行执行。看到这个blog post from Microsoft

    【讨论】:

    • 不,你没有。至少不是 OP 询问的“Visual Studio 2012 Test Runner”(即幕后“vstest”或“vstest.console.exe”)。那不支持线程。 MSTest 做了,它是 VS2010 中的“测试运行器”,你提供的链接是关于它的。另见this connect issue
    猜你喜欢
    • 1970-01-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    • 2014-02-12
    • 1970-01-01
    • 2013-06-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多