public
Last active

Trace the call order of JUnit annotations in a test suite.

  • Download Gist
StaticUtils.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
package com.test;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
 
public abstract class StaticUtils {
protected Logger logger = LoggerFactory.getLogger( getClass() );
protected static Logger staticlogger = LoggerFactory.getLogger( StaticUtils.class );
public static void waitTimer( int units, int mills ) {
// number of units of time * mills in length for each time unit
try {
Thread.currentThread();
int x = 0;
while( x < units ) {
Thread.sleep( mills );
x = x + 1;
}
} catch ( InterruptedException ex ) {
ex.printStackTrace();
}
}
}
TestSuite.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
//https://github.com/djangofan/JUnitSuiteCallOrder
package com.test;
 
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
 
@RunWith(Suite.class)
@SuiteClasses( { XTest1.class, XTest2.class } )
public class TestSuite extends StaticUtils {
 
@BeforeClass
public static void beforeClass() {
staticlogger.info("START");
staticlogger.info("TestSuite:beforeClass");
}
@Before
public void setUp() { // not called by JUnit runner?
logger.info("TestSuite:setUp");
}
@Test
public void suite() { // not called by JUnit runner?
logger.info("TestSuite:suite");
}
@After
public void tearDown() { // not called by JUnit runner?
logger.info("TestSuite:tearDown");
}
 
@AfterClass
public static void afterClass() {
staticlogger.info("TestSuite:afterClass");
}
}
XTest1.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
package com.test;
 
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
 
public class XTest1 extends StaticUtils{
@Test
public void test11() {
String msg = "test11";
logger.info( msg );
System.out.println( msg );
waitTimer(4, 250); // 1 second
}
@Test
public void test12() {
String msg = "test12";
logger.info( msg );
System.out.println( msg );
waitTimer(12, 250); // 3 second
}
@Test
public void test13() {
String msg = "test13";
logger.info( msg );
System.out.println( msg );
waitTimer(16, 250); // 4 second
}
@Test
public void test14() {
String msg = "test14";
logger.info( msg );
System.out.println( msg );
waitTimer(1, 250); // 1 second
}
@Test
public void test15() {
String msg = "test15";
logger.info( msg );
System.out.println( msg );
}
@BeforeClass
public static void beforeClass() {
staticlogger.info("XTest1:beforeClass");
}
@Before
public void setUp() {
logger.info("XTest1:setUp");
}
@After
public void tearDown() {
logger.info("XTest1:tearDown");
}
 
@AfterClass
public static void afterClass() {
staticlogger.info("XTest1:afterClass");
}
 
}
XTest2.java
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
package com.test;
 
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
 
public class XTest2 extends StaticUtils{
@Test
public void test21() {
String msg = "test21";
logger.info( msg );
System.out.println( msg );
waitTimer(32, 250); // 8 second
}
@Test
public void test22() {
String msg = "test22";
logger.info( msg );
System.out.println( msg );
waitTimer(1, 250); // 1 second
}
@Test
public void test23() {
String msg = "test23";
logger.info( msg );
System.out.println( msg );
waitTimer(4, 250); // 1 second
}
@Test
public void test24() {
String msg = "test24";
logger.info( msg );
System.out.println( msg );
}
@Test
public void test25() {
String msg = "test25";
logger.info( msg );
System.out.println( msg );
waitTimer(4, 250); // 1 second
}
@BeforeClass
public static void beforeClass() {
staticlogger.info("XTest2:beforeClass");
}
@Before
public void setUp() {
logger.info("XTest2:setUp");
}
@After
public void tearDown() {
logger.info("XTest2:tearDown");
}
 
@AfterClass
public static void afterClass() {
staticlogger.info("XTest2:afterClass");
}
 
}
build.gradle
Groovy
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
apply plugin: 'java'
apply plugin: 'eclipse'
group = 'com.test'
 
ext {
projTitle = 'Test JUnit Annotation Order'
projVersion = '1.0'
}
 
