4

I have a test case that provides arguments and executes the main method of a class. What would be the best approach using Junit to have multiple threads concurrenlty execute the main method of class.

3 Answers 3

12

Not sure if TestNG is an option for you, but it's pretty straightforward with it:

@Test(invocationCount = 100, threadPoolSize = 10) public void myTest() { ... } 

This will cause the test method to be invoked 100 times from 10 different threads. If this test passes and you run it a lot, you can be fairly confident that the code under test is multithread safe.

Sign up to request clarification or add additional context in comments.

Comments

0

Why would you do that? Is your public static void main(String []) really run by multiple threads? Seems a strange design, that's why I'm making sure.

If, on the other hand, you want to test parallel executions of your program (so each in a separate JVM), it's not the same as multithreaded, and JUnit won't do that, as it executes within the same JVM. You still can do that, no problem, but make sure you know the difference.

Some examples on SO:

Comments

0

Here is a lightweight solution:

Here is the Class you want to testing:

package mTTest; /** * UUT class is the Unit Under Test. This will be tested. * It has two simple method: * push(): sets the message string if it's null, and waits otherwise. * pop(): if there is any message sets it null and returns it. * */ public class UUT { String message = null; synchronized void push(String msg){ while (null != message) { try { wait(); } catch (InterruptedException e) { } } message = msg; notifyAll(); } synchronized String pop(){ while (null == message) { try { wait(); } catch (InterruptedException e) { } } String ret = message; message = null; notifyAll(); return ret; } } 

Here is the Test class. This will be invoked bz the JUnit framework. Rewrite multiTest() method. package mTTest;

import static org.junit.Assert.assertEquals; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.ListIterator; import org.junit.Test; /** * This is the JUnit test class. Method in this class will invoked by the JUnit * framework. */ public class DUTTest { /** * Stores sub test threads errors. */ private static List<AssertionError> errors; /** * sub test threads call this function with they errors. * @param err */ static void handle(AssertionError err){ errors.add(err); } /** * Simpler single thread test * @throws InterruptedException */ @Test public void testSingle() { UUT dut = new UUT(); dut.push("hello"); assertEquals("set-get", "hello", dut.message); } /** * Complex multi-thread test * @throws InterruptedException */ @Test public void testMulti() throws Exception { /* * Initialization */ errors = Collections.synchronizedList(new ArrayList<AssertionError>()); UUT dut = new UUT(); MyTestThread th = new MyTestThread(dut); /* * Tests */ dut.push("hello"); assertEquals("set-get", "hello", dut.message); th.start(); dut.push("hello"); th.join(); /* * Error handling */ ListIterator<AssertionError> iter = errors.listIterator(errors.size()); while (iter.hasPrevious()) { AssertionError err = iter.previous(); err.printStackTrace(); if(iter.previousIndex() == -1){ throw err; } } } } 

Here is the Thread, which can be invoked several time. Override test() method.

package mTTest; import static org.junit.Assert.assertEquals; /** * This is the custom test thread class. The main test thread (which is started * by JUnit) starts this thread. * */ public class MyTestThread extends Thread { UUT dut; /** * Constructor * @param dut : should be overwritten to your custom DUT-class */ public MyTestThread(UUT dut) { this.dut =dut; } /** * run() method is final to prevent overriding. Override test instead. * It just calls the test method and handle the assertion errors. */ @Override public final void run() { try{ test(); } catch (AssertionError ex){ DUTTest.handle(ex); } } /** * Write your tests here. run calls this function. */ void test(){ assertEquals("set-get", "This will cause an ERROR", dut.pop()); assertEquals("set-get", "hello", dut.pop()); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.