junit testng_您所有的测试都属于您:维护混合的JUnit 4 / JUnit 5和Testng / JUnit 5测试套件...

本文介绍了如何在Java项目中维护混合的JUnit 4 / JUnit 5和TestNG测试套件。当项目中存在不同版本的JUnit测试时,通过Apache Maven和Surefire插件,利用JUnit Vintage引擎可以运行JUnit 4测试。同时,文章提到了混合使用TestNG和JUnit 5的情况,可以通过显式指定测试引擎来解决。最后,文章强调了在迁移和更新测试框架时要注意确保所有测试套件都能正常执行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

junit testng

junit testng

如果您是经验丰富的Java开发人员,他从事测试驱动的开发(希望每个人都这样做),那么很有可能JUnit 4是您的一站式测试工具箱。 就我个人而言,我真的很喜欢它,但仍然喜欢它:简单,最少,非侵入性和直观。 连同出色的库(如AssertjHamcrest)一起,它使编写测试用例成为一种乐趣。

但是随着时间的流逝,Java作为一种语言已经发展了很多,但是JUnit 4并没有真正发展起来。 大约在2015年左右, JUnit 5的开发就开始了一个雄心勃勃的目标,即成为下一代针对Java和JVM的程序员友好测试框架。 而且,公平地说,我认为已经实现了这一目标:许多新项目从一开始就采用JUnit 5 ,而旧项目已经在迁移过程中(或至少正在考虑中)。

对于现有项目,向JUnit 5的迁移不会在一夜之间发生,可能会花费一些时间。 在今天的帖子中,我们将讨论借助Apache MavenApache Maven Surefire插件维护混合的JUnit 4 / JUnit 5TestNG / JUnit 5测试套件的方法。

为了使示例更真实一些,我们将测试一个UploadDestination类,该类基本上仅提供一个方法,该方法说明是否支持特定的目标方案:

 import java.net.URI;
 public class UploadDestination {

    public boolean supports(String location) {

        final String scheme = URI.create(location).getScheme();

        return scheme.equals( "http" ) || scheme.equals( ) || scheme.equals( "s3" ) || scheme.equals( ) || scheme.equals( "sftp" );

    }
 }

实现者非常友好,可以创建一套JUnit 4单元测试,以验证确实支持所有预期的目标方案。

 import static org.junit.Assert.assertTrue;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.junit.runners.Parameterized.Parameters;
 @RunWith (Parameterized. class )
 public class JUnit4TestCase {

    private UploadDestination destination;

    private final String location; 
    public JUnit4TestCase(String location) {

        this .location = location;

    }

    @Before

    public void setUp() {

        destination = new UploadDestination();

    }

    @Parameters (name= "{index}: location {0} is supported" )

    public static Object[] locations() {

        return new Object[] { "s3://test" , " http://host:9000 " , "sftp://host/tmp" };

    }

    @Test

    public void testLocationIsSupported() {

        assertTrue(destination.supports(location));

    }
 }

至少在项目构建中,至少需要将JUnit 4依赖项连同Apache Maven Surefire插件以及(可选) Apache Maven Surefire Reporter插件一起添加到pom.xml ,以下代码片段说明了这一点。

 < dependencies >

        < dependency >

            < groupId >junit</ groupId >

            < artifactId >junit</ artifactId >

            < version >4.13.1</ version >

            < scope >test</ scope >

        </ dependency >

    </ dependencies > 
    < build >

        < plugins >

            < plugin >

                < groupId >org.apache.maven.plugins</ groupId >

                < artifactId >maven-surefire-plugin</ artifactId >

                < version >3.0.0-M5</ version >

            </ plugin > 
            < plugin >

                < groupId >org.apache.maven.plugins</ groupId >

                < artifactId >maven-surefire-report-plugin</ artifactId >

                < version >3.0.0-M5</ version >

            </ plugin >

        </ plugins >

    </ build >

毫无疑问,触发Apache Maven构建通常每次都会运行所有单元测试套件。

 ...
 [INFO] -------------------------------------------------------
 [INFO] TESTS
 [INFO] -------------------------------------------------------
 [INFO] Running com.example.JUnit4TestCase
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0 , Time elapsed: 0.011 s - in com.example.JUnit4TestCase
 [INFO]
 [INFO] Results:
 [INFO]
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0
 [INFO]
 [INFO] ------------------------------------------------------------------------
 ...

太棒了,让我们想象一下,另一个队友正巧在该项目上工作,并注意到没有任何单元测试可以验证不支持的目标方案,因此她使用JUnit 5进行了添加。

 package com.example;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
 class JUnit5TestCase {

    private UploadDestination destination; 
    @BeforeEach

    void setUp() {

        destination = new UploadDestination();

    }

    @ParameterizedTest (name = "{index}: location {0} is supported" )

    @ValueSource (strings = { "s3a://test" , " https://host:9000 " , "ftp://host/tmp" } )

    public void testLocationIsNotSupported(String location) {

        assertFalse(destination.supports(location));

    }
 }

