Expand

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

+4
source share
3 answers

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

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

This will cause the test method to be called 100 times from 10 different threads. If this test passes and you run a lot of it, you can be pretty sure that the code under test is multi-threaded.

+7
source

Why would you do this? Does public static void main(String []) really work across multiple threads? Seems like a weird design, so I'm sure.

If, on the other hand, you want to test parallel executions of your program (so that each in a separate JVM), this is not the same as multithreading, and JUnit will not do this, since it runs within the same JVM, you can still do this do, no problem, but make sure you know the difference.

A few examples on SO:

+1
source

Here is a small solution:

Here is the class you want to test:

 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 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 called by the bz JUnit framework. Rewrite the multiTest () method. mTTest package;

 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 a thread that can be called multiple times. Override the 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()); } } 
0
source

All Articles