首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >并发JUnit测试

并发JUnit测试
EN

Stack Overflow用户
提问于 2011-02-11 23:35:13
回答 5查看 79.7K关注 0票数 75

我有一个很大的JUnit测试套件,我非常希望在其中并发运行所有测试,原因有两个:

  • 利用多核来运行整个测试套件faster
  • Hopefully检测由于非线程安全全局对象而导致的错误

我认识到这将迫使我重构一些代码,使其成为线程安全的,但我认为这是一件好事:-)

让JUnit同时运行所有测试的最佳方法是什么?

EN

回答 5

Stack Overflow用户

发布于 2012-04-24 21:11:27

TestNG提供了良好的开箱即用的多线程测试,并且它与JUnit测试兼容(您需要做一些更改)。例如,您可以像这样运行一个测试:

代码语言:javascript
复制
@Test(threadPoolSize = 3, invocationCount = 9,  timeOut = 10000)
public void doSomething() {
...
}

这意味着doSomething()方法将被3个不同的线程调用9次。

我强烈推荐TestNG

票数 29
EN

Stack Overflow用户

发布于 2013-01-01 11:57:56

我正在寻找这个问题的答案,根据这里的答案,以及我在其他地方读到的,目前似乎没有一种简单的开箱即用的方法来使用JUnit并行运行现有的测试。或者如果有我也没找到。所以我写了一个简单的JUnit运行器来实现这一点。请随时使用它;有关MultiThreadedRunner类的完整解释和源代码,请参阅http://falutin.net/2012/12/30/multithreaded-testing-with-junit/。有了这个类,您就可以像这样注释您现有的测试类:

代码语言:javascript
复制
@RunWith(MultiThreadedRunner.class)
票数 24
EN

Stack Overflow用户

发布于 2014-10-07 18:52:09

下面的代码应该可以满足您的需求,它取自德语书籍JUnit Profiwissen,其中包含一些关于并行测试的提示,或者关于如何通过使用多个内核而不是只使用一个内核来减少执行时间的提示。

JUnit 4.6引入了一个ParallelComputer类,它提供了测试的并行执行。然而,直到JUnit 4.7才能公开访问此功能,该功能提供了为父运行器设置自定义调度程序的可能性。

代码语言:javascript
复制
public class ParallelScheduler implements RunnerScheduler {

    private ExecutorService threadPool = Executors.newFixedThreadPool(
        Runtime.getRuntime().availableProcessors());

    @Override
    public void schedule(Runnable childStatement) {
        threadPool.submit(childStatement);
    }

    @Override
    public void finished() {
        try {
            threadPool.shutdown();
            threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new RuntimeException("Got interrupted", e);
        }
    }
}

public class ParallelRunner extends BlockJUnit4ClassRunner {

    public ParallelRunner(Class<?> klass) throws InitializationError {
        super(klass);
        setScheduler(new ParallelScheduler());
    }
}

如果现在使用@RunWith(ParallelRunner.class)注释测试类,则每个方法都将在其自己的线程中运行。此外,在执行机器上,将有与CPU核心一样多的活动线程(仅限)。

如果需要并行执行多个类,您可以定义一个自定义套件,如下所示:

代码语言:javascript
复制
public class ParallelSuite extends Suite {

    public ParallelSuite(Class<?> klass, RunnerBuilder builder) 
      throws InitializationError {
        super(klass, builder);
        setScheduler(new ParallelScheduler());
    }
}

然后用@RunWith(ParallelSuite.class)更改@RunWith(Suite.class)

您甚至可以利用f.e.的功能。通过直接从套件扩展WildcardPatternSuite,而不是像前面示例中那样扩展Suite。这使您能够进一步过滤单元测试f.e.任何@Category -一个只并行执行UnitTest注释类别的TestSuite可能如下所示:

代码语言:javascript
复制
public interface UnitTest {

}

@RunWith(ParallelSuite.class)
@SuiteClasses("**/*Test.class")
@IncludeCategories(UnitTest.class)
public class UnitTestSuite {

}

一个简单的测试用例现在可能如下所示:

代码语言:javascript
复制
@Category(UnitTest.class)
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {

    @Test
    public void testSomething() {
        ...
    }
}

UnitTestSuite将执行在以Test结尾的子目录中找到的每个类,并具有并行指定的@Category(UnitTest.class) -这取决于可用CPU核心的数量。

我不确定还能不能变得更简单:)

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4970907

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档