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"组。

相关推荐
Cc.Y3 小时前
Java零基础入门:字符串深度掌握——从基础API到StringBuilder性能优化
java·开发语言·性能优化
shuoshuohaohao7 小时前
MyBatis 小知识点
java·spring·mybatis
海上小飞龙7 小时前
【KMP算法-下篇】同一道题:Java 库函数 2600 微秒,手写 KMP 16 微秒
java·开发语言·算法
一条破秋裤8 小时前
Linux 共享内存通信:POSIX 共享内存与 mmap
linux·运维·服务器
谢亮_vipxieliang8 小时前
泛型擦除、通配符与 PECS 一次讲透
java·面试
贵州山魈羡民8 小时前
【玩转手机】通过 Podroid 上的 Alpine 部署 1Panel,把微型服务器装进口袋
运维·服务器
八解毒剂8 小时前
【计组】中央处理器CPU
java·开发语言·计算机组成原理
打工仔折腾 AI9 小时前
工业场景下时序库与实时计算一体化架构选型实践对比
java·开发语言·后端·python·性能优化·架构·ai agent 实战
ZealSinger10 小时前
Java虚拟线程上线后瓶颈转移到哪看三层
java·开发语言·firefox
2601_9611332810 小时前
盘立方软件指标文华期货公式下载
java