What do @BeforeAll and @AfterAll do in JUnit 5, and how do they differ from @BeforeEach and @AfterEach?
answer
- 'All' = once per class; 'Each' = once per test
- BeforeAll/AfterAll bracket the whole run
- BeforeEach/AfterEach bracket each test inside
- Expensive shared setup -> BeforeAll; fresh per-test state -> BeforeEach
- 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 sIn 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
Can state that 'All' runs once per class and 'Each' runs once per test, and give an example use for each.
Can describe the full execution order and choose the right hook based on cost vs isolation needs.
Can articulate the isolation trade-off of sharing state via @BeforeAll and steer teams away from order-dependent tests.
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