因此,另一个依赖项出现在项目的pom.xml中,以引入JUnit 5 (因为其API与JUnit 4不兼容)。

 < dependencies >

        < dependency >

            < groupId >org.junit.jupiter</ groupId >

            < artifactId >junit-jupiter</ artifactId >

            < version >5.7.0</ version >

            < scope >test</ scope >

        </ dependency >

    </ dependencies >

看起来很合法,不是吗? 但是有一个陷阱……这次的测试结果令人惊讶。

 ...
 [INFO] -------------------------------------------------------
 [INFO] TESTS
 [INFO] -------------------------------------------------------
 [INFO] Running com.example.JUnit5TestCase
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0 , Time elapsed: 0.076 s - in com.example.JUnit5TestCase
 [INFO]
 [INFO] Results:
 [INFO]
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0
 [INFO]
 [INFO] ------------------------------------------------------------------------
 ...

JUnit 4测试套件不见了, Apache Maven Surefire团队实际上在官方文档的“提供者选择”部分中很好地证明了这种行为。 那么我们如何才能让他们回来呢? 有几种可能的选择,但是到目前为止,最简单的选择是使用JUnit Vintage引擎,以便使用JUnit 5平台运行JUnit 4测试套件。

 < plugin >

                < groupId >org.apache.maven.plugins</ groupId >

                < artifactId >maven-surefire-plugin</ artifactId >

                < version >3.0.0-M5</ version >

                < dependencies >

                    < dependency >

                        < groupId >org.junit.vintage</ groupId >

                        < artifactId >junit-vintage-engine</ artifactId >

                        < version >5.7.0</ version >

                    </ dependency >

                </ dependencies >

            </ plugin >

这样, JUnit 4JUnit 5测试套件将同时执行。

 [INFO] -------------------------------------------------------
 [INFO] TESTS
 [INFO] -------------------------------------------------------
 [INFO] Running com.example.JUnit5TestCase
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0 , Time elapsed: 0.079 s - in com.example.JUnit5TestCase
 [INFO] Running com.example.JUnit4TestCase
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0 , Time elapsed: 0.009 s - in com.example.JUnit4TestCase
 [INFO]
 [INFO] Results:
 [INFO]
 [INFO] Tests run: 6 , Failures: 0 , Errors: 0 , Skipped: 0
 [INFO]
 [INFO] ------------------------------------------------------------------------

从这里可以学到的教训:请仔细观察所有测试套件是否正在执行(CI / CD通常会跟踪此类趋势并立即警告您)。 特别是,在迁移到最新的Spring BootApache Maven Surefire插件版本时,要格外小心。

您可能会遇到的另一个非常常见的用例是在一个项目范围内混合使用TestNGJUnit 5测试套件。 症状几乎相同,您会想知道为什么只运行JUnit 5测试套件。 这种情况下的处理方式略有不同,并且似乎效果很好的一种选择是显式枚举测试引擎提供者。

 < plugin >

                < groupId >org.apache.maven.plugins</ groupId >

                < artifactId >maven-surefire-plugin</ artifactId >

                < version >3.0.0-M5</ version >

                < dependencies >

                    < dependency >

                        < groupId >org.apache.maven.surefire</ groupId >

                        < artifactId >surefire-junit-platform</ artifactId >

                        < version >3.0.0-M5</ version >

                    </ dependency >

                    < dependency >

                        < groupId >org.apache.maven.surefire</ groupId >

                        < artifactId >surefire-testng</ artifactId >

                        < version >3.0.0-M5</ version >

                    </ dependency >

                </ dependencies >

            </ plugin >

在这种情况下,有些不希望的结果是测试套件是单独运行的(尽管还有其他方法可以尝试),例如:

 [INFO] -------------------------------------------------------
 [INFO] TESTS
 [INFO] -------------------------------------------------------
 [INFO] Running com.example.JUnit5TestCase
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0 , Time elapsed: 0.074 s - in com.example.JUnit5TestCase
 [INFO]
 [INFO] Results:
 [INFO]
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0
 [INFO]
 [INFO]
 [INFO] -------------------------------------------------------
 [INFO] TESTS
 [INFO] -------------------------------------------------------
 [INFO] Running TestSuite
 [INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0 , Time elapsed: 0.315 s - in TestSuite
 [INFO]
 [INFO] Results:
 [INFO]
 INFO] Tests run: 3 , Failures: 0 , Errors: 0 , Skipped: 0
 [INFO]
 [INFO]
 [INFO] ------------------------------------------------------------------------

公平地说,我认为JUnit 5是朝着为Java(通常是JVM)项目提供现代且简洁的测试套件迈出的一大步。 如今,几乎可以与任何其他测试框架或库( MockitoTestContainers …)进行无缝集成,并且在大多数情况下迁移路径并不那么困难。 另外,如您所见, JUnit 5与较早的测试引擎共存是完全可行的。

与往常一样,可以在Github上获得完整的项目示例: JUnit 4 / JUnit 5TestNG / JUnit 5

翻译自: https://www.javacodegeeks.com/2020/12/all-your-tests-belong-to-you-maintaining-mixed-junit-4-junit-5-and-testng-junit-5-test-suites.html

junit testng

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值