我有一个抽象的基类,我将其用作单元测试的基础(TestNG 5.10)。在此课程中,我初始化了测试的整个环境,设置数据库映射等。此抽象类具有一个带有一个方法的方法 @BeforeClass 进行初始化的注释。

接下来,我使用我拥有的特定课程扩展该课程 @Test 方法以及 @BeforeClass 方法。这些方法对环境进行特定于类的初始化(例如将一些记录放入数据库中)。

我如何执行特定订单 @BeforeClass 注释方法?我需要从抽象基类中执行扩展类的基础类别。

例子:

abstract class A {
    @BeforeClass
    doInitialization() {...}
}

class B extends A {
    @BeforeClass
    doSpecificInitialization() {...}

    @Test
    doTests() {...}
}

预期订单:

A.doInitialization
B.doSpecificInitialization
B.doTests

实际订单:

B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization        // <---not executed
 B.doTests)                // <-/
有帮助吗?

解决方案

不要放 @BeforeClassabstract 班级。从每个子类调用它。

abstract class A {
    void doInitialization() {}
}

class B extends A {
    @BeforeClass
    void doSpecificInitialization() {
        super.doInitialization();
    }

    @Test
    void doTests() {}
}

似乎Testng有 @BeforeClass(dependsOnMethods={"doInitialization"}) - 试试看。

其他提示

编辑: 下面的答案是 朱尼特, ,但是无论如何我都会把它留在这里,因为它可能会有所帮助。

根据 Junit API: :“超类的@beforeclass方法将在当前类之前运行。”

我对此进行了测试,似乎对我有用。

但是,正如@odys在下面提到的那样,对于Junit,您需要拥有 两种命名的方法不同 虽然这样做,但由于父母会被遮蔽,因此只会导致子类方法正在运行。

我添加了 public 在抽象类和testng(6.0.1)之前执行了doinitialization() doTests. 。 Testng不执行 doInitialization() 如果我删除 public 来自A级A。

public abstract class A {
 @BeforeClass
 doInitialization() {...}
}

class B extends A {    
 @Test
 doTests() {...}
}

我只是用5.11尝试了您的示例,然后首先调用了基类的@beforeclass。

您可以发布testng.xml文件吗?也许您在那里指定A和B,而仅需B。

请随时跟进Testng-users邮寄列表,我们可以仔细研究您的问题。

- 塞德里克

我只是经历了这一点,并找到了一种实现这一目标的方法。只是使用 alwaysRun@BeforeClass 或者 @BeforeMethod 在抽象课程中,按照您的期望工作。

public class AbstractTestClass {
    @BeforeClass(alwaysRun = true)
    public void generalBeforeClass() {
        // do stuff
        specificBeforeClass();
    }
}

当我逃跑时: junitcore.runclasses(testclass.class);它将在孩子之前正确执行父母(您不需要 super.setupbeforeclass();)如果您从Eclipse运行它:由于某种原因,它无法运行基类。工作的工作:明确致电基类:((basetest.setupbeforeclass();)如果您从应用程序运行它,则可能需要在基类中有一个标志,以确定它是否已经设置。因此,它仅在您通过两种可能的方法运行(例如来自Eclipse的个人测试,以及通过ANT进行构建版本)运行一次。

这似乎是Eclipse或至少意外结果的错误。

为junit:正如@fortega所提到的:根据Junit API的说法:“ @beforeclass的超类方法将在当前班级之前运行。”

但小心点 不要命名两种使用相同名称的方法. 。由于在这种情况下,父母将隐藏父级的方法。 资源.

如何使您的@beforeclass方法调用一个空的特定beforeclass()方法,该方法可能会被类似子类覆盖或可能不会覆盖:

public class AbstractTestClass {
  @BeforeClass
  public void generalBeforeClass() {
    // do stuff
    specificBeforeClass();
  }

  protected void specificBeforeClass() {}
}

public class SpecificTest {
  @Override
  protected void specificBeforeClass() {
    // Do specific stuff
  }

  // Tests
}

dependsOnMethod 可以使用。

例如在春季的情况下(AbstractTestNGSpringContextTests)

@BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextPrepareTestInstance")

检查您的导入语句。它应该是

import org.testng.annotations.BeforeClass;

不是

import org.junit.BeforeClass;

您为什么不尝试在超级类中创建一个抽象方法dospecialinit(),从超级类中的beforeclass注释方法中调用。

因此,继承您的班级的开发人员被迫实施此方法。

这里还有另一个简单的解决方案。

我的特殊情况是,我需要在执行超级类中的“ beforeclass”之前从“ beforeclass”中注入模拟服务。

为此 - 只需使用 @ClassRule 在子类中。

例如:

@ClassRule
public static ExternalResource mocksInjector = new ExternalResource() {
    @Override
    protected void before() {
        // inject my mock services here
        // Note: this is executed before the parent class @BeforeClass
    }
};

我希望这有帮助。这可以有效地执行“反向”顺序的静态设置。

我今天面临类似的问题,唯一的区别是基类不是抽象的

这是我的案子

public class A {
    @BeforeClass
    private void doInitialization() {...}
}

public class B extends A {
    @BeforeClass
    private void doSpecificInitialization() {...}

    @Test
    public void doTests() {...}
}

发生了一个 @BeforeClass A类的方法从未执行。

  • a.doinialization() - >从未默默执行
  • B. oppecificinialization()
  • b.dotests()

使用隐私修饰符播放我发现Testng 不会执行 一个 @BeforeClass 来自继承类的注释方法 如果从类商中看不到方法

因此,这将起作用:

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() {...}
}

结果,以下发生了:

  • a.doinialization()
  • B. oppecificinialization()
  • b.dotests()

这对我有用 -

abstract class A {
    @BeforeClass
    doInitialization() {...}
}

class B extends A {
    @Override
    @BeforeClass
    doInitialization() { 

       //do class specific init

    }   

    @Test
    doTests() {...}
}

在我的情况下(junit),我在基类和派生类中具有相同的方法称为setup()。在这种情况下 只要 派生类的方法被调用,我称其为基类方法。

使用继承实现这一目标的更好,更干净的方法可能如下 -

abstract class A {

    @BeforeClass
    void doInitialization() {}
}

class B extends A {

    @Override
    @BeforeClass
    void doInitialization() {
        super.doInitialization();
    }

    @Test
    void doTests() {}
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top