关于java:我可以在TestNG测试用例上指定类范围的组吗?

关于java:我可以在TestNG测试用例上指定类范围的组吗?

Can I specify a class wide group on a TestNG test case?

我有一个基类,它表示TestNG中的数据库测试,我想指定所有从该类扩展的类都属于" db-test"组,但是我发现这似乎是不可能的。 我尝试了@Test批注:

1
2
3
@Test(groups = {"db-test" })
public class DBTestBase {
}

但是,这是行不通的,因为@Test批注将尝试将一堆方法纳入测试,并且在运行测试时会在eclipse中弹出警告/错误。

所以我尝试禁用测试,因此至少分配了组:

1
2
3
@Test(enabled = false, groups = {"db-test" })
public class DBTestBase {
}

但是然后任何@BeforeTest(和其他类似的注释)也被禁用了……这当然不是我想要的。

我想以某种方式将类注释为特定类型的组,但在TestNG中似乎不太可能。 还有其他想法吗?


TestNG将使用@Test批注运行类中的所有公共方法。也许您可以更改不想让TestNG运行为非公开的方法


答案是通过自定义的org.testng.IMethodSelector:

它的includeMethod()可以排除我们想要的任何方法,例如公共未注释的方法。

但是,要注册自定义Java MethodSelector,必须将其添加到任何TestRunner管理的XMLTest实例中,这意味着您需要自己的自定义TestRunner。

但是,要构建自定义的TestRunner,您需要通过-testrunfactory选项注册一个TestRunnerFactory。

但是TestNG类从不考虑-testrunfactory ...因此,您还需要定义一个自定义TestNG类:

  • 为了覆盖configure(Map)方法,
  • 因此您实际上可以设置TestRunnerFactory
  • TestRunnerFactory将为您构建自定义TestRunner,
  • TestRunner,它将为XMLTest实例设置自定义XMLMethodSelector
  • XMLMethodSelector将构建自定义IMethodSelector
  • IMethodSelector将排除您选择的任何TestNG方法!

好吧...这是一场噩梦。但这也是一个代码挑战,因此它必须具有一定的挑战性;)

DZone片段中提供了所有代码。

像往常一样进行代码挑战:

  • 一个Java类(以及很多内部类)
  • 将类复制并粘贴到"源/测试"目录中(因为软件包为"测试")
  • 运行它(不需要任何参数)

来自Mike Stone的更新:

我将接受这一点,因为这听起来与我最终要完成的工作非常接近,但是我认为我也会补充我所做的事情。

基本上,我创建了一个Groups批注,其行为类似于Test(和其他)批注的groups属性。

然后,我创建了一个GroupsAnnotationTransformer,它使用IAnnotationTransformer查看所有测试和定义的测试类,然后修改测试以添加组,这与组排除和包含完美配合。

修改构建以使用新的注释转换器,一切都可以完美运行!

好吧...一个警告是,它没有将组添加到非测试方法中...因为在我这样做的时候,还有一个注释转换器可以让您转换任何内容,但是不包括在内在我出于某种原因使用的TestNG中...因此,使您之前/之后的注释方法始终运行为true是一个好主意...这对我来说已经足够了。

最终结果是我可以做到:

1
2
3
4
5
6
7
@Groups({"myGroup1","myGroup2"})
public class MyTestCase {
    @Test
    @Groups("aMethodLevelGroup")
    public void myTest() {
    }
}

然后,我使变压器能够处理子类化和所有工作。


在我看来,这是以下代码挑战(社区Wiki帖子):

如何在不使用" aGlobalGroup"组的情况下执行扩展类的所有测试方法:

  • 在扩展类本身上指定'aGlobalGroup'组?
  • 测试扩展类的非注释公共方法?

第一个答案很简单:
在基类级别上添加一个类TestNG(groups = {" aGlobalGroup"})

该组将适用于Base类和Extended类的所有公共方法。

但是:即使是非testng的公共方法(没有TestNG注释)也将包括在该组中。

挑战:避免包括那些非TestNG方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
@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 VonC
     */

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

我不确定TestNG的注释继承如何工作,但是本文可能会有所帮助。

实际上,这可能会更好,请看一下InheritGroups。


您可以在方法级别指定@Test批注,以实现最大的灵活性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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);
    }
}

这对您有用吗,或者我从您的问题中遗漏了一些东西。


推荐阅读