Quick background: I've been hunting down a Maven / Surefire test-running problem for days now, and I've narrowed it down to a small number suspect of tests. The behavior I'm seeing is insane. I start with mvn clean test
: 250 tests run, 0 skipped. Now, I move the suspect test into src/test/java
and try again: 146 tests run, 0 skipped! The output of Maven gives no clue that other tests aren't being run, even with the -X
flag.
That brings me to my question: the reason I call the test 'suspect' is that the whole class is decorated with @Ignore, so I would imagine that including it in my test sources should have no effect at all. Then it occurred to me -- those classes have @BeforeClass/@AfterClass methods that manage a dummy Zookeeper server. It's resulted in wonky behavior before, which is why we have the tests @Ignored.
If JUnit is running the before/after code but ignoring the tests, I have no idea what might happen (but it'd probably be super bad). Is this happening? Is this supposed to happen? If so, how am I supposed to say "for reference, here's a test that should work but needs fixing" when it includes @BeforeClass / @AfterClass? Also of substantial interest: what the hell is this doing to Surefire / Maven, that it causes unrelated tests to fall off the face of the Earth?
A test method annotated with @Ignore will not be executed. If a test class is annotated with @Ignore, then none of its test methods will be executed.
The @Ignore test annotation is used to ignore particular tests or group of tests in order to skip the build failure. @Ignore annotation can be used in two scenarios as given below: If you want to ignore a test method, use @Ignore along with @Test annotation.
Before and BeforeClass in JUnit The function @Before annotation will be executed before each of test function in the class having @Test annotation but the function with @BeforeClass will be execute only one time before all the test functions in the class.
The best way to disable a test method is to use the @Disabled annotation. @Disabled annotation is used to tell JUnit 5 engine that the annotated test class or test method is currently disabled and should not be executed. Test method will not be executed and will be included in the test report as a disabled test.
If you have a test with the @Ignore annotation, then it is normal behaviour for the @BeforeClass & @AfterClass to get run, whether or not all of the tests are @Ignored.
If, however, the Class has an @Ignore annotation, then the @BeforeClass & @AfterClass don't get run.
For maven, if you don't want to run any tests in a particular class, then you have to ignore them in surefire or failsafe. Add this to the maven configuration (see Maven Surefire Plugin)
<excludes>
<exclude>**/FoobarTest.class</exclude>
</excludes>
Environment: JDK 1.6, surefire plugin 2.9, jUnit 4.8.1, Maven 3.0, 3.0.3, 2.2.1.
I created this test class:
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@Ignore
public class IgnoreTest {
@BeforeClass
public static void beforeClass() {
System.out.println("BEFORE CLASS");
}
@AfterClass
public static void afterClass() {
System.out.println("AFTER CLASS");
}
@Test
public void test1() throws Exception {
System.out.println("test1");
}
@Test
public void test2() throws Exception {
System.out.println("test2");
}
@Test
public void test3() throws Exception {
System.out.println("test3");
}
}
Then mvn clean test
print this:
Running hu.palacsint.stackoverflow.q7535177.IgnoreTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.015 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 1
Works as you expected. If I remove the @Ignore
and run mvn clean test
again it prints this:
Running hu.palacsint.stackoverflow.q7535177.IgnoreTest
BEFORE CLASS
test2
test1
test3
AFTER CLASS
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.045 sec
Results :
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
So, it works for me with three different Maven versions. No @BeforeClass
/@AfterClass
was run in @Ignore
d classes.
There is one (maybe more) situation when @BeforeClass
/@AfterClass
methods could run in an @Ignore
d test class. It's when your ignored class has a not ignored subclass:
import org.junit.Test;
public class IgnoreSubTest extends IgnoreTest {
@Test
public void test4() throws Exception {
System.out.println("test4 subclass");
}
}
Results of mvn clean test
:
Running hu.palacsint.stackoverflow.q7535177.IgnoreTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 1, Time elapsed: 0.047 sec
Running hu.palacsint.stackoverflow.q7535177.IgnoreSubTest
BEFORE CLASS
test4 subclass
test1
test2
test3
AFTER CLASS
Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.057 sec
Results :
Tests run: 5, Failures: 0, Errors: 0, Skipped: 1
In this case the @BeforeClass
and the @AfterClass
methods runs because they are methods of the IgnoreSubTest
test class.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With