Skip to content

Junit5测试套件

JUnit5测试套件

Suite套件

  • JUnit5通过@Suite注解使用套件
  • 不需要再声明@RunWith(JUnitPlatform.class)

pom.xml

对应依赖导入

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>11</java.version>
    <maven.compiler.version>3.3</maven.compiler.version>
    <maven.surefire.version>3.0.0-M5</maven.surefire.version>
    <junit.version>5.8.1</junit.version>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.junit</groupId>
            <artifactId>junit-bom</artifactId>
            <version>${junit.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>


    </dependencies>
</dependencyManagement>


<dependencies>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-suite</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>${maven.surefire.version}</version>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven.compiler.version}</version>
            <configuration>
                <encoding>UTF-8</encoding>
                <source>${java.version}</source>
                <target>${java.version}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

@Suite

  • 如果项目是从Junit4进行迁移,仍然需要@RunWith(JUnitPlatform.class)
  • 如果是一个全新的 JUnit5 项目,直接使用@Suite注解

@Suite
注解 作用
@Suite 放在类上的注解;是 JUnit5 平台的一个测试套件
@SelectClasses 过滤出需要执行的测试类
@SelectPackages 过滤出需要执行的测试包
@SuiteDisplayName 自定义 Suite 套件的显示名称
@IncludePackages @SelectPackages搭配,过滤出需要执行的测试包
@ExcludePackages @SelectPackages搭配,过滤出不需要执行的测试包
@IncludeClassNamePatterns @SelectPackages搭配,过滤出需要执行的测试类
@ExcludeClassNamePatterns @SelectPackages搭配,过滤出不需要执行的测试类
@IncludeTags @SelectPackages搭配,根据标签过滤出需要执行的测试方法
@ExcludeTags @SelectPackages搭配,根据标签过滤出不需要执行的测试方法

测试类准备

按照以下目录创建测试文件,方便后续测试。

project
│   README.md
│
│
└───class1
│   │   OneTest.java
│   │   TwoTest.java
│
└───class2
    │   OneTest.java
    │   TwoTest.java
    │   TreeTest.java
    │   TestFour.java
  • 结构如图所示

测试类准备-class1
package com.ceshiren.class1;


import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

public class OneTest {

    @Test
    @Tag("SuiteTag")
    @Tag("SuiteTag1")
    void test1(){
        System.out.println("com.class5.packageA-----OneTest");

    }

}
package com.ceshiren.class1;


import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

public class TwoTest {
    @Test
    @Tag("SuiteTag")
    void test1(){
        System.out.println("com.class5.packageA-----TwoTest");

    }
}

测试类准备-class2
package com.ceshiren.class2;


import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

public class OneTest {

    @Test
    @Tag("SuiteTag")
    @Tag("SuiteTag1")
    void test1(){
        System.out.println("com.class5.packageB-----OneTest");

    }
}
package com.ceshiren.class2;


import org.junit.jupiter.api.Test;

public class TwoTest {

    @Test
    void test1(){
        System.out.println("com.class5.packageB-----TwoTest");

    }
}

测试类准备-class2
package com.ceshiren.class2;


import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

public class TreeTest {
    @Test
    @Tag("SuiteTag1")
    void test1(){
        System.out.println("com.class5.packageB-----TreeTest1");

    }
}
package com.ceshiren.class2;


import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

public class TestFour {

    @Test
    @Tag("SuiteTag1")
    void test1(){
        System.out.println("com.class5.packageB-----TestFour");

    }

    @Test
    void test2(){
        System.out.println("com.class5.packageB-----TestFour---test2");

    }
    @Test
    void test3(){
        System.out.println("com.class5.packageB-----TestFour---test3");

    }
    @Test
    void test4(){
        System.out.println("com.class5.packageB-----TestFour---test4");

    }
}

测试套件组合

在 JUnit5 中,可以使用 @Suite 注解来创建测试套件组合。测试套件组合允许将不同的测试套件组合在一起,并作为一个整体运行。

执行单个测试类
  • @Suite+@SelectClasses
  • 过滤出需要执行的单个测试类
  • 在 class1 和 class2 包中均有 OneTest.class 文件,在使用@SelectClasses 直接选择需要执行的文件时会默认导入测试文件,需要检查一下是否是我们需要执行的测试文件,再使用测试套件过滤,这样就可以执行单个测试类。
