题
我有一个代表 TestNG 中数据库测试的基类,我想指定从该类扩展的所有类都属于“db-test”组,但是我发现这似乎不可能。我尝试过@Test注释:
@Test(groups = { "db-test" })
public class DBTestBase {
}
然而,这不起作用,因为 @Test 注解会尝试将一堆方法放入测试中,并且当测试运行时,Eclipse 中会弹出警告/错误。
所以我尝试禁用测试,因此至少分配了组:
@Test(enabled = false, groups = { "db-test" })
public class DBTestBase {
}
但随后任何 @BeforeTest (和其他类似的注释)也会被禁用......这当然不是我想要的。
我想要某种方法将一个类注释为特定类型的组,但这在 TestNG 中似乎不太可能。还有人有其他想法吗?
解决方案
答案是通过习惯 org.testng.IMethodSelector:
它是 包含方法() 可以排除我们想要的任何方法,例如公共的未注释的方法。
但是,要注册自定义 爪哇 MethodSelector,您必须将其添加到 XML测试 由任何 TestRunner 管理的实例,这意味着您需要自己的 自定义测试运行器.
但是,要构建自定义 TestRunner,您需要注册 测试工厂, ,通过 -测试运行工厂 选项。
但是 -testrunfactory 从未被考虑到 测试NG 班级...所以你还需要定义一个自定义 TestNG 类:
- 为了重写configure(Map)方法,
- 所以你实际上可以设置 TestRunnerFactory
- TestRunnerFactory 将为您构建一个自定义的 TestRunner,
- TestRunner 将为 XMLTest 实例设置一个自定义 XMLMethodSelector
- XMLMethodSelector 将构建自定义 IMethodSelector
- IMethodSelector 将排除您选择的任何 TestNG 方法!
好的...这是一场噩梦。但这也是一个代码挑战,所以它一定有点挑战性;)
所有代码均可在 DZone 片段.
像往常一样,进行代码挑战:
- 一个java类(以及相当多的内部类)
- 将类复制粘贴到“source/test”目录中(因为包是“test”)
- 运行它(不需要参数)
迈克·斯通更新:
我将接受这一点,因为它听起来非常接近我最终所做的事情,但我想我也会添加我所做的事情。
基本上,我创建了一个 Groups 注释,其行为类似于 Test(和其他)注释的 groups 属性。
然后,我创建了一个 GroupsAnnotationTransformer,它使用 IAnnotationTransformer 查看所有定义的测试和测试类,然后修改测试以添加组,这与组排除和包含完美配合。
修改构建以使用新的注释转换器,一切都完美运行!
出色地...一个需要注意的是,它不会将组添加到非测试方法中......因为在我这样做的时候,还有另一个注释转换器可以让你转换任何东西,但由于某种原因它没有包含在我使用的 TestNG 中......所以最好将之前/之后带注释的方法设置为alwaysRun=true...这对我来说就足够了。
最终结果是我能做到:
@Groups({ "myGroup1", "myGroup2"})
public class MyTestCase {
@Test
@Groups("aMethodLevelGroup")
public void myTest() {
}
}
我让变压器可以与子类化和其他一切一起工作。
其他提示
TestNG 将运行带有 @Test 注释的类中的所有公共方法。也许您可以将您不希望 TestNG 运行的方法更改为非公开的
在我看来如下 代码挑战 (社区维基帖子):
如何能够执行“aGlobalGroup”组中扩展类的所有测试方法,而无需:
- 在扩展类本身上指定“aGlobalGroup”组?
- 测试扩展类的非注释公共方法?
第一个答案很简单:
在基类级别添加类 TestNG(groups = { "aGlobalGroup" })
该组将应用于基类和扩展类的所有公共方法。
但:即使非 testng 公共方法(没有 TestNG 注释)也将包含在该组中。
挑战:避免包含那些非 TestNG 方法。
@Test(groups = { "aGlobalGroup" })
public class Base {
/**
*
*/
@BeforeClass
public final void setUp() {
System.out.println("Base class: @BeforeClass");
}
/**
* Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
* Will be executed even if the TestNG class tested is a sub-class.
*/
@Test(groups = { "aLocalGroup" })
public final void aFastTest() {
System.out.println("Base class: Fast test");
}
/**
* Test not part a 'aGlobalGroup', but still included in that group due to the class annotation. <br />
* Will be executed even if the TestNG class tested is a sub-class.
*/
@Test(groups = { "aLocalGroup" })
public final void aSlowTest() {
System.out.println("Base class: Slow test");
//throw new IllegalArgumentException("oups");
}
/**
* Should not be executed. <br />
* Yet the global annotation Test on the class would include it in the TestNG methods...
*/
public final void notATest() {
System.out.println("Base class: NOT a test");
}
/**
* SubClass of a TestNG class. Some of its methods are TestNG methods, other are not. <br />
* The goal is to check if a group specify in the super-class will include methods of this class. <br />
* And to avoid including too much methods, such as public methods not intended to be TestNG methods.
* @author <a href="http://stackoverflow.com/users/6309/vonc">VonC</a>
*/
public static class Extended extends Base
{
/**
* Test not part a 'aGlobalGroup', but still included in that group due to the super-class annotation. <br />
* Will be executed even if the TestNG class tested is a sub-class.
*/
@Test
public final void anExtendedTest() {
System.out.println("Extended class: An Extended test");
}
/**
* Should not be executed. <br />
* Yet the global annotation Test on the class would include it in the TestNG methods...
*/
public final void notAnExtendedTest() {
System.out.println("Extended class: NOT an Extended test");
}
}
您可以在方法级别指定 @Test 注释,以实现最大的灵活性。
public class DBTestBase {
@BeforeTest(groups = "db-test")
public void beforeTest() {
System.out.println("Running before test");
}
public void method1() {
Assert.fail(); // this does not run. It does not belong to 'db-test' group.
}
@Test(groups = "db-test")
public void testMethod1() {
Assert.assertTrue(true);
}
}
这对你有用还是我从你的问题中遗漏了一些东西。