@BeforeClass and inheritance - order of execution

前端 未结 16 2037
梦如初夏
梦如初夏 2020-12-02 11:39

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

相关标签:
16条回答
  • 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..

    0 讨论(0)
  • 2020-12-02 12:17

    This works for me --

    abstract class A {
        @BeforeClass
        doInitialization() {...}
    }
    
    class B extends A {
        @Override
        @BeforeClass
        doInitialization() { 
    
           //do class specific init
    
        }   
    
        @Test
        doTests() {...}
    }
    
    0 讨论(0)
  • 2020-12-02 12:17

    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.

    • A.doInitialization() -> THIS WAS NEVER EXECUTED silently
    • B.doSpecificInitialization()
    • B.doTests()

    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:

    • A.doInitialization()
    • B.doSpecificInitialization()
    • B.doTests()
    0 讨论(0)
  • 2020-12-02 12:20

    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
    }
    
    0 讨论(0)
  • 2020-12-02 12:21

    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() {}
    }
    
    0 讨论(0)
  • 2020-12-02 12:22

    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() {...}
    }
    
    0 讨论(0)
提交回复
热议问题