@BeforeMethod/@AfterMethod(onlyForGroups) 方法没有执行,如果执行属于这个组的测试方法

@BeforeMethod/@AfterMethod(onlyForGroups) methods did not execute, if a test method belonging to this group is executed

我是运行一个测试套件,其测试方法属于某个组。

Selenium代码如下:

public class BaseClass
{

    @BeforeMethod(onlyForGroups = {"P1"})
    public void bmeth1()
    {
        System.out.println("Before Method1 called");
    }

    @BeforeMethod(onlyForGroups = {"P2"})
    public void bmeth2()
    {
        System.out.println("Before Method2 called");
    }

    @BeforeMethod(onlyForGroups = {"P3"})
    public void bmeth3()
    {
        System.out.println("Before Method3 called");
    }

    @AfterMethod(onlyForGroups = {"P1"})
    public void ameth1()
    {
        System.out.println("After Method1 called");
    }

    @AfterMethod(onlyForGroups = {"P2"})
    public void ameth2()
    {
        System.out.println("After Method2 called");
    }

    @AfterMethod(onlyForGroups = {"P3"})
    public void ameth3()
    {
        System.out.println("After Method3 called");
    }

}

public class TC_003 extends BaseClass
{

    @Test(groups = {"P1"})
    public void tCase6()
    {
        System.out.println("Inside testcase 6");
    }

    @Test(groups = {"P2"})
    public void tCase7()
    {
        System.out.println("Inside testcase 7");
    }

    @Test(groups = {"P3"})
    public void tCase8()
    {
        System.out.println("Inside testcase 8");
    }

}

下面是 testng.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Suite" verbose="10">
<test name="Test1">
    <groups>
        <run>
            <include name=".*"/>
        </run>
    </groups>
    <classes>
        <class name="testing.TC_003"/>
    </classes>
</test>
</suite>

实际输出:

Inside testcase 6
Inside testcase 7
Inside testcase 8

预期输出:

Before Method1 called
Inside testcase 6
After Method1 called
Before Method2 called
Inside testcase 7
After Method2 called
Before Method3 called
Inside testcase 8
After Method3 called

测试方法执行了,但是@BeforeMethod/@AfterMethod没有执行。仅当我们在 testng.xml 文件中包含某些组时才会出现此问题。但是如果我们在 testng.xml 文件中排除某些组或者不使用组标签,那么它们将被执行。

按照建议 here, the current workaround is to use alwaysRun=true flag along with onlyForGroups flag. But if we apply this workaround, and if there is any SkipException in the preceding/parent config methods, then it is forced to execute the @BeforeMethod/@AfterMethod methods, even when the test method is going to be skipped. There is a similar issue logged here,当 preceding/parent 配置方法失败时。

我不确定这个正则表达式是否适用于所有组,因此请尝试删除这些行:

<groups>
    <run>
        <include name=".*"/>
    </run>
</groups>

下面是原post中提到的问题的解决方法:

如果我们只想执行某些组,那么我们可以排除那些我们不想执行的组,而不是对我们要执行的组使用include。
类似地,如果我们想要执行所有组,那么不要使用 <include name=".*"/>,而是使用排除并给出一些在您的测试套件中不存在的组名称,例如 <exclude name="unknown"/><exclude name=""/>
但请注意,在使用上述解决方法时,它还会包括 运行 所有不属于任何组的测试。因此,我们必须通过为所有那些我们认为不属于任何特定组的测试和配置方法分配默认组来应用另一种解决方法。

因此,如果我们应用上述解决方法,那么我们就不必应用原始 post 中提到的解决方法,即我们不必将 alwaysRun=true 标志与 [=14] 一起使用=].也就是说,我们可以用@BeforeMethod/@AfterMethod(onlyForGroups = {"P2"})代替@BeforeMethod/@AfterMethod(onlyForGroups = {"P2"}, alwaysRun=true)

请避免回答这个问题,因为我 crystal 不清楚组和 onlyForGroups 标志以及如何以及何时使用这些标志。因此,我建议使用 PDHide 给出的简单解决方案,因为它更清楚地解释了 groups 和 onlyForGroups 标志之间的区别以及如何以及何时使用它们。

如果将 onlyforgroups 更改为 groups 那么一切正常,这是一个有趣的观察:

但是当您的 testng.xml 中包含多个组时,提到的组中的所有前后方法都会在每个测试方法之前执行。所以为了避免这种情况,你必须将 groups 和 onlygroups 混合在一起

解释:

如果您没有在 testng xml 中指定组,则会调用所有方法。但是如果你提到组,那么只有那个特定组中的方法才会被执行。

这是因为如果你阅读组的定义:

https://testng.org/doc/documentation-main.html

groups The list of groups this class/method belongs to.

因此,如果您不提及该组或始终 运行 true,则不会调用该方法,因此您不会调用之前和之后的方法,因为它们不在任何组中

解决方法:

您可以将两者混合为:

package driversetup;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;



public class TestBaseClass  {
    

    @BeforeMethod(onlyForGroups = {"P1"},groups = {"P1"})
    public void bmeth1()
    {
        System.out.println("Before Method1 called");
    }

    @BeforeMethod(onlyForGroups = {"P2"},groups = {"P2"})
    public void bmeth2()
    {
        System.out.println("Before Method2 called");
    }

    @BeforeMethod(onlyForGroups = {"P3"},groups = {"P3"})
    public void bmeth3()
    {
        System.out.println("Before Method3 called");
    }

    @AfterMethod(onlyForGroups = {"P1"},groups = {"P1"})
    public void ameth1()
    {
        System.out.println("After Method1 called");
    }

    @AfterMethod(onlyForGroups = {"P2"},groups = {"P2"})
    public void ameth2()
    {
        System.out.println("After Method2 called");
    }

    @AfterMethod(onlyForGroups = {"P3"},groups = {"P3"})
    public void ameth3()
    {
        System.out.println("After Method3 called");
    }
    

}

或始终启用运行 true

package driversetup;

import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;



public class TestBaseClass {
    

    @BeforeMethod(onlyForGroups = {"P1"},alwaysRun = true)
    public void bmeth1()
    {
        System.out.println("Before Method1 called");
    }

    @BeforeMethod(onlyForGroups = {"P2"},alwaysRun = true)
    public void bmeth2()
    {
        System.out.println("Before Method2 called");
    }

    @BeforeMethod(onlyForGroups = {"P3"},alwaysRun = true)
    public void bmeth3()
    {
        System.out.println("Before Method3 called");
    }

    @AfterMethod(onlyForGroups = {"P1"},alwaysRun = true)
    public void ameth1()
    {
        System.out.println("After Method1 called");
    }

    @AfterMethod(onlyForGroups = {"P2"},alwaysRun = true)
    public void ameth2()
    {
        System.out.println("After Method2 called");
    }

    @AfterMethod(onlyForGroups = {"P3"},alwaysRun = true)
    public void ameth3()
    {
        System.out.println("After Method3 called");
    }
    

}

这确保调用前后方法,但仅针对正确的@test 方法执行