package com.ceshiren.testcases;


import com.ceshiren.class1.OneTest;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;
//测试套件基本注解
@Suite
//选择需要执行的测试类 参数:OneTest.class
@SelectClasses(OneTest.class )
public class RunSuite01Test {
}
  • 执行结果

执行多个测试类
  • @Suite+@SelectClasses
  • 过滤出需要执行的多个测试类
  • 与执行单个测试类使用的测试套件相同,但在选择测试类是,需要写成集合的形式,{OneTest.class,TwoTest.class} ,使用@SelectClasses 直接选择需要执行的文件时会默认导入测试文件,如果文件中存在重名则需要检查是否是我们期望执行的文件,class1、class2 中均有 OneTest、TwoTest 文件,这里执行 class1 中的 Onetest 和 class2 中的 Twotest。
package com.ceshiren.testcases;

import com.ceshiren.class1.OneTest;
import com.ceshiren.class2.TwoTest;
import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;

@Suite
//选择需要执行的测试类
//参数类型为集合:{OneTest.class,TwoTest.class}
//如果文件存在重名的情况需要检查导入的文件是否预期的文件
@SelectClasses({
        OneTest.class,
        TwoTest.class
})
class RunSuite02Test {
}
  • 从执行结果可以看到我们成功执行了 class1 中的 Onetest 和 class2 中的 Twotest,成功使用测试套件执行多个测试类

执行单个测试包
  • 如果需要执行单个测试包下的所有文件,可以使用@Suite@SelectPackages的组合过滤出需要执行的单个测试包
  • @Suite+@SelectPackages
package com.ceshiren.testcases;

import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;

@Suite
//选择需要执行的测试包,括号中输入包名
//参数类型为String:com.ceshiren.class1
@SelectPackages("com.ceshiren.class1")
public class RunSuite03Test {
}
  • 执行单个测试包结果,成功执行 class1 中所有的测试文件。

执行多个测试包
  • 与执行单个测试包使用的注解相同,但括号中的包名需要以列表的形式书写,{ "com.ceshiren.class1", "com.ceshiren.class2" }过滤出需要执行的多个测试包
  • @Suite+@SelectPackages
  • 代码示例
package com.ceshiren.testcases;

import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;

@Suite
//选择需要执行的测试包
//参数类型为集合:{"com.ceshiren.class1","com.ceshiren.class2"}
//
@SelectPackages({
        "com.ceshiren.class1",
        "com.ceshiren.class2"
})
public class RunSuite04Test {
}
  • 成功执行 class1 和 class2 下的所有测试文件。

自定义Suite套件的显示名称

默认情况下,使用 @Suite 注解创建的测试套件将显示为类名。但是,有时候我们可能希望为测试套件指定一个自定义的显示名称。

  • @Suite+@SuiteDisplayName+*
package com.ceshiren.testcases;

import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
import org.junit.platform.suite.api.SuiteDisplayName;

@Suite
//对应测试套件显示的名称是Test Suite
@SuiteDisplayName("Test Suite")
@SelectPackages({
        "com.ceshiren.class1",
        "com.ceshiren.class2"
})
public class RunSuite05Test {
}

问题 不显示自定义的显示名称


过滤需执行的测试包

在某些情况下,可能希望只执行特定的测试包,而忽略其他测试包。这种情况下,过滤需执行的测试包将会派上用场。

  • @Suite+@SelectPackages+@IncludePackages
  • 过滤需执行的测试包
package com.ceshiren.testcases;

import org.junit.platform.suite.api.IncludePackages;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
import org.junit.platform.suite.api.SuiteDisplayName;

@Suite
//使用@SelectPackages注解选择需要执行的包
@SelectPackages({
        "com.ceshiren"
})
//对应的满足SelectPackages的包名
//参数类型 String :"com.ceshiren.class1"
//选择包中需要执行的文件,如下,代表执行"com.ceshiren"包中的class1包下的文件
@IncludePackages("com.ceshiren.class1")
public class RunSuite06Test {
}
  • 使用@Suite+@SelectPackages+@IncludePackages套件组合过滤掉不希望执行的文件,如图,我们只执行了 class1 下的文件,过滤了 class2 中的文件

