写点什么

Jakarta EE 项目的现代化测试实践

作者:Otavio Santana

  • 2024-05-15
    北京
  • 本文字数:7116 字

    阅读完需:约 23 分钟

大小:2.75M时长:16:00
Jakarta EE项目的现代化测试实践

在动态的软件开发世界中,开源项目的重要性怎么强调也不为过。这些协作成果推动了创新,并为技术领域的质量和持续性建立了基准。很多长期项目,例如已开源发布二十多年的 Java,还有 Jakarta EE 规范及其实现,都体现了开源计划的影响。

 

这些项目提供了很多宝贵的见解和方法,可以很容易地应用于各种企业环境,充分体现了强大的文档和测试文化的重要性。

 

本文旨在深入探讨一些最新规范中所采用的一系列测试程序和工具,重点关注数据驱动的测试方法。通过研究这些方法,我们试图找出确保开源项目质量、可靠性和长寿的秘诀。我们将探索不断发展的软件开发领域中测试实践的复杂性,并探究如何利用这些原则来提高企业项目的质量。

 

我们将专注于目前正在发展的两个最新规范:Jakarta DataJakarta NoSQL。这些新兴规范代表了 Jakarta EE 生态系统中的创新工作,并有望重新定义 Java 企业级应用程序与数据的交互方式。

 

Jakarta Data 是 Jakarta EE 家族的最新成员之一,它定义了一组核心 API,旨在帮助开发人员构建 Jakarta EE 应用程序,并轻松访问各种数据技术。

 

此规范使开发人员能够利用关系和非关系数据库、基于云的数据服务和其他数据技术的优势。 其目标是在 Jakarta EE 应用程序中培养一种更灵活、适应性更强的数据管理方法。

 

@Repository 注释是 Jakarta Data 的重要组成部分,因为它提供了存储库接口。 此接口在你的域和数据库之间提供了简单的连接,允许你以域为中心的方式访问多个数据库。



图 1:Jakarta Data 表示

 

同样,Jakarta NoSQL 代表了 Jakarta EE 演进的又一步。此规范和 Jakarta Data 为开发人员提供了一种将 Java 应用程序与 NoSQL 数据库集成的标准化方法。

 

我们的研究将围绕这两个规范及其实现,主要通过 Eclipse JNoSQL 的视角来展开。我们的目标是揭示它们如何为 Jakarta EE 项目中以数据为中心的测试方法铺平道路。通过探索数据驱动的测试原则,我们将深入解析那些确保 Jakarta EE 项目的质量、可靠性和寿命的复杂性。通过关注 Jakarta EE 的最新进展及其对测试方法的潜在影响,我们努力为开发人员和企业提供在不断发展的软件开发领域持续进步所需的知识和工具。



图 2:Eclipse JNoSQL 插图,说明了使用这两个规范,我们可以在 NoSQL 数据库之间切换

 

现在,我们已经为全面探索 Jakarta Data 和 Jakarta NoSQL 规范做好了准备,我们将深入研究这些规范如何改进 Jakarta EE 项目中的测试方法。我们将重点介绍作为我们实现平台的 Eclipse JNoSQL 。在下一节中,我们将开始一段对测试实践进行现代化的旅程,介绍应用于 Jakarta Data 和 Jakarta NoSQL 项目的具体步骤。

测试方法

在本节中,我们将探讨增强 Jakarta EE 项目中测试方法的六个基本步骤,它们用来确保整个开发过程中的稳健性和可靠性。这些步骤旨在使 Jakarta Data 和 Jakarta NoSQL 项目与当代软件工程的需求保持一致:

 

  1. 测试指南:通过文档建立清晰全面的测试程序,指导项目贡献者采用统一的测试方法。

  2. 现代测试库:采用 JUnit Jupiter 和 AssertJ 等高级库来简化测试流程、增强代码可读性并提高整体测试效率。

  3. 数据驱动方法:采用数据驱动方法进行测试,探索各种数据集以发现 Jakarta EE 项目中的潜在问题和极端情况。

  4. 丰富的断言:利用各种断言库全面验证代码行为,确保 Jakarta EE 应用程序符合严格的质量标准。

  5. 扩展覆盖范围:使用 PITest、JaCoCo 或 Cobertura 等工具扩大测试覆盖范围。这将使 Jakarta EE 项目开发人员能够评估其测试的有效性并找出需要改进的领域。

  6. 用于测试的容器:利用容器创建和管理隔离的测试环境,确保 Jakarta EE 应用程序的测试条件是一致且可重复的。

 

