Java TestNG对所有测试套件运行一次方法

Java TestNG对所有测试套件运行一次方法,java,spring,maven,unit-testing,testng,Java,Spring,Maven,Unit Testing,Testng,我写了这段代码作为例子。 当@BeforeClass注释出现时,它将该值设置为我期望的值,并且继承的TestsOther类将正确打印该值。 但它每次都运行testInit方法,一次用于某个测试,一次用于另一个测试 因此,我想做的一件显而易见的事情是将其更改为@BeforeTest注释,这样它只会在所有测试之前对该方法求值一次,但随后我的继承TestsOther类将为null 有人能给我解释一下为什么它会得到一个空值,以及让testInit方法在整个套件中只运行一次的正确方法是什么吗 谢谢 更新:

我写了这段代码作为例子。 当@BeforeClass注释出现时,它将该值设置为我期望的值,并且继承的TestsOther类将正确打印该值。 但它每次都运行testInit方法,一次用于某个测试,一次用于另一个测试

因此,我想做的一件显而易见的事情是将其更改为@BeforeTest注释,这样它只会在所有测试之前对该方法求值一次,但随后我的继承TestsOther类将为null

有人能给我解释一下为什么它会得到一个空值,以及让testInit方法在整个套件中只运行一次的正确方法是什么吗

谢谢

更新: 为了更清楚,我对代码进行了一些重构

//deleted, see a refactoring at Update section.
我得到的结果是:

    public class TestsInit {

    protected String value;

    @BeforeClass
    public void testInit(){
        System.out.println("Entered testInit in TestsInit class,to set the value.");
        value="Something";
    }

    @Test
    public void SomeTest(){
        boolean isTrue=true;
        System.out.println("Entered SomeTest in TestsInit class.");
        Assert.assertTrue(isTrue);
    }
}

public class TestsOther extends TestsInit {

    @Test(dependsOnMethods = {"SomeTest"})
    public void OtherTest(){
        System.out.println("Entered OtherTest test in TestsOther class with value: "+value);
    }
}
我想看起来像这样:

Entered testInit in TestsInit class,to set the value.
Entered SomeTest in TestsInit class.
Entered testInit in TestsInit class,to set the value.
Entered SomeTest in TestsInit class.
Entered OtherTest test in TestsOther class with value: Something
因此,它将只运行testInit方法一次,并在TestsOther测试之前运行SomeTest测试一次。 我需要将该值存储在父类中,以便所有子类都可以使用它。 我只需要运行testInit一次,SomeTest也只需要运行一次

有什么建议吗

若要对所有类只执行一次testInit方法,请尝试在单独的抽象类中执行初始化部分,并在需要时使用该类扩展其他类

如果您正在接收这样的输出

某物

通过:一些测试

通过:其他测试

据了解,父类的@Test将在当前子类的@Test之前运行。因为两个类中都有@Test,所以在每个类中都会执行@Test并在控制台上打印

使用@BeforeTest注释,它也可以正常工作。这意味着我在这个更改中没有得到null

如果在这个建议的解决方案之后仍然为空,请您再分享一些代码。

若要对所有类只执行一次testInit方法,请尝试在单独的抽象类中执行初始化部分,并在需要时使用该类扩展其他类

如果您正在接收这样的输出

某物

通过:一些测试

通过:其他测试

据了解,父类的@Test将在当前子类的@Test之前运行。因为两个类中都有@Test,所以在每个类中都会执行@Test并在控制台上打印

使用@BeforeTest注释,它也可以正常工作。这意味着我在这个更改中没有得到null


如果在这个建议的解决方案之后仍然为空,请您再分享一些代码。

两个类都有测试,因此它们都是测试类,@BeforeClass将按类运行一次。 使用@BeforeTest,您会看到null,因为您有2个实例,但该方法仅在1个实例上调用,而另一个实例的值为null

如果希望只调用一个不带null的方法,则需要从ITestContext中存储并查找值

添加解释静态变量用法的示例


这两个类都有测试,所以它们都是测试类,@BeforeClass将按类运行一次。 使用@BeforeTest,您会看到null,因为您有2个实例,但该方法仅在1个实例上调用,而另一个实例的值为null

如果希望只调用一个不带null的方法,则需要从ITestContext中存储并查找值

添加解释静态变量用法的示例

因为@BeforeClass一个类一个类运行一次,并且在您的场景中有两个类,所以它将运行两次

带有@BeforeClass注释的输出

如果只想运行TestsInit一次,那么将@BeforeClass替换为@BeforeSuite

带有@BeforeSuite注释的输出

请注意,SomeTest运行了两次,这是因为TestsOther是一个扩展TestsInit类的不同类,并且它只有一个依赖于SomeTestCase的方法

希望这会有所帮助。

因为@BeforeClass会一个一个地运行一次,而且您的场景中有两个类,所以它会运行两次

带有@BeforeClass注释的输出

如果只想运行TestsInit一次,那么将@BeforeClass替换为@BeforeSuite

带有@BeforeSuite注释的输出

请注意,SomeTest运行了两次,这是因为TestsOther是一个扩展TestsInit类的不同类,并且它只有一个依赖于SomeTestCase的方法


