1

According to this answer, the @Before annotation is executed once before each test, whereas the @BeforeClass annotation is only executed once before all tests.

My intuition tells me to always use @BeforeClass, so the question is, why even use @Before? Is there a case where the @Before annotation performs better/faster than the @BeforeClass annotation?

budi
  • 6,351
  • 10
  • 55
  • 80
  • 1
    Perform better? Why do you want performance into your junit tests? The @Before is usefull to reset a context before each test... – Karbos 538 Oct 30 '15 at 17:24
  • 1
    For my specific case, I'm currently using `@Before` paired with `assumeFalse` to exclude certain tests. So it's not really a performance issue I guess, it's more of, if I don't need to re-check redundant conditions, I should be using `@BeforeClass`. – budi Oct 30 '15 at 17:30
  • Could you provide an example of what you mean by that? – Michael Lloyd Lee mlk Oct 30 '15 at 17:32
  • `@Before public void exclude() { assumeFalse(condition); }` – budi Oct 30 '15 at 17:33
  • I'm sorry I still don't understand why you are doing that @budi. Are you after some sort of [categories](https://github.com/junit-team/junit/wiki/Categories)? Int tests vs unit sort of thing? – Michael Lloyd Lee mlk Oct 30 '15 at 21:36
  • Hmm... after looking at my code again, `@Before` wasn't even used as I was explicitly calling `exclude`... But yeah I'm going to take a look at categories, looks like a good solution to what I'm trying to do. – budi Oct 30 '15 at 22:01
  • 1
    To excude a test you may anotate it with @Ignore, no? – Karbos 538 Oct 31 '15 at 07:52
  • Yes, but I've found it easier to use `assumeFalse`. – budi Oct 31 '15 at 15:46
  • https://onlyfullstack.blogspot.com/2019/02/annotations-used-in-junit.html – Saurabh Oza Mar 12 '19 at 15:21

3 Answers3

3

Each test should be isolated. By using BeforeClass then the state of the previous test could be hanging about and messing up the later tests.

One generally uses BeforeClass to setup an expensive external resource and Before to reset the world (be that the external resource or local).

One final note:

performs better/faster

In this case I would say the two properties should be treated independently here (that is better!=faster). As long as the total time to run your complete tests suite is under 10 minutes then "faster" is simply not important.

Once you go above that magic ten minutes (and at this point you will definitely be talking integration tests not unit tests) then start looking for ways to make things "faster".

Michael Lloyd Lee mlk
  • 14,561
  • 3
  • 44
  • 81
3

I'll give you an example:

Say you need to validate a form in your web application. You are going to use Selenium for that.

Your test class will have 10 tests. You don't need to open and close your webdriver browser each time you start your test suite. In such case, you iniatilize your webdrive browser on a @BeforeClass method.

However, for each validation test you need to reset your form. This action you will perform on a @Before method.

This is a very simple example, but may make things clearer.

Sidney de Moraes
  • 993
  • 3
  • 11
  • 29
1

When you use @BeforeClass it suggests that you do initialization before all the tests. So one test might depend on other one (e.g. if tests change the state of fields), so I would encourage usage of @Before, or even better to do preparations for the test method inside the method itself. There are very rarely cases when your tests need exactly the same initial state, so why couple them together?

Krzysztof Krasoń
  • 26,515
  • 16
  • 89
  • 115