过滤不需要执行的测试包

  • 当我们需要执行的包中包含少数包不希望执行,我们使用@IncludePackages 注解未免会有些麻烦,这时我们只需要用到@ExcludePackages 注解过滤不需要执行的包即可。
  • @Suite+@SelectPackages+@ExcludePackages
  • 过滤不需要执行的测试包
package com.ceshiren.testcases;

import org.junit.platform.suite.api.ExcludePackages;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;
import org.junit.platform.suite.api.SuiteDisplayName;


@Suite
@SelectPackages("com.ceshiren")
//满足SelectPackages下的包且不执行"com.ceshiren.class1"、"com.ceshiren.testcases"下的所有类
//参数是以列表的形式
@ExcludePackages({
        "com.ceshiren.class1",
        "com.ceshiren.testcases"//包中包含Suite套件,不可执行
})
public class RunSuite07Test {
}
  • 我们使用组合套间规定执行满足 SelectPackages 下的包且不执行"com.ceshiren.class1"、"com.ceshiren.testcases"下的所有类,从执行结果可以看出我们只执行了 class2 包下的类

正则匹配Test

  • 当我们需要执行包中某些特定命名格式的文件时,可以使用正则表达式进行匹配操作,相应的 class 将会执行
  • @Suite+@SelectPackages+@IncludeClassNamePatterns
package com.ceshiren.testcases;

import org.junit.platform.suite.api.*;

@Suite
@SuiteDisplayName("Test Suite08")
@SelectPackages({
        "com"
})
//对应正则表达式匹配执行的相关class
//参数类型为集合:{"com.ceshiren.class2.*Test"}
@IncludeClassNamePatterns({
        "com.ceshiren.class2.*Test"
//        "com.ceshiren.class2.*"
})
public class RunSuite08Test {
}
  • 在满足条件的包中过滤符合以 Test 结尾的文件名的文件执行,如 class2 中 TestFour 文件不符合以 Test 结尾,则不会执行。

正则匹配Test不被执行

  • @IncludeClassNamePatterns相对,不希望执行某些特定的文件时,使用@ExcludeClassNamePatterns进行正则匹配,对应的 class 将不会被执行
  • @Suite+@SelectPackages+ @ExcludeClassNamePatterns
package com.ceshiren.testcases;

import org.junit.platform.suite.api.*;

@Suite
@SuiteDisplayName("Test Suite09")
@SelectPackages({
        "com.ceshiren.class2"
})
//对应正则表达式匹配不被执行的相关class
//参数类型为集合:{"com.ceshiren.class2.*Test$"}
@ExcludeClassNamePatterns("com.ceshiren.class2.*Test$")
public class RunSuite09Test {
}
  • 使用@ExcludeClassNamePatterns 注解,在满足条件的包中过滤符合以 Test 结尾的文件名的文件将不会执行,如 class2 中只有 TestFour 文件不符合以 Test 结尾,所以会只执行 TestFour 文件。

执行包内的标签

  • 这里包内包含标签的方法和类都会执行,
  • @Suite+@SelectPackages+@IncludeTags
  • 执行包内包含标签的方法或者类
package com.ceshiren.testcases;

import org.junit.platform.suite.api.*;

@Suite
@SelectPackages({
        "com.ceshiren.class2"
})
//对应包含的标签
//参数可以是单个标签:"SuiteTag"
//参数是集合:{"SuiteTag1","SuiteTag"}
@IncludeTags({
//        "SuiteTag"
        "SuiteTag1"
})
public class RunSuite10Test {
}
  • class2 包中包含SuiteTag标签的仅有 OneTest,从结果也可以看出只执行了 OneTest 文件。

不执行包内标签的方法/类

  • @Suite+@SelectPackages+@ExcludeTags
  • 不执行包内标签的方法/类
package com.ceshiren.testcases;

import org.junit.platform.suite.api.*;

@Suite
@SelectPackages({
        "com.ceshiren.class2"
})
//对应不执行包含的标签
//参数是集合:{"SuiteTag1"}
@ExcludeTags({
        "SuiteTag1"
})
public class RunSuite11Test {
}
  • 在对 class2 包中的文件过滤后仅有 TwoTest 文件和 TestFour 中的部分方法没有"SuiteTag1"标签。