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

时间:2017-08-01 11:43:18

标签: java spring maven unit-testing testng

//deleted, see a refactoring at Update section.

我有一段代码,我写了一个例子。 当 @BeforeClass 注释显示时,它将值设置为我期望的值,并且继承的TestsOther类正确打印它。 每次都会运行 testInit 方法,一次用于 SomeTest ,一次用于 OtherTest

所以我想要做的显而易见的事情是将其更改为 @BeforeTest 注释,因此它会在所有测试之前仅评估该方法一次,但随后我继承的TestsOther类获得

有人可以向我解释为什么它会变为空,并且使 testInit 方法只对所有套件运行一次的正确方法是什么。

感谢。

更新 为了更清楚,我已经重构了一些代码。

    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

我想看起来像这样:

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。

有什么建议吗?

4 个答案:

答案 0 :(得分:2)

以下是您的问题的答案:

我已按照以下方式使用您自己的代码:

TestsInit上课:

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);
    }
}

TestsOther上课:

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);
    }
}

testng.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite">
  <test name="Test">
    <classes>
       <class name="Q45436872.TestsInit"/> 
       <class name="Q45436872.TestsOther"/>
    </classes>
  </test> <!-- Test -->
</suite> <!-- Suite -->

现在,当我将此设置作为TestNG Suite运行时,我得到以下结果:

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

===============================================
Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================

我想在此之前我们在同一页上。

要求:

现在,您的要求似乎是:

  1. 仅运行一次testInit方法。
  2. SomeTest测试
  3. 之前运行TestsOther测试一次

    解决方案:

    作为解决方案,我只是注释了TestsInit类的强制执行。所以我更新的testng.xml如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
    <suite name="Suite">
      <test name="Test">
        <classes>
     <!--       <class name="Q45436872.TestsInit"/>  -->
           <class name="Q45436872.TestsOther"/>
        </classes>
      </test> <!-- Test -->
    </suite> <!-- Suite -->

    所以现在我只执行TestsOther类。 TestsOther班级extends TestsInit。因此testInit()@BeforeClass注释范围内时,此方法首先执行。

    接下来,SomeTest()注释下的@Test会被执行,这符合您的要求。

    最后,来自OtherTest()类的@Test注释下的TestsOther方法被执行(标记为(dependsOnMethods = {"SomeTest"})),这再次符合您的要求。

    我的控制台上的输出是:

    Entered testInit in TestsInit class,to set the value.
    Entered SomeTest in TestsInit class.
    Entered OtherTest test in TestsOther class with value: Something
    

    此输出完全符合您的要求。

    如果这回答你的问题,请告诉我。

答案 1 :(得分:1)

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

如果您只想在没有null的情况下调用该方法,则需要存储并查找ITestContext中的值。

@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);
    }
}

答案 2 :(得分:1)

由于@BeforeClass按类运行一次,因此在您的方案中有两个类,因此它将运行两次。

使用@BeforeClass注释

输出
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
===============================================

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

使用@BeforeSuite注释

输出
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
===============================================

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

希望这会有所帮助。

答案 3 :(得分:0)

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

如果您收到这样的输出

  

东西

     

PASSED:SomeTest

     

PASSED:OtherTest

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

使用 @BeforeTest 注释,它也能正常工作。(这意味着我没有在此更改中获得 null

如果您在提出此解决方案后仍然无效,请分享一些代码。