I have an abstract base class, which I use as a base for my unit tests (TestNG 5.10). In this class, I initialize the whole environment for my tests, setting up database map
When I run from: JUnitCore.runClasses(TestClass.class); It will execute the parent properly, before the child (You do not need super.SetUpBeforeClass();) If you run it from Eclipse: For some reason it fails to run the base class. The work around: Call the base class explicitely: (BaseTest.setUpBeforeClass();) You may want to have a flag in the base class in case you run it from an application, to determine if it is already setup or not. So it only runs once if you run it via both possible methods (such as from eclipse for personal testing, and through ANT for a build release).
This appears to be a bug with Eclipse, or at least unexpected results..
This works for me --
abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@Override
@BeforeClass
doInitialization() {
//do class specific init
}
@Test
doTests() {...}
}
I've faced a similar issue today, the only difference was a Base class was not abstract
Here's my case
public class A {
@BeforeClass
private void doInitialization() {...}
}
public class B extends A {
@BeforeClass
private void doSpecificInitialization() {...}
@Test
public void doTests() {...}
}
It occurred that a @BeforeClass
method from class A was never executed.
Playing with privacy modifiers I found that TestNG will not execute a @BeforeClass
annotated method from inherited class if a method is not visible from a class-inheritor
So this will work:
public class A {
@BeforeClass
private void doInitialization() {...}
}
public class B extends A {
@BeforeClass
//Here a privacy modifier matters -> please make sure your method is public or protected so it will be visible for ancestors
protected void doSpecificInitialization() {...}
@Test
public void doTests() {...}
}
As a result following happens:
How about having your @BeforeClass method call an empty specificBeforeClass() method that may or may not be overwritten by sub classes like so:
public class AbstractTestClass {
@BeforeClass
public void generalBeforeClass() {
// do stuff
specificBeforeClass();
}
protected void specificBeforeClass() {}
}
public class SpecificTest {
@Override
protected void specificBeforeClass() {
// Do specific stuff
}
// Tests
}
A better and cleaner way to achieve this using inheritance may be as following -
abstract class A {
@BeforeClass
void doInitialization() {}
}
class B extends A {
@Override
@BeforeClass
void doInitialization() {
super.doInitialization();
}
@Test
void doTests() {}
}
I added public
to the abstract class and TestNG (6.0.1) executed the doInitialization() before doTests
. TestNG does not execute doInitialization()
if I remove public
from class A.
public abstract class A {
@BeforeClass
doInitialization() {...}
}
class B extends A {
@Test
doTests() {...}
}