Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JUnit 4 @BeforeClass & @AfterClass when using Suites

Tags:

java

junit

junit4

When using this approach below, by setting up the jUnit with Suites. We got the problem when all @BeforeClass in every Testclass will be executed before any tests starts to execute. (For each n TestClass file the @BeforeClass runs, then after they have execute, it started to execute the first MyTest.class files @Test)

This will cause that we allocate up much resources and memory. My thoughts was that it must be wrong, shouldn't each @BeforeClass run only before the actual testclass is executed, not when the Suite is started?

@RunWith(Suite.class) @Suite.SuiteClasses({ MyTests.class, Mytests2.class, n1, n2, n }) public class AllTests {     // empty }   public class MyTests {  // no extends here     @BeforeClass     public static void setUpOnce() throws InterruptedException {         ...     @Test         ...  public class MyTests2 {  // no extends here     @BeforeClass     public static void setUpOnce() throws InterruptedException {         ...     @Test         ... 
like image 406
Andreas Mattisson Avatar asked Dec 17 '09 12:12

Andreas Mattisson


People also ask

What is @BeforeClass in JUnit?

org.junitAnnotating a public static void no-arg method with @BeforeClass causes it to be run once before any of the test methods in the class. The @BeforeClass methods of superclasses will be run before those of the current class, unless they are shadowed in the current class.

What is the difference between @BeforeClass and @before in JUnit?

The code marked @Before is executed before each test, while @BeforeClass runs once before the entire test fixture. If your test class has ten tests, @Before code will be executed ten times, but @BeforeClass will be executed only once.

Does @before run before each test?

Methods annotated with the @Before annotation are run before each test. This is useful when we want to execute some common code before running a test. Notice that we also added another method annotated with @After in order to clear the list after the execution of each test.

What is @before and @after in JUnit?

junit Getting started with junit @Before, @AfterAn annotated method with @Before will be executed before every execution of @Test methods. Analogous an @After annotated method gets executed after every @Test method. This can be used to repeatedly set up a Test setting and clean up after every test.


2 Answers

Write a @BeforeClass method in the AllTests class which will be executed when the suite is started.

public class MyTests1 {      @BeforeClass     public static void beforeClass() {         System.out.println("MyTests1.beforeClass");     }      @Before     public void before() {         System.out.println("MyTests1.before");     }      @AfterClass     public static void afterClass() {         System.out.println("MyTests1.AfterClass");     }      @After     public void after() {         System.out.println("MyTests1.after");     }      @Test     public void test1() {         System.out.println("MyTests1.test1");     }      @Test     public void test2() {         System.out.println("MyTests1.test2");     } }    public class MyTests2 {      @BeforeClass     public static void beforeClass() {         System.out.println("MyTests2.beforeClass");     }      @Before     public void before() {         System.out.println("MyTests2.before");     }      @AfterClass     public static void afterClass() {         System.out.println("MyTests2.AfterClass");     }      @After     public void after() {         System.out.println("MyTests2.after");     }      @Test     public void test1() {         System.out.println("MyTests2.test1");     }      @Test     public void test2() {         System.out.println("MyTests2.test2");     } }     @RunWith(Suite.class) @Suite.SuiteClasses( { MyTests1.class, MyTests2.class }) public class AllTests {      @BeforeClass     public static void beforeClass() {         System.out.println("AllTests.beforeClass");     }      @Before     public void before() {         System.out.println("AllTests.before");     }      @AfterClass     public static void afterClass() {         System.out.println("AllTests.AfterClass");     }      @After     public void after() {         System.out.println("AllTests.after");     }      @Test     public void test1() {         System.out.println("AllTests.test1");     }      @Test     public void test2() {         System.out.println("AllTests.test2");     }      } 

Output:

AllTests.beforeClass MyTests1.beforeClass MyTests1.before MyTests1.test1 MyTests1.after MyTests1.before MyTests1.test2 MyTests1.after MyTests1.AfterClass MyTests2.beforeClass MyTests2.before MyTests2.test1 MyTests2.after MyTests2.before MyTests2.test2 MyTests2.after MyTests2.AfterClass AllTests.AfterClass 
like image 200
nayakam Avatar answered Sep 19 '22 01:09

nayakam


I'm not too familiar with @RunWith in JUnit, so I may have done something wrong, but I can't seem to replicate the behaviour you describe. With the class:

@RunWith(Suite.class) @Suite.SuiteClasses( { FirstTest.class, SecondTest.class, ThirdTest.class }) public class AllTests {     // empty } 

And FirstTest.java looking like this:

public class FirstTest {     @BeforeClass     public static void doBeforeClass() {          System.out.println("Running @BeforeClass for FirstTest");     }      @Test     public void doTest() {         System.out.println("Running @Test in " + getClass().getName());     } } 

... with SecondTest.java and ThirdTest.java pretty much the same. I get the test output:

Running @BeforeClass for FirstTest Running @Test in FirstTest Running @BeforeClass for SecondTest Running @Test in SecondTest Running @BeforeClass for ThirdTest Running @Test in ThirdTest 

This is with JUnit 4.5.0 (default JUnit in Eclipse 3.5.1) on Sun's JDK 1.6.0_12. Can you spot any difference in my example from yours? Perhaps a different JDK/JVM? I don't know enough about the internals of JUnit to know if these can be a factor.

like image 22
Grundlefleck Avatar answered Sep 19 '22 01:09

Grundlefleck