repositories {
mavenCentral()
}
 
dependencies {
compile group: 'junit', name: 'junit', version: '4.+'
compile group: 'org.slf4j', name: 'slf4j-api', version: '1.7.+'
compile group: 'ch.qos.logback', name: 'logback-classic', version: '1.+'
}
 
tasks.withType(Test) {
jvmArgs '-Xms128m', '-Xmx1024m', '-XX:MaxPermSize=128m'
maxParallelForks = 4
testLogging {
exceptionFormat "full"
events "started", "passed", "skipped", "failed", "standardOut", "standardError"
displayGranularity = 0
}
forkEvery = 0
}
 
// this task uses standard JUnit test suite styling
task testSuite(type: Test) {
include '**/TestSuite.class'
testReportDir = file("${reporting.baseDir}/TestSuite")
testResultsDir = file("${buildDir}/test-results/TestSuite")
}
 
// this task uses Gradle test filter styling without a defined suite
task testWithoutSuite(type: Test) {
include '**/XTest*.class'
testReportDir = file("${reporting.baseDir}/XTest")
testResultsDir = file("${buildDir}/test-results/XTest")
}
logback.xml
XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
<configuration>
 
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>build/logs/junit.log</file>
<append>false</append>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4r %-5level %logger{35}: %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
<!-- We want error logging from this logger to go to an extra appender
It still inherits CONSOLE STDOUT from the root logger -->
<logger name="junit" level="INFO">
<appender-ref ref="STDOUT" />
</logger>
</configuration>
nonsuite-output.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
210 INFO com.test.StaticUtils: START
213 INFO com.test.StaticUtils: TestSuite:beforeClass
213 INFO com.test.StaticUtils: XTest1:beforeClass
216 INFO com.test.XTest1: XTest1:setUp
216 INFO com.test.XTest1: test11
1219 INFO com.test.XTest1: XTest1:tearDown
1220 INFO com.test.XTest1: XTest1:setUp
1221 INFO com.test.XTest1: test12
4221 INFO com.test.XTest1: XTest1:tearDown
4221 INFO com.test.XTest1: XTest1:setUp
4221 INFO com.test.XTest1: test13
8222 INFO com.test.XTest1: XTest1:tearDown
8222 INFO com.test.XTest1: XTest1:setUp
8222 INFO com.test.XTest1: test14
8473 INFO com.test.XTest1: XTest1:tearDown
8473 INFO com.test.XTest1: XTest1:setUp
8473 INFO com.test.XTest1: test15
8473 INFO com.test.XTest1: XTest1:tearDown
8473 INFO com.test.StaticUtils: XTest1:afterClass
8474 INFO com.test.StaticUtils: XTest2:beforeClass
8474 INFO com.test.XTest2: XTest2:setUp
8474 INFO com.test.XTest2: test21
16475 INFO com.test.XTest2: XTest2:tearDown
16475 INFO com.test.XTest2: XTest2:setUp
16475 INFO com.test.XTest2: test22
16725 INFO com.test.XTest2: XTest2:tearDown
16725 INFO com.test.XTest2: XTest2:setUp
16725 INFO com.test.XTest2: test23
17725 INFO com.test.XTest2: XTest2:tearDown
17725 INFO com.test.XTest2: XTest2:setUp
17725 INFO com.test.XTest2: test24
17725 INFO com.test.XTest2: XTest2:tearDown
17725 INFO com.test.XTest2: XTest2:setUp
17725 INFO com.test.XTest2: test25
18726 INFO com.test.XTest2: XTest2:tearDown
18726 INFO com.test.StaticUtils: XTest2:afterClass
18726 INFO com.test.StaticUtils: TestSuite:afterClass
198 INFO com.test.StaticUtils: XTest2:beforeClass
199 INFO com.test.StaticUtils: XTest1:beforeClass
203 INFO com.test.XTest2: XTest2:setUp
203 INFO com.test.XTest2: test21
204 INFO com.test.XTest1: XTest1:setUp
204 INFO com.test.XTest1: test11
1208 INFO com.test.XTest1: XTest1:tearDown
1209 INFO com.test.XTest1: XTest1:setUp
1209 INFO com.test.XTest1: test12
4211 INFO com.test.XTest1: XTest1:tearDown
4211 INFO com.test.XTest1: XTest1:setUp
4211 INFO com.test.XTest1: test13
8209 INFO com.test.XTest2: XTest2:tearDown
8211 INFO com.test.XTest2: XTest2:setUp
8211 INFO com.test.XTest2: test22
8211 INFO com.test.XTest1: XTest1:tearDown
8211 INFO com.test.XTest1: XTest1:setUp
8211 INFO com.test.XTest1: test14
8461 INFO com.test.XTest1: XTest1:tearDown
8461 INFO com.test.XTest2: XTest2:tearDown
8461 INFO com.test.XTest2: XTest2:setUp
8461 INFO com.test.XTest1: XTest1:setUp
8461 INFO com.test.XTest1: test15
8461 INFO com.test.XTest1: XTest1:tearDown
8462 INFO com.test.StaticUtils: XTest1:afterClass
8462 INFO com.test.XTest2: test23
9462 INFO com.test.XTest2: XTest2:tearDown
9462 INFO com.test.XTest2: XTest2:setUp
9462 INFO com.test.XTest2: test24
9462 INFO com.test.XTest2: XTest2:tearDown
9462 INFO com.test.XTest2: XTest2:setUp
9463 INFO com.test.XTest2: test25
10463 INFO com.test.XTest2: XTest2:tearDown
10463 INFO com.test.StaticUtils: XTest2:afterClass
suite_output.txt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
210 INFO com.test.StaticUtils: START
213 INFO com.test.StaticUtils: TestSuite:beforeClass
213 INFO com.test.StaticUtils: XTest1:beforeClass
216 INFO com.test.XTest1: XTest1:setUp
216 INFO com.test.XTest1: test11
1219 INFO com.test.XTest1: XTest1:tearDown
1220 INFO com.test.XTest1: XTest1:setUp
1221 INFO com.test.XTest1: test12
4221 INFO com.test.XTest1: XTest1:tearDown
4221 INFO com.test.XTest1: XTest1:setUp
4221 INFO com.test.XTest1: test13
8222 INFO com.test.XTest1: XTest1:tearDown
8222 INFO com.test.XTest1: XTest1:setUp
8222 INFO com.test.XTest1: test14
8473 INFO com.test.XTest1: XTest1:tearDown
8473 INFO com.test.XTest1: XTest1:setUp
8473 INFO com.test.XTest1: test15
8473 INFO com.test.XTest1: XTest1:tearDown
8473 INFO com.test.StaticUtils: XTest1:afterClass
8474 INFO com.test.StaticUtils: XTest2:beforeClass
8474 INFO com.test.XTest2: XTest2:setUp
8474 INFO com.test.XTest2: test21
16475 INFO com.test.XTest2: XTest2:tearDown
16475 INFO com.test.XTest2: XTest2:setUp
16475 INFO com.test.XTest2: test22
16725 INFO com.test.XTest2: XTest2:tearDown
16725 INFO com.test.XTest2: XTest2:setUp
16725 INFO com.test.XTest2: test23
17725 INFO com.test.XTest2: XTest2:tearDown
17725 INFO com.test.XTest2: XTest2:setUp
17725 INFO com.test.XTest2: test24
17725 INFO com.test.XTest2: XTest2:tearDown
17725 INFO com.test.XTest2: XTest2:setUp
17725 INFO com.test.XTest2: test25
18726 INFO com.test.XTest2: XTest2:tearDown
18726 INFO com.test.StaticUtils: XTest2:afterClass
18726 INFO com.test.StaticUtils: TestSuite:afterClass

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.