JUnit 4テストマルチスレッド

3385 ワード

JUnit 4は実際にマルチスレッドプログラムのテストをサポートしていません.
The article at http://www.planetgeek.ch/2009/08/25/how-to-find-a-concurrency-bug-with-java/describes a method of exposing concurrency bugs that adds a new assertion method assertConcurrent .
この論文では,マルチスレッドプログラムをテストするための新しい断言法を提供した:assertConcurrent(final String message, final List extends Runnable> runnables, final int maxTimeoutSeconds)
  • final String message:テストが不合格の場合、印刷されたメッセージ
  • .
  • final List extends Runnable> runnables:テストが必要なスレッド
  • final int maxTimeoutSeconds:最長運転時間、単位秒、タイムアウトの場合、テストは
  • に合格しません.
    この方法は,テストが必要なスレッドを1つのスレッドプールに入れ,同時に実行し,最後に異常発生の有無,タイムアウト発生の有無を判断する.
    例は次のとおりです.次のコードはタイムアウトし、テストに合格しません.java.lang.AssertionError: Test Failed timeout! More than1seconds
    public class JUnit4_Test {
        @Test
        public void test1() throws Exception {
            List runnables = new ArrayList<>(10);
            for (int i = 0; i < 10; i++) {
                runnables.add(new MyRunnable());
            }
    
            assertConcurrent("Test Failed", runnables, 1);
        }
    
        public static void assertConcurrent(final String message, final List extends Runnable> runnables, final int maxTimeoutSeconds) throws InterruptedException {
            final int numThreads = runnables.size();
            final List exceptions = Collections.synchronizedList(new ArrayList());
            final ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
            try {
                final CountDownLatch allExecutorThreadsReady = new CountDownLatch(numThreads);
                final CountDownLatch afterInitBlocker = new CountDownLatch(1);
                final CountDownLatch allDone = new CountDownLatch(numThreads);
                for (final Runnable submittedTestRunnable : runnables) {
                    threadPool.submit(new Runnable() {
                        public void run() {
                            allExecutorThreadsReady.countDown();
                            try {
                                afterInitBlocker.await();
                                submittedTestRunnable.run();
                            } catch (final Throwable e) {
                                exceptions.add(e);
                            } finally {
                                allDone.countDown();
                            }
                        }
                    });
                }
                // wait until all threads are ready
                assertTrue("Timeout initializing threads! Perform long lasting initializations before passing runnables to assertConcurrent", allExecutorThreadsReady.await(runnables.size() * 10, TimeUnit.MILLISECONDS));
                // start all test runners
                afterInitBlocker.countDown();
                assertTrue(message + " timeout! More than" + maxTimeoutSeconds + "seconds", allDone.await(maxTimeoutSeconds, TimeUnit.SECONDS));
            } finally {
                threadPool.shutdownNow();
            }
            assertTrue(message + "failed with exception(s)" + exceptions, exceptions.isEmpty());
        }
    }
    
    class MyRunnable implements Runnable {
        public void run() {
            try {
                Thread.sleep(10000);
            } catch (Exception e) {
            } finally {
    
            }
        }
    }
    

    参照:Multithreaded code and concurrency