There are many similar questions to my questions,but there is no clear answer for it!
My tests are failing because they are running once inside suite and once alone. And I need them to run only once inside suite.
This is my suite:
#RunWith(Suite.class)
#Suite.SuiteClasses({Test1.class, Test2.class})
{
.....
}
I am running the test from the command line with command test.
Has anyone found a solution for this?
I use the following setup to run tests with JUnit, parallel, and they run only once:
#RunWith(ParallelSuite.class)
#SuiteClasses({ Test1.class, Test2.class })
public class AllTests {
}
And I have a ParallelSuite.class:
package tests;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import org.junit.internal.runners.*;
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerBuilder;
import org.junit.runners.model.RunnerScheduler;
public class ParallelSuite extends Suite {
public ParallelSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
super(klass, builder);
setScheduler(new RunnerScheduler() {
private final ExecutorService service = Executors.newFixedThreadPool(4);
public void schedule(Runnable childStatement) {
service.submit(childStatement);
}
public void finished() {
try {
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace(System.err);
}
}
});
}
}
Related
I just created a test class from File->New->JUnit Test Cases and this is my whole code:
import static org.junit.jupiter.api.Assertions.*;
import org.junit.After;
import org.junit.Before;
import org.junit.jupiter.api.Test;
class TestingJUnit {
#Before
public void testOpenBrowser() {
System.out.println("Opening Chrome browser");
}
#Test
public void tesingNavigation() {
System.out.println("Opening website");
}
#Test
public void testLoginDetails() {
System.out.println("Enter Login details");
}
#After
public void testClosingBrowser() {
System.out.println("Closing Google Chrome browser");
}
}
But when I run this cas only #Test annotations are running #Before and #After annotations code are not running. Please guide me I think this is JUnit version or eclipse IDE version problem, and also my all Test classes not running in TestSuit I don't know why although Test Classes are running fine individually.
My TestSuit Class is here:
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
#RunWith(Suite.class)
#SuiteClasses({TestingJUnit.class, SecondTest.class})
public class TestSuit {
}
Try using #BeforeEach instead of #Before and #AfterEach instead of #After
Try Using This
#BeforeEach
public void before() {
System.out.println("Before");
}
#AfterEach
public void after() {
System.out.println("After");
}
#Test
public void sum_with3numbers() {
System.out.println("Test 1");
}
#Test
public void sum_with1numbers() {
System.out.println("Test 2");
}
Output will be:
Before
Test 1
After
Before
Test 2
After
the main class:
package com.xxx.yyy;
public class Hello{
public static void main(String[] args){
A a = new A();
while(true){
try {
a.execute(1000);
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
}
}
}
class A:
package com.xxx.yyy;
public class A{
public void execute(int sleepTime) throws Exception {
System.out.println("sleep time is "+sleepTime);
}
}
btrace script:
import static com.sun.btrace.BTraceUtils.println;
import static com.sun.btrace.BTraceUtils.str;
import static com.sun.btrace.BTraceUtils.strcat;
import static com.sun.btrace.BTraceUtils.timeMillis;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
import com.sun.btrace.annotations.TLS;
#BTrace
public class BtraceTest{
#OnMethod(clazz="com.xxx.yyy.A",method="execute",location=#Location(Kind.RETURN))
public static void traceExecute(#ProbeClassName String name,#ProbeMethodName String method,int sleepTime){
println(strcat("the class name=>", name));
println(strcat("the class method=>", method));
println(strcat("the class method params=>", str(sleepTime)));
}
}
everything is right.
BUT: when I move the line Thread.sleep(1000) to class A's execute function, like this:
package com.xxx.yyy;
public class A{
public void execute(int sleepTime) throws Exception {
System.out.println("sleep time is "+sleepTime);
Thread.sleep(1000);
}
}
the NoSuchMethodError is thrown by Hello.
Exception in thread "main" java.lang.NoSuchMethodError: com.xxx.yyy.A.$btrace$BtraceTest$traceExecute(Ljava/lang/String;Ljava/lang/String;I)V
at com.xxx.yyy.A.execute(Unknown Source)
at com.xxx.yyy.Hello.main(Hello.java:8)
my environment is
java version "1.8.0_121"
BTrace v.1.3.9 (20170111)
anyone can explain why?thanks!
I think your class should implements Runnable or extends Thread. Then only you can use start, sleepand such similar methods in your program. Have a look at here to know how to implement thread methods.
I have a problem with Idea 14 and JUnit. I can't run #BeforeClass and #AfterClass methods in proper order (before all test and after all test). Every time order is different. I tried to reinstall IDEA, delete all settings but nothing works. Please help. This is example of my test code:
package com.rent.test;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import static org.junit.Assert.*;
import org.junit.Test;
public class testnewTest {
static int num;
static int num1;
#BeforeClass
public static void OnceExecutedBeforeAll() {
System.out.println("#BeforeClass: onceExecutedBeforeAll");
num = 15;
num1 = 16;
}
#AfterClass
public static void after() throws Exception {
System.out.println("End");
}
#Test
public void testLogin() throws Exception {
System.out.println("test");
assertEquals(15, num);
}
#Test
public void testGetOrdersDate() throws Exception {
System.out.println("test2");
assertEquals(16, num1);
}
}
This is output:
test2
#BeforeClass: onceExecutedBeforeAll
test
End
What you're likely observing is the fact that the output is not always going to be synchronous in the terminal. The test themselves are running in the correct sequence.
If they weren't, then you would have failures in test2 given that it would have appeared that your #BeforeClass method fired afterwards.
Below is a unit test which uses ScheduledExecutorService to execute a scheduled runnable every second :
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.junit.Test;
public class ConcurrentRequestSimulator {
private static final int NUMBER_REQUESTS = 4;
#Test
public void testGetToDoList() {
try {
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10);
scheduler.scheduleAtFixedRate(new RequestThreadInvoker(), 0, 1, TimeUnit.SECONDS);
} catch (Exception e) {
e.printStackTrace();
}
}
private final class RequestThreadInvoker implements Runnable {
public void run() {
ExecutorService es = Executors.newCachedThreadPool();
for (int i = 1; i <= NUMBER_REQUESTS; i++) {
es.execute(new RequestThread());
}
es.shutdown();
while (!es.isTerminated()) {
}
}
}
private final class RequestThread implements Runnable {
public void run() {
try {
System.out.println("in RequestThread");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The line System.out.println("in RequestThread"); in RequestThread does not appear to be invoked as no output is displayed to console.
I think the issue is that since the test runs to completion, it causes the scheduler to stop scheduling? Can the test be updated so that scheduler is not terminated and RequestThreadInvoker is invoked repeatedly once per second ?
In RequestThreadInvoker I create a new instance of ExecutorService. Could this be causing the issue ?
Adding Thread.sleep(99000); to end of test causes test to wait 99 seconds which is enough time for test to run.
I am trying to learn the JUnit and wanted to extend it to test in a multi-threaded way.
The class I want to test is PrimeNumberValidator. This just tests if a passed in number is prime or not.
package com;
public class PrimeNumberValidator {
public Boolean validate(final Integer primeNumber) {
System.out.println("Validating .............:" + primeNumber);
for (int i = 2; i < (primeNumber / 2); i++) {
if (primeNumber % i == 0) {
return false;
}
}
return true;
}
}
The PrimeNumberValidatorTest is the test class. The 2 of the test data are wrong and I have done this purposely to test for failure.
The test method testPrimeNumberValidator runs perfectly fine. But, the multi-threaded version testMultiThreadedPrimeNumberValidator always says 'pass' for even wrong data.
Why is this happening like this? How do solve this ?
package com;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
#RunWith(Parameterized.class)
public class PrimeNumberValidatorTest {
private Integer primeNumber;
private Boolean expectedValidation;
private PrimeNumberValidator primeNumberValidator;
#Before
public void initialize() {
primeNumberValidator = new PrimeNumberValidator();
}
// Each parameter should be placed as an argument here
// Every time runner triggers, it will pass the arguments from parameters we defined
public PrimeNumberValidatorTest(Integer primeNumber, Boolean expectedValidation) {
this.primeNumber = primeNumber;
this.expectedValidation = expectedValidation;
}
#Parameterized.Parameters
public static Collection primeNumbers() {
return Arrays.asList(new Object[][] {
{ 2, Boolean.FALSE},// 2 is prime so Test should fail
{ 6, Boolean.FALSE}, //is NOT prime so test should pass
{ 19, Boolean.TRUE},//is prime so test should pass
{ 22, Boolean.TRUE} //is NOT prime so test should fail
});
}
// This test will run 4 times since we have 4 parameters defined
#Test
public void testPrimeNumberValidator() {
assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
}
#Test
public void testMultiThreadedPrimeNumberValidator() {
ExecutorService executor = Executors.newFixedThreadPool(100);
executor.submit(new Runnable() {
public void run() {
for (int i = 0; i < 100; i++) {
assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
}
}
});
}
}
Referring to http://www.youtube.com/watch?v=wDN_EYUvUq0 as mentioned in one of the posts Weird problem using JUnit in multi-thread environment, tried as below. The exceptions are thrown, but the JUnit does not report failure :(
package com;
import static org.junit.Assert.assertEquals;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
#RunWith(Parameterized.class)
public class PrimeNumberValidatorTest {
volatile Exception exception;
volatile Error error;
private Integer primeNumber;
private Boolean expectedValidation;
private PrimeNumberValidator primeNumberValidator;
#Before
public void initialize() {
primeNumberValidator = new PrimeNumberValidator();
}
// Each parameter should be placed as an argument here
// Every time runner triggers, it will pass the arguments from parameters we defined
public PrimeNumberValidatorTest(Integer primeNumber, Boolean expectedValidation) {
this.primeNumber = primeNumber;
this.expectedValidation = expectedValidation;
}
#Parameterized.Parameters
public static Collection primeNumbers() {
return Arrays.asList(new Object[][] {
{ 2, Boolean.FALSE},// 2 is prime so Test should fail
{ 6, Boolean.FALSE}, //is NOT prime so test should pass
{ 19, Boolean.TRUE},//is prime so test should pass
{ 22, Boolean.TRUE} //is NOT prime so test should fail
});
}
// This test will run 4 times since we have 4 parameters defined
#Test
#Ignore
public void testPrimeNumberValidator() {
assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
}
#Test
public void testMultiThreadedPrimeNumberValidator() {
ExecutorService executor = Executors.newFixedThreadPool(100);
executor.submit(new Runnable() {
public void run() {
for (int i = 0; i < 1; i++) {
try{
assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
}catch(Error e){
System.out.println("error thrown :" + e);
error =e;
}catch(Exception e){
exception=e;
System.out.println("exception thrown :" + e);
}
}
}
});
}
#After
public void runAfterEveryTest() throws Exception{
if(null != error){
System.out.println("runAfterEveryTest throwing error...............");
throw error;
}
if(null != exception){
System.out.println("runAfterEveryTest throwing exception...............");
throw exception;
}
}
}
The reason the multi-threaded is always passing is the following:
first, the test method does nothing to wait for the multiple threads to complete therefore the #Test method is exiting before any errors are reported
second, the way that testing works is that the assert method throws an exception. The JUnit framework catches this exception by wrapping the #Test method and fails the test if an unexpected exception is thrown. However, in the multi-threaded test no exception is thrown from the #Test method because they are thrown within the threads and the test method does nothing to check this. One solution for this part would be to use an ErrorCollector
It got resolved with the below code. The addtion of Future related code made it work.
#Test
public void testMultiThreadedPrimeNumberValidator() throws InterruptedException, ExecutionException {
ExecutorService executor = Executors.newFixedThreadPool(100);
Future future = executor.submit(new Runnable() {
public void run() {
for (int i = 0; i < 10; i++) {
try{
assertEquals(expectedValidation, primeNumberValidator.validate(primeNumber));
}catch(Error e){
System.out.println("error thrown :" + e);
//error =e;
System.out.println("error set to :" + e);
}catch(Exception e){
System.out.println("exception thrown :" + e);
//exception=e;
System.out.println("Exception set to :" + e);
}
}
}
});
future.get();
}