4

How to parameterize @BeforeEach/@AfterEach annotated method in Junit 5? This method than should take arguments from passed stream or list of objects.

Suppose you have a base class BaseSmokeTest, where in @BeforeEach annotated method named prepare() the WebDriver is initialized. Now, other classes such as LoginSmokeTest or LogoutSmokeTest extends the BaseSmokeTest, so they do not care about the WebDriver initialization.

I would like to run parametrized tests for each browser. The only solution for me is to parameterize prepare() method with String parameter that will specify which browser to use - void prepare(String browserName)

I've tried to use ParameterResolver for resolving the parameter for prepare method, but if I understand this correctly, the ParameterResolver only resolves parameter for @BeforeEach/@AfterEach method once.

I also tried to parametrize Constructor, but again - the ParameterResolver only resolves parameter for constructor once.

I am looking for solution that would do something like this:

@ValueSource(strings = {"firefox", "chrome"})
@BeforeEach
public void prepare(String browserName) {
    WebDriver driver = initializeWebDriver(browserName);
    WebDriverRunner.initialize(driver);
}

@AfterEach
public void cleanup() {
    WebDriverRunner.closeWebDriver();
}

Edit: I should also state that desired functionality of these parameterized tests then would be parallelization - each browser should be launched parallel in its own session.

Edit2: I should also mention that the BaseSmokeTest (despite of the name) does not contain any tests at all, just the initialization of web driver necessary for other tests to run. Tests contain only the classes that extends the BaseSmokeTest.

  • Simple solution: use abstract test class with abstract getBrowserName method and two concrete subclasses. – johanneslink Jul 26 '19 at 21:22
  • 2
    I quite do not understand your proposed solution. When I have a type of hierarchy where every SmokeTest extends BaseSmokeTest to prevent code duplication (where I want to parametrize BaseSmokeTest for any possible browser that will be tested), how would implementing two concrete subclasses help? And furthermore, how would BaseSmokeTest use these two subclasses, where as I stated before - there is no parametrization without ParameterResolver allowed for BeforeEach method? – Dominik Tuchyna Jul 28 '19 at 11:13

1 Answers1

0

If the number of different browsers is reasonably small you could go with a simple abstract test class approach. Here's a sketch:

abstract class BaseSmokeTest {
  abstract String getBrowserName();

  @BeforeEach
  public void prepare() {
    WebDriver driver = initializeWebDriver(getBrowserName());
    WebDriverRunner.initialize(driver);
  }

  @Test
  void test1() {}

  @Test
  void test2() {}
}

class FirefoxSmokeTest extends BaseSmokeTest {
  String getBrowserName() { return "firefox"; }
}


class ChromeSmokeTest extends BaseSmokeTest {
  String getBrowserName() { return "chrome"; }
} 

Jupiter will now run two test classes: ChromeSmokeTest and FirefoxSmokeTest. Each test method in BaseSmokeTest will be run twice, once for each concrete test class.

johanneslink
  • 4,877
  • 1
  • 20
  • 37
  • 2
    This does not help in my case. The purpose of having a BaseSmokeTest is to group together initialization functionality so that other classes like LoginSmokeTest and LogoutSmokeTest only care about the actual tests and does not duplicate any unnecessary code. Therefore, BaseSmokeTest should not have any tests whatsoever. It is only used as a parent for specific test classes (e.g. each can contain 100+ tests cases - it is then impossible to group everything into the BaseSmokeTest). The idea and test structure specified in the answer does not correlate with my question. – Dominik Tuchyna Jul 29 '19 at 08:21
  • In that case don't put any tests in the base class but put them all into the concrete test classes. – johanneslink Jul 29 '19 at 13:05
  • Sorry for the lack of my specification, I thought it was obvious but now I see that I did not mention it anywhere. I will edit the question to be more precise. – Dominik Tuchyna Jul 29 '19 at 16:14