采用这六个步骤后,开发人员可以改进他们在 Jakarta EE 项目中的测试实践,确保他们的应用程序在不断变化的软件需求面前保持稳健性、可靠性和弹性。

 

下面让我们深入研究每个步骤,并揭示它们如何帮助 Jakarta EE 项目取得成功。



图 3:在 Jakarta EE 项目中增强测试方法的步骤

 

在测试的第一步中,起点是文档:它是充当罗盘的一份测试指南,引导所有项目贡献者朝着质量和可靠性的共同愿景前进。它封装了一组最佳实践和方法,用于管理测试程序来确保整个项目的一致性和有效性。

 

在 Jakarta JNoSQL 和 Jakarta Data 项目中,这些测试指南塑造了项目的测试文化,并构建了对质量的承诺。它们的内容包括:

 

  • 要使用的工具:定义的测试集和相关工具,以简化测试流程并确保贡献之间的一致性。

  • 命名约定:测试类、方法、描述和结构的命名约定一致性可增强测试的可读性和可维护性。

  • 具体的测试创建方法:测试创建方法指南(例如软断言和扩展断言)可确保对代码行为的验证。

  • 扩展覆盖范围:强调扩展测试覆盖范围,包括突变测试等技术、发现隐藏的错误和提高整体代码质量。

 

这些指南可作为测试的路线图,并强调了文档的重要性。它们为项目贡献者提供了明确的起点,便于无缝集成到测试框架中。例如,Jakarta Data 中的文档(如本文提供的 Asciidoc 格式的示例所示)概述了要使用的框架、命名约定、测试结构等,以设定项目内测试实践的标准。

 

要进一步探索,请参阅 GitHub 上 Jakarta Data 项目的测试指南

 

作为对该指南的补充,我们提供了以下技巧:

 

  • 使用工具:推荐的工具包括 JUnit 5 与 AssertJ 的结合,提供具有增强断言功能的测试框架。

  • 命名约定:测试类应以测试主题​​命名,后跟“Test”后缀,以提升测试套件内的清晰度和组织性。

  • 测试方法描述:测试方法应使用结构化方法描述测试意图:前缀“should”Action 名称

  • 为快乐路径提供可选预期结果,为负面场景(极端情况)提供强制性结果

 

例如,下面的代码片段演示了如何使用指南创建测试:

