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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 10:44:30  来源:igfitidea点击:

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

javatestng

提问by Mike Stone

I have a base class that represents a database test in TestNG, and I want to specify that all classes extending from this class are of a group "db-test", however I have found that this doesn't seem possible. I have tried the @Test annotation:

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

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

However, this doesn't work because the @Test annotation will try to make a bunch of methods into tests, and warnings/errors pop up in eclipse when the tests are run.

但是,这不起作用,因为@Test 注释会尝试将一堆方法放入测试中,并且在运行测试时会在 Eclipse 中弹出警告/错误。

So I tried disabling the test, so at least the groups are assigned:

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

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

but then any @BeforeTest (and other similar annotations) ALSO get disabled... which is of course not what I want.

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

I would like some way to annotate a class as being of a particular type of group, but it doesn't quite seem possible in TestNG. Does anyone have any other ideas?

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

采纳答案by VonC

The answer is through a custom org.testng.IMethodSelector:

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

Its includeMethod()can exclude any method we want, like a public not-annotated method.

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

However, to register a custom JavaMethodSelector, you must add it to the XMLTestinstance managed by any TestRunner, which means you need your own custom TestRunner.

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

But, to build a custom TestRunner, you need to register a TestRunnerFactory, through the -testrunfactoryoption.

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

BUT that -testrunfactory is NEVER taken into account by TestNGclass... so you need also to define a custom TestNG class :

但是 -testrunfactory 从未被TestNG类考虑在内......所以你还需要定义一个自定义的 TestNG 类:

  • in order to override the configure(Map) method,
  • so you can actually set the TestRunnerFactory
  • TestRunnerFactory which will build you a custom TestRunner,
  • TestRunner which will set to the XMLTest instance a custom XMLMethodSelector
  • XMLMethodSelector which will build a custom IMethodSelector
  • IMethodSelector which will exclude any TestNG methods of your choosing!
  • 为了覆盖 configure(Map) 方法,
  • 所以你实际上可以设置 TestRunnerFactory
  • TestRunnerFactory 它将为您构建一个自定义的 TestRunner,
  • TestRunner 将自定义 XMLMethodSelector 设置为 XMLTest 实例
  • XMLMethodSelector 将构建自定义 IMethodSelector
  • IMethodSelector 将排除您选择的任何 TestNG 方法!

Ok... it's a nightmare. But it is also a code-challenge, so it must be a little challenging ;)

好吧……这是一场噩梦。但这也是一个代码挑战,所以一定有点挑战;)

All the code is available at DZone snippets.

所有代码都可以在DZone 片段中找到

As usual for a code challenge:

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

  • one java class (and quite a few inner classes)
  • copy-paste the class in a 'source/test' directory (since the package is 'test')
  • run it (no arguments needed)
  • 一个 java 类(和相当多的内部类)
  • 将类复制粘贴到“源/测试”目录中(因为包是“测试”)
  • 运行它(不需要参数)


Update from Mike Stone:

迈克·斯通的更新:

I'm going to accept this because it sounds pretty close to what I ended up doing, but I figured I would add what I did as well.

我将接受这一点,因为这听起来与我最终所做的非常接近,但我想我也会添加我所做的。

Basically, I created a Groups annotation that behaves like the groups property of the Test (and other) annotations.

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

Then, I created a GroupsAnnotationTransformer, which uses IAnnotationTransformer to look at all tests and test classes being defined, then modifies the test to add the groups, which works perfectly with group exclusion and inclusion.

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

Modify the build to use the new annotation transformer, and it all works perfectly!

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

Well... the one caveat is that it doesn't add the groups to non-test methods... because at the time I did this, there was another annotation transformer that lets you transform ANYTHING, but it somehow wasn't included in the TestNG I was using for some reason... so it is a good idea to make your before/after annotated methods to alwaysRun=true... which is sufficient for me.

嗯......一个警告是它不会将组添加到非测试方法......因为在我这样做的时候,还有另一个注释转换器可以让你转换任何东西,但不知何故它没有被包括在内在 TestNG 中,我出于某种原因使用了......所以将你的前/后注释方法设置为 alwaysRun=true 是个好主意......这对我来说已经足够了。

The end result is I can do:

最终结果是我可以做到:

@Groups({ "myGroup1", "myGroup2"})
public class MyTestCase {
    @Test
    @Groups("aMethodLevelGroup")
    public void myTest() {
    }
}

And I made the transformer work with subclassing and everything.

我让转换器与子类化和所有东西一起工作。

回答by Alejandro Bologna

TestNG will run all the public methods from a class with a @Test annotation. Maybe you could change the methods you don't want TestNG to run to be non-public

TestNG 将运行带有 @Test 注释的类中的所有公共方法。也许您可以将您不希望 TestNG 运行的方法更改为非公开

回答by VonC

It would seem to me as the following code-challenge(community wiki post):

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

How to be able to execute all test methods of Extended class from the group 'aGlobalGroup' without:

如何能够从组“aGlobalGroup”执行扩展类的所有测试方法,而无需:

  • specifying the 'aGlobalGroup' group on the Extended class itself ?
  • testing non-annotated public methods of Extended class ?
  • 在扩展类本身上指定“aGlobalGroup”组?
  • 测试扩展类的非注释公共方法?

The first answer is easy:
add a class TestNG(groups = { "aGlobalGroup" }) on the Base class level

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

That group will apply to all public methods of both Base class and Extended class.

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

BUT: even non-testng public methods (with no TestNG annotation) will be included in that group.

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

CHALLENGE: avoid including those non-TestNG methods.

挑战:避免包含那些非 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");
        }
    }

回答by Sam Merrell

I'm not sure how the annotation inheritance works for TestNG but this articlemay be of some use.

我不确定注释继承对 TestNG 是如何工作的,但这篇文章可能会有一些用处。

Actually, this may help better, look at inheritGroups.

实际上,这可能会更好,看看inheritGroups。

回答by Jorge Ferreira

You can specify the @Test annotation at method level that allows for maximum flexibility.

您可以在允许最大灵活性的方法级别指定 @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);
    }
}

Does this works for you or I am missing something from your question.

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