skip to content

What do @BeforeAll and @AfterAll do in JUnit 5, and how do they differ from @BeforeEach and @AfterEach?

level: juniorimportance: must knowfreq 70%

answer

  1. 'All' = once per class; 'Each' = once per test
  2. BeforeAll/AfterAll bracket the whole run
  3. BeforeEach/AfterEach bracket each test inside
  4. Expensive shared setup -> BeforeAll; fresh per-test state -> BeforeEach
  5. JUnit 4 equivalents: @BeforeClass/@AfterClass

basics

~10 s

@BeforeAll runs once before all the tests in a class; @AfterAll runs once after all of them. @BeforeEach and @AfterEach run before and after every single test method instead.

solid answer

~40 s

In JUnit 5, @BeforeAll marks a method that runs exactly once before any test in the class executes, and @AfterAll marks one that runs exactly once after all tests finish. They're for class-level setup and teardown of expensive, shared resources, e.g. starting a database or test server, then closing it. By contrast, @BeforeEach and @AfterEach run before and after each individual test method, so they fire N times for N tests and are meant to give each test a fresh, isolated state. A useful way to remember it: 'All' = once per class, 'Each' = once per test. Order is: @BeforeAll, then for every test (@BeforeEach, test, @AfterEach), then @AfterAll.

go deeper

for a junior

Can state that 'All' runs once per class and 'Each' runs once per test, and give an example use for each.

for a middle

Can describe the full execution order and choose the right hook based on cost vs isolation needs.

for a senior

Can articulate the isolation trade-off of sharing state via @BeforeAll and steer teams away from order-dependent tests.

for a principal

Frames lifecycle choices as a policy: when shared fixtures are acceptable, how they interact with parallelism, and the maintenance cost of cross-test coupling.

## The problem these annotations solve A **test class** is just a Java class containing **test methods** (methods marked `@Test`). When you run it, the testing framework (here **JUnit 5**, the standard Java unit-testing library) calls each test method and reports pass/fail. **Setup** is work you do *before* a test so it has what it needs (e.g. create an object, open a connection); **teardown** is cleanup done *after* (e.g. close that connection). JUnit gives you **lifecycle annotations** to attach such code to the right moment. ## The four lifecycle hooks - **`@BeforeEach`** — a method that runs **before every individual test method**. If a class has 5 tests, it runs 5 times. Use it to build fresh state so tests don't interfere. - **`@AfterEach`** — runs **after every individual test method** (5 times for 5 tests). Use it to clean up per-test state. - **`@BeforeAll`** — runs **exactly once, before the first test in the class** (not once per test). Use it for setup that is **expensive and safe to share** across all tests, e.g. starting an in-memory database, an embedded web server, or loading a large file. - **`@AfterAll`** — runs **exactly once, after the last test in the class** finishes. Use it to release whatever `@BeforeAll` acquired. ## Mental model: 'All' vs 'Each' `All` = the whole class, so **once**. `Each` = each test, so **N times**. That single distinction is the heart of the topic. ## Full execution order For a class with tests T1, T2: ``` @BeforeAll @BeforeEach -> T1 -> @AfterEach @BeforeEach -> T2 -> @AfterEach @AfterAll ``` So `@BeforeAll` and `@AfterAll` bracket the *entire* run; the `Each` hooks bracket *each* test inside that. ## Why not just put everything in @BeforeEach? You could, but re-doing expensive work (like spinning up a database) before every single test wastes time. `@BeforeAll` does it **once** and shares the result. The trade-off is **isolation**: anything shared via `@BeforeAll` is reused, so tests must not corrupt it. Per-test mutable state still belongs in `@BeforeEach`. ## A subtlety you must know Under JUnit 5's **default lifecycle**, `@BeforeAll`/`@AfterAll` methods **must be `static`** (because no test instance exists yet when they run). That's covered in depth in a separate question; just remember it pairs with these two annotations. ## JUnit 4 note If you've seen JUnit 4, the equivalents are `@BeforeClass`/`@AfterClass` (also static) and `@Before`/`@After`. JUnit 5 renamed them to the clearer `*All`/`*Each` names.

  • If a test mutates an object created in @BeforeAll, will later tests see the change?
    Yes. @BeforeAll runs once and the object is shared, so mutations persist across tests in that class — a common source of order-dependent flakiness. Put mutable per-test state in @BeforeEach instead.
  • What are the JUnit 4 names for these hooks?
    @BeforeClass/@AfterClass correspond to @BeforeAll/@AfterAll, and @Before/@After correspond to @BeforeEach/@AfterEach.

saying these in an interview costs you the question

  • Saying @BeforeAll runs before each test (that's @BeforeEach)
  • Thinking @BeforeAll re-runs per test method
  • Confusing JUnit 4 @Before with JUnit 5 @BeforeAll
  • Claiming @AfterAll runs even per test

context