Master JUnit 5: A Deep Dive into @TestInstance, @TestMethodOrder, and @Timeout
If your JUnit tests rely on clumsy static setup, break the moment they are reordered, or occasionally freeze your CI/CD pipeline, you are likely fighting the default test engine. JUnit 5 (Jupiter) introduced a suite of powerful annotations to solve these exact architectural bottlenecks. In this guide, we’ll explore three game-changers: @TestInstance, @TestMethodOrder, and @Timeout, and how to use them to build a professional-grade, enterprise-ready automation framework. 1. @TestInstance: Redefining the Test Lifecycle By default, JUnit creates a new instance of your test class for every single @Test method. This is known as Lifecycle.PER_METHOD. While this ensures perfect test isolation, it forces one major constraint: @BeforeAll and @AfterAll methods must be static. The Problem: Static Constraints and Overhead In a standard lifecycle, you are restricted to static fields for global setup. This becomes a headache when using Dependency Injection (like Spring’s @Autowired) or when your setup logic requires access to instance-level variables. Furthermore, if your test class has a heavy constructor or deep initialization, recreating it dozens of times for every test significantly slows down your build speed.