//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。
有什么建议吗?
答案 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
===============================================
我想在此之前我们在同一页上。
现在,您的要求似乎是:
testInit
方法。SomeTest
测试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 )
如果您在提出此解决方案后仍然无效,请分享一些代码。