1. 概述

通常情况下,我们会在Maven构建过程中使用Maven surefire插件执行测试。

本教程将探讨如何使用此插件来运行单个测试类或测试方法。

2. 问题介绍

Maven surefire插件易于使用,它只有一个目标:test

因此,使用默认配置,只需通过命令mvn test,即可执行项目中的所有测试。

有时,我们可能希望只执行一个单独的测试类,甚至是一个单独的测试方法。在本教程中,我们将以JUnit 5为例,说明如何实现这一点。

3. 示例项目

为了更直观地展示测试结果,让我们创建几个简单的测试类:

class TheFirstUnitTest {

    // declaring logger ... 

    @Test
    void whenTestCase_thenPass() {
        logger.info("Running a dummyTest");
    }
}

class TheSecondUnitTest {

    // declaring logger ... 

    @Test
    void whenTestCase1_thenPrintTest1_1() {
        logger.info("Running When Case1: test1_1");
    }

    @Test
    void whenTestCase1_thenPrintTest1_2() {
        logger.info("Running When Case1: test1_2");
    }

    @Test
    void whenTestCase1_thenPrintTest1_3() {
        logger.info("Running When Case1: test1_3");
    }

    @Test
    void whenTestCase2_thenPrintTest2_1() {
        logger.info("Running When Case2: test2_1");
    }
}

TheFirstUnitTest类中,我们只有一个测试方法。而TheSecondUnitTest类包含四个测试方法。所有方法名都遵循“*when...then...*”模式。

为了简单起见,我们在每个测试方法中添加了一行输出,以指示方法正在被调用。

现在如果我们运行mvn test,所有测试都会被执行:

$ mvn test
...
[INFO] Scanning for projects...
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.baeldung.runasingletest.TheSecondUnitTest
16:58:16.444 [main] INFO ...TheSecondUnitTest - Running When Case2: test2_1
16:58:16.448 [main] INFO ...TheSecondUnitTest - Running When Case1: test1_1
16:58:16.449 [main] INFO ...TheSecondUnitTest - Running When Case1: test1_2
16:58:16.450 [main] INFO ...TheSecondUnitTest - Running When Case1: test1_3
[INFO] Tests run: 4, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.065 s - in com.baeldung.runasingletest.TheSecondUnitTest
[INFO] Running com.baeldung.runasingletest.TheFirstUnitTest
16:58:16.453 [main] INFO ...TheFirstUnitTest - Running a dummyTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0 s - in com.baeldung.runasingletest.TheFirstUnitTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
 ...

接下来,我们将告诉Maven只执行指定的测试。

4. 执行单个测试类

Maven surefire插件提供了一个test参数,我们可以使用它来指定想要执行的测试类或方法。

如果要执行单个测试类,可以在mvn命令中使用-Dtest="TestClassName"

例如,我们可以传递-Dtest="TheFirstUnitTest"命令来仅执行TheFirstUnitTest类:

$ mvn test -Dtest="TheFirstUnitTest"
...
[INFO] Scanning for projects...
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.baeldung.runasingletest.TheFirstUnitTest
17:10:35.351 [main] INFO com.baeldung.runasingletest.TheFirstUnitTest - Running a dummyTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.053 s - in com.baeldung.runasingletest.TheFirstUnitTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
 ...

如输出所示,只有传递给test参数的测试类会被执行。

5. 执行单个测试方法

此外,我们还可以通过在mvn命令中传递-Dtest="TestClassName#TestMethodName"来请求Maven surefire插件执行单个测试方法。

现在让我们执行TheSecondUnitTest类中的whenTestCase2_thenPrintTest2_1()方法:

$ mvn test -Dtest="TheSecondUnitTest#whenTestCase2_thenPrintTest2_1"    
...
[INFO] Scanning for projects...
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.baeldung.runasingletest.TheSecondUnitTest
17:22:07.063 [main] INFO ...TheSecondUnitTest - Running When Case2: test2_1
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.057 s - in com.baeldung.runasingletest.TheSecondUnitTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
...

正如我们所见,这次我们只执行了指定的测试方法。

6. 关于test参数的更多内容

到目前为止,我们已经展示了如何通过提供相应的test参数值来执行单个测试类或测试方法。

实际上,Maven surefire插件允许我们以不同的格式设置test参数,以便灵活地执行测试。

接下来,我们将展示一些常用的格式:

  • 通过名称执行多个测试类:-Dtest="TestClassName1, TestClassName2, TestClassName3..."
  • 通过名称模式执行多个测试类:-Dtest="*ServiceUnitTest"\-Dtest="The*UnitTest, Controller*Test"
  • 指定多个测试方法名称:-Dtest="ClassName#method1+method2"
  • 指定多个方法名称的名称模式:-Dtest="ClassName#whenSomethingHappens_*"

最后,让我们看一个例子。假设我们只想执行TheSecondUnitTest类中所有名为“*whenTestCase1...*”的方法。根据我们之前讨论的模式,我们希望-Dtest="TheSecondUnitTest#whenTestCase1*"可以完成这个任务:

$ mvn test -Dtest="TheSecondUnitTest#whenTestCase1*"
...
[INFO] Scanning for projects...
...
[INFO] -------------------------------------------------------
[INFO]  T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.baeldung.runasingletest.TheSecondUnitTest
17:51:04.973 [main] INFO ...TheSecondUnitTest - Running When Case1: test1_1
17:51:04.979 [main] INFO ...TheSecondUnitTest - Running When Case1: test1_2
17:51:04.980 [main] INFO ...TheSecondUnitTest - Running When Case1: test1_3
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 s - in com.baeldung.runasingletest.TheSecondUnitTest
[INFO] 
[INFO] Results:
[INFO] 
[INFO] Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] 
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
...

正如预期的那样,只有匹配指定名称模式的三个测试方法被执行。

7. 总结

Maven surefire插件提供了test参数,使我们在选择要执行的测试时具有很大的灵活性。

在这篇文章中,我们讨论了test参数的一些常用值格式,并通过示例说明了如何使用Maven仅执行指定的测试类或测试方法。

如往常一样,文章的代码可以在GitHub上找到。