@BeforeClass

From NovaOrdis Knowledge Base
Jump to navigation Jump to search

Internal

Overview

The annotation must be attached to a static method.

@BeforeClass and Class Hierarchies

If two methods with different names are annotated with @BeforeClass in a test class hierarchy, as shown below:

TestBase.java
  │  @BeforeClass
  │  public static void testBaseOneTimeSetup() {
  │     ...
  │  }
  │
  └── SomeTest.java
        @BeforeClass
        public static void someTestOneTimeSetup() {
          ...
        }

then both methods are executed only once, in this order: first the parent class method (testBaseOneTimeSetup()), then the subclass method (someTestOneTimeSetup()). The rule holds true in a multi-layer hierarchy.

However, if both methods have the same name, an override of sorts takes place and only the method belonging to the subclass is executed:

TestBase.java
  │  @BeforeClass
  │  public static void oneTimeClassSetup() {
  │     ...
  │  }
  │
  └── SomeTest.java
        @BeforeClass
        public static void oneTimeClassSetup() {
          ...
        }

Only SomeTest.oneTimeClassSetup() (the most specific subclass) is executed, so if you need the logic executed in superclass, it must be invoked explicitly with:

class SomeTest {
  @BeforeClass
  public static void oneTimeClassSetup() {
     TestBase.oneTimeClassSetup();
  }
}

This behavior is useful when we want to customize static fields in subclass, then execute the @BeforeClass superclass behavior.

In conclusion, if class-level one-time initialization is needed for each level of a class hierarchy, the best solution is to name @BeforeClass methods differently for each class. This way, all methods are executed in order, starting from the root of the hierarchy and continuing towards the bottom, ending with the most specific subclass. If customization of static fields is required in subclass, annotated same-name methods with @BeforeClass both in superclass and subclass. Recommended naming convention:

class SomeTest {
  @BeforeClass
  public static void someTestOneTimeSetup() {
     ...
  }
}