nemelianov
nemelianov

Reputation: 909

Call @Before and @After methods for each test in a suit

I have class runner for all my tests:

import org.junit.*;
import org.junit.rules.TestName;
import org.junit.rules.TestRule;
import org.junit.rules.TestWatcher;
import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.List;

@RunWith(Suite.class)
@Suite.SuiteClasses({

   Test1.class,
   Test2.class,
   Test3.class,
   Test4.class,
   Test5.class
})

public class AllTestRunner {
   ...
@Before
public void method1() {}

@After 
public void method2() {}

I need to run method1() and method2() for each @Test in each class from SuiteClasses. But it doesn't work, may be I do smth. wrong?

Thanks for your help and sorry for my english.

Upvotes: 0

Views: 496

Answers (3)

nrainer
nrainer

Reputation: 2623

Alternatively you can use rules. This approach has the advantage that you don't need to inherit a certain class.

In one class you implement a rule which specifies the behavior to be executed before and afte the test case execution.

public class MyRule implements MethodRule {
  public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) {
    return new Statement() {
        @Override
        public void evaluate() throws Throwable {
            try {
                before();
                statement.evaluate();
            } finally {
                after();
            }
        }
    };
  }

  protected void before() {
    System.out.println("before");
  }

  public void after() {
    System.out.println("after");
  }
}

Then you can instantiate the rule in each test class where it should be used. No inheritance is needed.

public class TestClass {

  @Rule
  public MyRule myRule = new MyRule();

  @Test
  public void test() {
  }
}

Upvotes: 0

nemelianov
nemelianov

Reputation: 909

First, create an abstract class BasicTest:

//
    @Rule
    public TestWatcher watcher = new TestWatcher() {

        @Override
        protected void starting(Description description) {
        }

        @Override
        protected void succeeded(Description description) {
        }

        @Override
        protected void failed(Throwable e, Description description) {
        }

        @Override
        protected void skipped(AssumptionViolatedException e, Description description) {
        }

        @Override
        public void finished(Description description) {
        }
    };
//...

For each test class:

public class Test extends BasicTest { }

So, for each @Test will be called methods from TestWatcher.

Upvotes: 1

Kraiss
Kraiss

Reputation: 999

It is because @Before, @After, @BeforeClass and @AfterClass are class dependent. In other words, they only concerns the class they are defined in.

There is no way to achieve what you try to achieve with these annotations, sorry. You will have to duplicate your method in each SuiteClasses

Upvotes: 0

Related Questions