希望这会有所帮助。

以下是您问题的答案:

我采用了您自己的代码,如下所示:

TestsInit类:

TestsOther类:

testng.xml:


以下是你问题的答案:

我采用了您自己的代码,如下所示:

TestsInit类:

TestsOther类:

testng.xml:


我希望它在父类中初始化一次,以便扩展它的所有其他子类都可以使用它。这样做是行不通的。另外,我举的例子更像是abstrac

除此之外,它们的值并不是真正的字符串,它们背后的逻辑更为复杂。您想要的是不可能的:您有两个TestsInit实例,但您只需要一个init实例。唯一的解决方案是使用上下文或静态变量。我已经更新了问题,如果你能看一看的话,尽管我认为你已经得到了我想要做的,根据你最后的回答。我已经添加了一个静态到值和testInit方法,它真的很有帮助,现在它只输入testInit一次,我得到了正确的值。有什么建议可以避免运行父SomeTest测试两次吗?我希望它在父类中初始化一次,以便扩展它的所有其他子类都可以使用它。这样做是行不通的。此外,我给出的示例比这更抽象,它们的值不是真正的字符串,它们背后的逻辑也更复杂。您想要的是不可能的:您有2个TestsInit实例,但您只需要一个init实例。唯一的解决方案是使用上下文或静态变量。我已经更新了问题,如果你能看一看的话,尽管我认为你已经得到了我想要做的,根据你最后的回答。我已经添加了一个静态到值和testInit方法,它真的很有帮助,现在它只输入testInit一次,我得到了正确的值。有什么建议我可以避免运行两次家长SomeTest测试吗?我更新了问题以使问题更清楚,我在那里展示了我想要的输出。我更新了问题以使问题更清楚,我已经在那里展示了我想要的输出。你能同时更新导入吗?@AnujTeotia没什么特别的,import org.testng.Assert;导入org.testng.annotations.Test@AnujTeotia使用TestNG和一些Spring库。在我看来一切都是正确的。让我检查一下这一点:请检查我的解决方案,使您的TestNG套件更加干燥。您可以同时更新导入吗?@AnujTeotia It’s note special,import org.TestNG.Assert;导入org.testng.annotations.Test@AnujTeotia使用TestNG和一些Spring库。在我看来一切都是正确的。让我来检查一下:请检查我的解决方案,使您的TestNG套件更干燥谢谢,我仍然没有得到只运行一次测试所需的操作?谢谢,我仍然没有得到只运行一次测试所需的操作?我需要测试它,我将更新您和主题。谢谢,这是我一直在寻找的。被选为答案@MarkDavydov很高兴能够帮助您。我需要测试它,我会更新您和主题。谢谢,这是我一直在寻找的。被选为答案@马克达维多夫很高兴能帮助你。
Entered testInit in TestsInit class,to set the value.
Entered SomeTest in TestsInit class.
Entered OtherTest test in TestsOther class with value: Something
@BeforeTest
public void testInit(ITestContext context) {
    context.setAttribute("value", "Something");
}

@Test(dependsOnMethods = {"SomeTest"})
public void OtherTest() {
    System.out.println(context.getAttribute("value"));
}
public class TestsInit {
    protected String value;
    private static boolean initialised = false;

    @BeforeClass
    public void testInit() {
        synchronized (TestsInit.class) {
            if (initialised) {
                return;
            }
            System.out.println("Entered testInit in TestsInit class,to set the value.");
            value = "Something";
            initialised = true;
        }
    }

    @Test
    public void SomeTest() {
        boolean isTrue = true;
        System.out.println("Entered SomeTest in TestsInit class.");
        Assert.assertTrue(isTrue);
    }
}
Entered testInit in TestsInit class,to set the value.
Entered SomeTest in TestsInit class.
Entered OtherTest test in TestsOther class with value: Something
Entered testInit in TestsInit class,to set the value.
Entered SomeTest in TestsInit class.
PASSED: SomeTest
PASSED: OtherTest
PASSED: SomeTest

===============================================
    Default test
    Tests run: 3, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
Entered testInit in TestsInit class,to set the value.
Entered SomeTest in TestsInit class.
Entered OtherTest test in TestsOther class with value: Something
Entered SomeTest in TestsInit class.
PASSED: SomeTest
PASSED: OtherTest
PASSED: SomeTest

===============================================
    Default test
    Tests run: 3, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
package Q45436872;

import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class TestsInit 
{

    protected String value;

    @BeforeClass
    public void testInit(){
    System.out.println("Entered testInit in TestsInit class,to set the value.");
    value="Something";
    }

    @Test
    public void SomeTest(){
    boolean isTrue=true;
    System.out.println("Entered SomeTest in TestsInit class.");
    Assert.assertTrue(isTrue);
    }
}
package Q45436872;

import org.testng.annotations.Test;

public class TestsOther  extends TestsInit
{

    @Test (dependsOnMethods = {"SomeTest"})
    public void OtherTest(){
    System.out.println("Entered OtherTest test in TestsOther class with value: "+value);
    }
}