【问题标题】:Test a method behavior in multi threading environment using JUnit?使用 JUnit 在多线程环境中测试方法行为?
【发布时间】:2013-09-02 21:20:08
【问题描述】:

对于给定的方法,我想编写测试用例来查看当多个线程同时运行时它的行为。可能听起来很愚蠢,但只是想知道是否有可能创建任何这样的场景?

【问题讨论】:

  • 也许不是您问题的真正答案,但一般注意:使用多个线程时,您的代码将不是确定性的。您的测试可能运行良好 1000 次,但在第 1001 次执行期间失败而没有任何代码更改。
  • 同意,这是一个很大的因素,但是如果我所写的一切都应该在多线程环境中运行,如何检查线程安全?这对我来说非常重要

标签: java unit-testing tdd junit4


【解决方案1】:

这就是我最近在一些代码中的实现方式:

import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static org.junit.Assert.*;
public class UtilTest
{
    private final static int TEST_THREAD_COUNT = 10;
    private volatile int threadsRun = 0;
    private volatile List<String> nonUniqueIds = new ArrayList<>();

    @Test
    public void testUniqueIdGeneration()
    {
        final ExecutorService pool = Executors.newFixedThreadPool(TEST_THREAD_COUNT);
        Runnable r = new Runnable()
        {
            @Override
            public void run()
            {
                List<String> doneIds = new ArrayList<>();
                for (int i = 1; i <= 100; i++)
                {
                    String id = Util.generateId();
                    if (doneIds.contains(id))
                    {
                        nonUniqueIds.add(id);
                        break;
                    }
                    doneIds.add(id);
                }
                threadsRun++;
                if (threadsRun >= TEST_THREAD_COUNT)
                    pool.shutdown();
            }
        };

        for (int i = 0; i < TEST_THREAD_COUNT; i++)
        {
            pool.submit(r);
        }
        while (! pool.isShutdown())
        {
            //stay alive
        }

        if (nonUniqueIds.isEmpty() )
            return;

        for (String id: nonUniqueIds)
        {
            System.out.println("Non unique id: " + id);
        }
        assertTrue("Non unique ids found", false);
    }
}

【讨论】:

  • 没有第三方库可以抽象并发执行吗?我遇到了 contiPerf,但它现在不活跃。如果您知道任何其他可以从多个线程调用测试用例并像 contiPerf 那样通过注释抽象出来的库,请告诉我。谢谢!
【解决方案2】:

你实际上可以在测试用例中启动你的线程,但我很确定它不会做你想要的。执行是不确定的。

似乎有一些并发测试框架可能会有所帮助。他们使用特殊技术来控制线程的行为,从而导致竞争条件和其他不良情况。

我快速检查了一下,发现MultithreadedTC

也许这会让你走上正轨。

【讨论】:

  • 这看起来很相关,一定要试一试,让你知道
【解决方案3】:

也将您的单元测试代码视为一个线程。当我尝试在多线程环境中测试某些东西时,一般来说我做了以下事情:

  • 我在单元测试线程中手动启动了工作线程(包含测试方法和其他线程的线程),并且
  • 让单元测试线程休眠给定的时间,或者等待其他线程,然后我检查我的结果。

问题是,the unit test thread may not give up execution to the others 这就是为什么你必须以某种方式强制它。您无法“直接”控制如何将处理器时间分配给线程,因此您必须启动它们并让它们“解决”问题。

【讨论】:

    猜你喜欢
    • 2013-03-08
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多