Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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
Java 使用JUnit在多线程环境中测试方法行为?_Java_Unit Testing_Tdd_Junit4 - Fatal编程技术网

Java 使用JUnit在多线程环境中测试方法行为?

Java 使用JUnit在多线程环境中测试方法行为?,java,unit-testing,tdd,junit4,Java,Unit Testing,Tdd,Junit4,对于给定的方法,我想编写测试用例,以查看当多个线程同时运行时它的行为。可能听起来很愚蠢,但只是想知道是否有可能创建这样的场景?也可以将单元测试代码视为一个线程。当我尝试在多线程环境中测试某些东西时,通常我会执行以下操作: 我手动和手动启动了工作线程—包含测试方法的线程和单元测试线程中的其他线程 让单元测试线程在给定的时间内休眠,或者等待其他线程,然后我检查结果。 问题是,单元测试线程可能不会向其他线程放弃执行,这就是为什么您必须以某种方式强制它。您无法直接控制如何将处理器时间分配给线程,因此必须

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

也可以将单元测试代码视为一个线程。当我尝试在多线程环境中测试某些东西时,通常我会执行以下操作:

我手动和手动启动了工作线程—包含测试方法的线程和单元测试线程中的其他线程 让单元测试线程在给定的时间内休眠,或者等待其他线程,然后我检查结果。
问题是,单元测试线程可能不会向其他线程放弃执行,这就是为什么您必须以某种方式强制它。您无法直接控制如何将处理器时间分配给线程,因此必须启动线程并让它们解决问题。

将单元测试代码也视为一个线程。当我尝试在多线程环境中测试某些东西时,通常我会执行以下操作:

我手动和手动启动了工作线程—包含测试方法的线程和单元测试线程中的其他线程 让单元测试线程在给定的时间内休眠,或者等待其他线程,然后我检查结果。
问题是,单元测试线程可能不会向其他线程放弃执行,这就是为什么您必须以某种方式强制它。您无法直接控制如何将处理器时间分配给线程,因此您必须启动线程并让它们解决问题。

您实际上可以在测试用例中启动线程,但我非常确定它不会执行您想要的操作。执行是不确定的

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

我做了一个快速检查,发现


也许这让您走上了正确的轨道。

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

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

我做了一个快速检查,发现


也许这让您走上了正确的道路。

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

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);
    }
}

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

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);
    }
}

这看起来非常相关,一定要尝试一下,让你知道这看起来非常相关,一定要尝试一下,让你知道也许不是你问题的真正答案,但要注意:当使用多线程时,你的代码将不是确定性的。您的测试可能会正常运行1000次,但在第1001次执行期间失败,没有任何代码更改。同意,这是一个重要因素,但如果我编写的所有测试都应该在多线程环境中运行,如何检查线程安全性?这对Memy来说非常关键,它可能不是对您的问题的真正答案,而是一个一般性的提示:当使用多线程时,您的代码将不是确定性的。您的测试可能会正常运行1000次,但在第1001次执行期间失败,没有任何代码更改。同意,这是一个重要因素,但如果我编写的所有测试都应该在多线程环境中运行,如何检查线程安全性?这对于meAren来说非常关键,难道没有第三方库可以抽象并发执行吗?我遇到过contiPerf,但它现在不活跃。如果您知道任何其他库可以从多个线程调用测试用例,并像contiPerf那样通过注释将其抽象出来,请告诉我。谢谢难道没有第三方库可以抽象并发执行吗?我遇到过contiPerf,但它现在不活跃。如果您知道任何其他库可以从多个线程调用测试用例,并像contiPerf那样通过注释将其抽象出来,请告诉我。谢谢