TestNG中的方法拦截器(重新排序测试方法)

在本文中,我们将讨论如何在TestNG中使用方法拦截器。TestNG按照方法名称的字母顺序运行我们的测试用例。如果TestNG已经决定了调用测试方法的顺序,那么我们可以将其分为两组:

  • 方法以特定的顺序运行因此,依赖方法将在依赖方法之前运行。
  • 该方法的运行顺序不特别为了给予更多的控制权,TestNG为我们提供了方法拦截器。
java 复制代码
public interface IMethodInterceptor extends ITestNGListener {
 
  List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context);
}

"intercept"方法是做什么的?它将在其参数中接受可以以任何顺序运行的方法列表,并返回类似的方法列表。

"intercept"方法返回什么?它将返回在其参数中传递的方法的类似列表,并且返回的列表可以是-

  • 我们在参数中接收到相同的列表,但顺序不同。
  • IMethodInstance方法的较小列表。
  • IMethodInstance方法的列表比参数中接收的方法的列表大。

让我们先拿一个测试类的例子,在这个类中我们将尝试使用方法拦截器来改变测试方法的顺序。

CodekruTest.java

java 复制代码
package Test;
 
import org.testng.Assert;
import org.testng.annotations.Test;
 
public class CodekruTest {
 
    @Test
    public void gammaMethod() {
        System.out.println("Executing gammaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test
    public void alphaMethod() {
        System.out.println("Executing alphaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test
    public void betaMethod() {
        System.out.println("Executing betaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test
    public void deltaMethod() {
        System.out.println("Executing deltaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
}

xml文件

html 复制代码
<suite name="codekru">
 
    <test name="codekruTest">
        <classes>
            <class name="Test.CodekruTest">
            </class>
        </classes>
    </test>
</suite>

运行结果:

Executing alphaMethod in CodekruTest class
Executing betaMethod in CodekruTest class
Executing deltaMethod in CodekruTest class
Executing gammaMethod in CodekruTest class
我们应该怎么做才能让一个特定的方法(比如说,本例中的deltaMethod)总是先运行?

因为我们想先运行一个特定的方法。我们可以通过多种方式来实现-

  • 通过为该方法分配优先级,使其始终首先运行。这很容易做到,但是这个类可能包含更多的测试方法,并且其他一些测试方法可能也需要一些优先级。如果我们将优先级作为一个非常负的值(比如-12345)传递,那么使用优先级执行方法是一个很好的方法。此值
  • 第二种方法是使用方法拦截器。方法拦截器提供了一个很好的接口来按照我们想要的顺序运行我们的测试。

下面是实现IMethodInterceptor接口并首先执行deltaMethod的类。

java 复制代码
package Test;
 
import java.util.ArrayList;
import java.util.List;
 
import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;
 
public class CodekruMethodInterceptor implements IMethodInterceptor {
 
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
        List<IMethodInstance> result = new ArrayList<IMethodInstance>();
        for (IMethodInstance m : methods) {
            if (m.getMethod().getMethodName().equalsIgnoreCase("deltaMethod")) {
                result.add(0, m);
            } else {
                result.add(m);
            }
 
        }
        return result;
    }
 
}

现在,我们必须将上面的类作为侦听器添加到XML文件中,如下所示。

html 复制代码
<suite name="codekru">
    <listeners>
        <listener class-name="Test.CodekruMethodInterceptor" />
    </listeners>
    <test name="codekruTest">
        <classes>
            <class name="Test.CodekruTest">
            </class>
        </classes>
    </test>
</suite>

运行XML结果:

bash 复制代码
Executing deltaMethod in CodekruTest class

Executing alphaMethod in CodekruTest class

Executing betaMethod in CodekruTest class 

Executing gammaMethod in CodekruTest class

让我们尝试在以特定顺序运行的方法上使用它(方法依赖于其他方法)。下面是我们的CodekruTest类,但我们已经修改了它,以按照特定的顺序运行方法。

java 复制代码
package Test;
 
import org.testng.Assert;
import org.testng.annotations.Test;
 
public class CodekruTest {
 
    @Test(dependsOnMethods = {"betaMethod"})
    public void gammaMethod() {
        System.out.println("Executing gammaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test
    public void alphaMethod() {
        System.out.println("Executing alphaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test(dependsOnMethods = {"alphaMethod"})
    public void betaMethod() {
        System.out.println("Executing betaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test(dependsOnMethods = {"gammaMethod"})
    public void deltaMethod() {
        System.out.println("Executing deltaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
}

现在,再次使用相同的XML文件。

XML 复制代码
<suite name="codekru">
    <listeners>
        <listener class-name="Test.CodekruMethodInterceptor" />
    </listeners>
    <test name="codekruTest">
        <classes>
            <class name="Test.CodekruTest">
            </class>
        </classes>
    </test>
</suite>

运行XML文件后的输出-

Executing alphaMethod in CodekruTest class
Executing betaMethod in CodekruTest class
Executing gammaMethod in CodekruTest class
Executing deltaMethod in CodekruTest class

我们可以看到,deltaMethod是在最后执行的,因为它依赖于另一个方法,而另一个方法又依赖于另一个方法。因此,在执行案件时遵循了这一命令。

如果我们想先运行一个特定的组呢?

我们将从TestNG文档中挑选代码,但在撰写本文时,TestNG文档中的代码中有一个小问题。所以,我们将在这里编写一个功能齐全的代码。

让我们再次使用CodekruTest类

java 复制代码
package Test;
 
import org.testng.Assert;
import org.testng.annotations.Test;
 
public class CodekruTest {
 
    @Test(groups = { "func" })
    public void gammaMethod() {
        System.out.println("Executing gammaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test
    public void alphaMethod() {
        System.out.println("Executing alphaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test(groups = { "func" })
    public void betaMethod() {
        System.out.println("Executing betaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
    @Test
    public void deltaMethod() {
        System.out.println("Executing deltaMethod in CodekruTest class");
        Assert.assertTrue(true);
    }
 
}

在这里,我们希望首先运行属于"func"组的方法,其余的方法应该在之后执行。下面是我们的方法拦截器代码。

java 复制代码
package Test;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
 
import org.testng.IMethodInstance;
import org.testng.IMethodInterceptor;
import org.testng.ITestContext;
import org.testng.annotations.Test;
 
public class CodekruMethodInterceptor implements IMethodInterceptor {
 
    public List<IMethodInstance> intercept(List<IMethodInstance> methods, ITestContext context) {
        List<IMethodInstance> result = new ArrayList<IMethodInstance>();
        for (IMethodInstance m : methods) {
            Test test = m.getMethod().getConstructorOrMethod().getMethod().getAnnotation(Test.class);
            Set<String> groups = new TreeSet<String>();
             
            for (String group : test.groups()) {
                groups.add(group);
            }
 
            // if group is "func", then put the method
            // at the first position in the list
            if (groups.contains("func")) {
                result.add(0, m);
            } else {
                result.add(m);
            }
        }
        return result;
 
    }
 
}

下面是用于执行CodekruTest类的XML,其中属于func的测试方法将首先执行。

XML 复制代码
<suite name="codekru">
    <listeners>
        <listener class-name="Test.CodekruMethodInterceptor" />
    </listeners>
    <test name="codekruTest">
        <classes>
            <class name="Test.CodekruTest">
            </class>
        </classes>
    </test>
</suite>

运行上述XML文件后的输出-

Executing gammaMethod in CodekruTest class
Executing betaMethod in CodekruTest class
Executing alphaMethod in CodekruTest class
Executing deltaMethod in CodekruTest class

这里我们可以看到gammaMethod和betaMethod首先被执行,因为它们属于"func"组。

相关推荐
这孩子叫逆几秒前
Spring Boot项目的创建与使用
java·spring boot·后端
星星法术嗲人4 分钟前
【Java】—— 集合框架:Collections工具类的使用
java·开发语言
一丝晨光23 分钟前
C++、Ruby和JavaScript
java·开发语言·javascript·c++·python·c·ruby
C++忠实粉丝24 分钟前
Linux环境基础开发工具使用(2)
linux·运维·服务器
天上掉下来个程小白25 分钟前
Stream流的中间方法
java·开发语言·windows
暮雪倾风32 分钟前
【WPF开发】控件介绍-Grid(网格布局)
windows·wpf
xujinwei_gingko36 分钟前
JAVA基础面试题汇总(持续更新)
java·开发语言
liuyang-neu38 分钟前
力扣 简单 110.平衡二叉树
java·算法·leetcode·深度优先
康熙38bdc1 小时前
Linux 环境变量
linux·运维·服务器
一丝晨光1 小时前
Java、PHP、ASP、JSP、Kotlin、.NET、Go
java·kotlin·go·php·.net·jsp·asp