If you don't want to force a declaration of a variable that is set and checked on each subtest, then adding this to a SuperTest could do:
public abstract class SuperTest {
private static final ConcurrentHashMap<Class, Boolean> INITIALIZED = new ConcurrentHashMap<>();
protected final boolean initialized() {
final boolean[] absent = {false};
INITIALIZED.computeIfAbsent(this.getClass(), (klass)-> {
return absent[0] = true;
});
return !absent[0];
}
}
public class SubTest extends SuperTest {
@Before
public void before() {
if ( super.initialized() ) return;
... magic ...
}
}
Edit: I just found out while debugging that the class is instantiated before every test too. I guess the @BeforeClass annotation is the best here.
You can set up on the constructor too, the test class is a class after all. I'm not sure if it's a bad practice because almost all other methods are annotated, but it works. You could create a constructor like that:
public UT () {
// initialize once here
}
@Test
// Some test here...
The ctor will be called before the tests because they are not static.
Use Spring's @PostConstruct method to do all initialization work and this method runs before any of the @Test is executed
JUnit 5 @BeforeAll can be non static provided the lifecycle of the test class is per class, i.e., annotate the test class with a @TestInstance(Lifecycle.PER_CLASS)
and you are good to go
My dirty solution is:
public class TestCaseExtended extends TestCase {
private boolean isInitialized = false;
private int serId;
@Override
public void setUp() throws Exception {
super.setUp();
if(!isInitialized) {
loadSaveNewSerId();
emptyTestResultsDirectory();
isInitialized = true;
}
}
...
}
I use it as a base base to all my testCases.
Try this solution: https://stackoverflow.com/a/46274919/907576 :
with @BeforeAllMethods
/@AfterAllMethods
annotation you could execute any method in Test class in an instance context, where all injected values are available.
JUnit 5 now has a @BeforeAll annotation:
Denotes that the annotated method should be executed before all @Test methods in the current class or class hierarchy; analogous to JUnit 4’s @BeforeClass. Such methods must be static.
The lifecycle annotations of JUnit 5 seem to have finally gotten it right! You can guess which annotations available without even looking (e.g. @BeforeEach @AfterAll)
You can use the BeforeClass
annotation:
@BeforeClass
public static void setUpClass() {
//executed only once, before the first test
}
I solved this problem like this:
Add to your Base abstract class (I mean abstract class where you initialize your driver in setUpDriver() method) this part of code:
private static boolean started = false;
static{
if (!started) {
started = true;
try {
setUpDriver(); //method where you initialize your driver
} catch (MalformedURLException e) {
}
}
}
And now, if your test classes will extends from Base abstract class -> setUpDriver() method will be executed before first @Test only ONE time per run.
When setUp()
is in a superclass of the test class (e.g. AbstractTestBase
below), the accepted answer can be modified as follows:
public abstract class AbstractTestBase {
private static Class<? extends AbstractTestBase> testClass;
.....
public void setUp() {
if (this.getClass().equals(testClass)) {
return;
}
// do the setup - once per concrete test class
.....
testClass = this.getClass();
}
}
This should work for a single non-static setUp()
method but I'm unable to produce an equivalent for tearDown()
without straying into a world of complex reflection... Bounty points to anyone who can!
Source: Stackoverflow.com