class CalculatorTest {    @Test    @DisplayName("Should sum up correctly two numbers")    void sumUpCorrectly() {        // AAA pattern (arrange, act, assert)    }}
复制代码

首选软断言:建议使用软断言,而不是硬断言。它们允许在单个测试方法中执行多个语句,而不会在第一次失败时中止测试执行。这样可以对测试场景进行更全面的验证。

assertSoftly(softly->{softly.assertThat(pageable.size()).isEqualTo(20);softly.assertThat(pageable.page()).isEqualTo(1L);softly.assertThat(pageable.mode()).isEqualTo(Pageable.Mode.CURSOR_NEXT);softly.assertThat(pageable.cursor().size()).isEqualTo(3);softly.assertThat(pageable.cursor().getKeysetElement(0)).isEqualTo("First");softly.assertThat(pageable.cursor().getKeysetElement(1)).isEqualTo(2L);softly.assertThat(pageable.cursor().getKeysetElement(2)).isEqualTo(3);});
复制代码

对 Jakarta EE 项目中的测试方法进行现代化的第二步,主要是精心选择和采用现代化测试工具和库。虽然 Jakarta EE 的根源可以追溯到 1999 年诞生的 Java EE 平台,但现代化工具对于在当今的软件领域保持敏捷性和竞争力来说是至关重要的。

 

Jakarta NoSQL 和 Jakarta Data 是 Jakarta EE 中最年轻的规范之二,它们无缝集成了一些现代测试库,以增强代码的可维护性、可读性和测试覆盖率。在这些库中,JUnit 5 的采用非常亮眼,它提供了可显著改善测试实践的一些高级特性。

 

事实证明,迁移到 JUnit 5(特别是 JUnit Jupiter)是值得的,它为 Jakarta EE 项目带来了许多有价值的特性。这些特性包括带来更清晰测试意图的测试描述、用于处理特定于环境的测试场景的环境条件,以及用于数据驱动测试的各种来源,例如值来源、方法来源和参数来源。

 

通过利用 JUnit 5 的上述特性,开发人员可以改进 Jakarta EE 项目的测试实践,以确保在不断变化的软件需求面前保持稳健性、可靠性和适应性。我们来深入研究如何利用这些特性来增强 Jakarta EE 项目中的测试。

 

对 Jakarta EE 项目中的测试方法进行现代化的第三步是采用数据驱动测试。本质上,这种方法是使用不同的数据集迭代相同的测试代码,从而提供一种快速增强代码覆盖率和可维护性的机制。

 

JUnit Jupiter 是 Jakarta EE 项目中的强大伙伴,主要用在 Jakarta Data 和 Jakarta NoSQL 中;它提供了 @ParameterizedTest 注释来简化数据驱动测试。此注释和多种来源选项简化了将动态数据注入测试用例的过程。

 

ValueWriterDecoratorTest 的第一个示例代码片段中,@ValueSource 注释用于将参数中的值注入测试方法。它能轻松测试不同类之间的兼容性。

@ParameterizedTest(name = "must be compatible to {0}")@DisplayName("Should be able to verify the test compatibility")@ValueSource(classes = {Enum.class, Optional.class, Temporal.class})@SuppressWarnings("unchecked")void shouldVerifyCompatibility(Class<?> supportedClass) {    assertThat(valueWriter.test(supportedClass)).isTrue();}
复制代码

如图 4 所示,我们可以看到单个测试基于 @ValueSource 和不同值执行了多次。



图 4:测试应用程序执行 ValueWriterDecoratorTest 类中定义的 shouldVerifyCompatibility() 方法

 

此外,JUnit Jupiter 提供了更多高级选项来动态注入参数,如 TemporalWriterTest 中所示。此处,@MethodSource 注释从一个方法处请求值,从而使用各种输入来测试 temporal 转换。

@ParameterizedTest(name = "must convert {0}")@DisplayName("Should be able to convert temporal")@MethodSource("temporalDataForConversion")void shouldConvert(Temporal temporal) {    String result = valueWriter.write(temporal);    assertThat(result).isEqualTo(temporal.toString());}static Stream<Arguments> temporalDataForConversion() {    return Stream.of(        arguments(LocalDateTime.now()),        arguments(LocalDate.now()),        arguments(LocalTime.now()),        arguments(Year.now()),        arguments(YearMonth.now()),        arguments(ZonedDateTime.now())    );}
复制代码

JUnit Jupiter 的优点在于其灵活性,允许开发人员将测试与特定数据值分离。它能够与外部数据源(如 Data Faker、数据库或 Web 服务)无缝集成,而不会影响测试套件的完整性。通过利用 JUnit Jupiter 提供的数据驱动测试方法,Jakarta EE 项目可以实现更高的测试覆盖率和可维护性,同时确保其软件解决方案的稳健性和可靠性。

 

在对 Jakarta EE 项目中的测试方法进行现代化的过程中,第四步是利用 AssertJ 等库提供的大量断言。这些库通过许多断言和特性丰富了测试工具包,包括用于简化和增强验证过程的软断言方法。

 

AssertJ 以其自带的一个流畅的 API 库而闻名,它扩展了可用断言的范围并显著提高了代码的可读性。这种增强的可读性在 KeyValueQueryParserTest 等测试中得到了体现,其中 AssertJ 的流畅 API 简化了验证过程。

@Test@DisplayName("Should execute prepared statement using 'put' setting a value")void shouldExecutePrepareStatement2() {   // code ignored   assertSoftly(softly -> {       softly.assertThat(entity.key()).as("key is equal").isEqualTo("Diana");       softly.assertThat(entity.value()).as("entity is equal").isEqualTo("Hunt");       softly.assertThat(duration).as("duration is equal").isEqualTo(ofSeconds(10L));   });}
复制代码

在此示例中,AssertJ 软断言方法中的 assertSoftly() 方法允许在单个测试方法中执行多个断言,而不会在遇到第一次失败时中止测试执行。它带来了对测试场景的更全面验证,同时保持了测试代码的可读性和清晰度。

 

通过采用 AssertJ 等库提供的大量断言,Jakarta EE 项目可以增强其测试套件的稳健性、可靠性和可维护性,最终确保其软件解决方案的质量和完整性。

 

对 Jakarta EE 项目中的测试方法进行现代化的第五步,我们转向突变测试。这种先进的技术使我们能够发现隐藏的错误并评估测试的强度。

 

PITest 是一种为 Java 和 JVM 设计的最先进的突变测试系统,在此过程中发挥着关键作用。PiTest 自动将故障或突变引入我们的代码库,使我们能够评估我们的测试对这些变化的响应程度。

 

突变测试的工作机制如下:将故障注入代码,然后执行我们的测试。如果测试失败,表明它检测到了突变,则认为突变已被终止。相反,如果测试通过,意味着它未能检测到突变,则突变仍可存活。

 

Eclipse JNoSQL 项目中,我们可以使用一个简单的命令将 PiTest 无缝集成到我们的测试工作流程中:

mvn clean test-compile -P pitest
复制代码

此命令触发分析过程,生成全面的报告,提供有关测试覆盖率、变异分数和测试强度的见解。这些报告可通过位于 target/pit-reports 的 文件访问。



图 5:针对 Eclipse JNoSQL 通信核心项目的 PITest 执行

 

上图 5 显示了 PiTest 的实际运行情况,展示了覆盖率、变异和测试强度指标。这种直观的表示使我们能够评估测试的有效性并找出改进领域。

 

通过 PITest 和突变测试,Jakarta EE 项目可以扩展其测试覆盖范围,检测潜在错误,并提高其软件解决方案的整体质量和可靠性。借助 PITest,我们可以确保我们的测试稳健而全面,从而对我们应用程序的稳定性充满信心。

 

对于 Jakarta Data 和 Jakarta NoSQL 项目,改进测试方法的最后一步是利用容器进行测试。由于核心数据库的集成情况,这一步至关重要,因为确保无缝交互和兼容性是必要的。

 

对 Jakarta EE 项目中的测试方法进行现代化的第六步也是最后一步中,Testcontainers 会用作一个强大的测试库。Testcontainers 提供简单轻量级的 API,通过封装在 Docker 容器中的精确服务简化了集成测试的引导工作。其功能可以管理测试期间数据库的生命周期,以保证测试开始时的初始化、执行期间的持久性和之后的正确拆卸。

 

JNoSQL-Database 项目中,多个集成需要与数据库直接集成,因此测试对合约的确认是非常重要的。在这里,我们见证了 Testcontainers 的实际操作,它无缝地协调数据库容器的设置和拆卸,以促进全面测试。

 

为了优化资源使用,该项目尽可能采用单例模式实例,尽可能减少初始化数据库实例的开销。这里使用了两种主要样式:管理容器的单例模式和基本测试模式。该项目正在向源自 Testcontainers 文档的标准化结构过渡,以确保测试管理的一致性和清晰度。

abstract class AbstractContainerBaseTest {    static final MySQLContainer MY_SQL_CONTAINER;    static {        MY_SQL_CONTAINER = new MySQLContainer();        MY_SQL_CONTAINER.start();    }}class FirstTest extends AbstractContainerBaseTest {    @Test    void someTestMethod() {        String url = MY_SQL_CONTAINER.getJdbcUrl();        // Create a connection and run test as normal    }}
复制代码

为了提高测试执行的灵活性,开发人员利用多个属性,根据系统属性有选择地启用或禁用集成测试。可以根据需要切换重量级集成测试。

@EnabledIfSystemProperty(named = "jnosql.test.integration", matches = "true")class MongoDBDocumentManagerTest {    // Executes test with a container}
复制代码

这种方法使开发人员能够有效地管理测试执行,有选择地运行资源密集型测试,从而优化 Jakarta EE 项目中的测试流程。通过利用容器进行测试,Jakarta Data 和 Jakarta NoSQL 项目可以验证数据库集成,从而提高其软件解决方案的可靠性和稳健性。

 

利用容器在 Jakarta EE 项目,特别是在 Jakarta Data 和 Jakarta NoSQL 项目中进行测试,对于确保软件解决方案的稳健性和可靠性至关重要。Testcontainers 具有轻量级 API 和无缝 Docker 容器集成,有助于全面测试数据库交互。将 Testcontainers 与已建立的测试模式和实践(例如 Singleton 实例和灵活的测试执行切换)并用后,Jakarta EE 开发人员可以简化测试流程并验证数据库集成。这种细致的方法不仅提高了软件解决方案的质量和可靠性,还使开发人员能够自信地应对 Jakarta EE 生态系统中数据库集成的复杂性。

总结

下面总结我们对 Jakarta EE 项目中测试方法进行现代化的探索结果,很明显,提高代码质量和可靠性是一项持续不断的努力。采用一系列创新工具和实践,例如数据驱动测试、广泛的断言和基于容器的测试,标志着行业在确保软件解决方案的稳健性方面取得了重大进展。

 

重要的是要认识到,与任何开源计划一样,Jakarta Data 和 Jakarta NoSQL 项目仍然充满活力并不断寻求改进。贡献者、测试人员和用户的积极参与对于推动这些项目向前发展、改进测试方法和提高 Jakarta EE 应用程序的可靠性是非常关键的。

 

对于那些寻求软件测试进一步见解和指导的人们来说,有很多参考资料和资源可用。一个值得推荐的是 Maurizio Aniche 的《有效软件测试:开发人员指南》,这是一本内容全面的著作,改变了许多人的测试实践。

 

此外,著名质量工程师和 Java Champion Elias Nogueira 等人的指导和领导在促进 Jakarta EE 项目中的良好测试实践方面发挥着关键作用。 Nogueira 的博客和在 Twitter 等社交媒体平台上的活跃表现,为寻求提升对测试的理解并为推进 Jakarta EE 项目做出贡献的开发人员提供了宝贵的资源。

 

在我们探索不断发展的软件开发领域时,让我们继续致力于在 Jakarta EE 项目中培育质量、协作和持续改进的文化。我们可以共同赋能开发人员,加强测试实践,并提供无与伦比的可靠性和卓越性软件解决方案。

作者介绍:

Otavio 是一位屡获殊荣的软件工程师和架构师,他热衷于为其他工程师提供开源最佳实践,以构建高度可扩展且高效的软件。他是 Java 和开源生态系统的知名贡献者,并因其工作获得了无数奖项和荣誉。Otavio 的兴趣包括历史、经济、旅行,并且精通多种语言,还非常幽默。

 

原文链接:

Modernizing Testing Practices for Jakarta EE Projects

2024-05-15 08:007426

评论

发布
暂无评论
发现更多内容

金融小程序风险如何控制,WeTest小程序质量专项方案一步到位

WeTest

一个cpp协程库的前世今生(十七)带时限的锁

SkyFire

c++ cocpp

不优雅的 React Hooks

CRMEB

关于A股投资--《香帅中国财富报告》摘录(3/100)

hackstoic

投资

重庆华美:用宜搭实现全流程管理上云,节约超百万研发成本

一只大光圈

前端 阿里 低代码 数字化转型 钉钉宜搭

网络安全——内网渗透完整流程

网络安全学海

黑客 网络安全 信息安全 渗透测试 安全漏洞

模块九作业-设计电商秒杀系统

deng

架构实战营

专有云运维如何更快、更准、更稳?丨智能运维

百度大脑

人工智能

LabVIEW实现PCB电路板坐标定位(实战篇—2)

不脱发的程序猿

机器视觉 图像处理 LabVIEW PCB电路板坐标定位

虎年前迎来脑科学新锐:脑虎科技的创生故事

脑极体

不是私密链接,如何继续前往?

BUG侦探

https HSTS 劫持

ORTC与SIP融合通信服务架构

安第斯智能云

音视频 RTC 流媒体

「干货分享」如何做好应急响应工作?常见应急响应流程

H

网络安全 应急响应

VuePress 博客优化之开启 HTTPS

冴羽

Vue 前端 博客 vuepress 博客搭建

Tengine + BabaSSL ,让国密更易用!

SOFAStack

密码学 tengine 国密 BABASSL

Flink 在字节跳动数据流的实践

字节跳动数据平台

大数据 flink 字节跳动 埋点 数据流

2022中国低代码十大发展趋势,市场规模预计达42.6亿

J2PaaS低代码平台

低代码 低代码开发 J2PaaS

酒店资产管理系统解决方案

低代码小观

CRM 企业管理系统 CRM系统 企业管理工具 企业管理软件

组件发布效率提升15倍是怎么做到的——基于 Gradle 调度机制深度研究与优化

字节跳动终端技术

字节跳动 Gradle Andriod

金融云原生漫谈(五)|如何打造更适合云原生的数据存储方案?

York

云原生 数据存储

龙蜥利器:系统运维工具 SysAK的云上应用性能诊断 | 龙蜥技术

OpenAnolis小助手

开源 运维

2022 起始篇

万万

一周信创舆情观察(1.4~1.9)

统小信uos

实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析

JackJiang

音视频 WebRTC IM 即时通讯IM

JuiceFS 即将发布 1.0 并调整开源许可

Juicedata

开源 文件系统 云存储

百度智能云以“3D+AI”技术,助力“三亿人上冰雪”

百度开发者中心

人工智能

用 SwiftUI 实现一个开源的 App Store

37手游iOS技术运营团队

swift appstore SwiftUI App榜单 App免费榜

疫情下的口罩生活,演绎出了哪些心理剧场?

脑极体

元宇宙时代:银行如何探索数字化转型

CECBC

重磅功能!Apache APISIX 拥抱 WASM 生态

API7.ai 技术团队

开源 云原生 Wasm Apache APISIX

Go语言gorm框架MySQL实践

FunTester

Go MySQL gorm FunTester

Jakarta EE项目的现代化测试实践_编程语言_InfoQ精选文章