首页 > 解决方案 > @BeforeMethod/@AfterMethod(onlyForGroups) 方法没有执行,如果属于该组的测试方法被执行

问题描述

我正在使用属于特定组的测试方法运行一个测试套件。

下面是硒代码:

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 文件中排除某些组或不使用组标签,那么它们就会被执行。

正如这里所建议的,当前的解决方法是使用 alwaysRun=true 标志和 onlyForGroups 标志。但是如果我们应用这个变通方法,并且如果前面/父配置方法中有任何 SkipException,那么即使要跳过测试方法,也会强制执行 @BeforeMethod/@AfterMethod 方法。当前面的/父配置方法失败时,此处记录了类似的问题。

标签: javaseleniumselenium-webdrivertestng

解决方案


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

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

解释:

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

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

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

groups 该类/方法所属的组列表。

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

解决方法:

您可以将两者混合为:

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

}

这样可以确保调用 before 和 after 方法,但仅针对正确的 @test 方法执行


推荐阅读