如何在seata中编写测试用例


title: 如何在seata中编写测试用例
keywords: [Seata, unit test, junit, mockito, assertj]
description: 这篇文章主要介绍了Seata中已经使用的测试用例相关框架,以及社区建议开发者如何更好的编写测试用例
author: 汪忠祥 - trustdecision 技术专家
date: 2024-02-20

本文转载自Seata官网:https://seata.apache.org/zh-cn/blog/

背景

随着 Seata 项目的不断发展和壮大,我们的贡献者群体也在持续扩大。项目的功能不断增强,对于代码质量的要求也在提高。在这个过程中,我们期望每一位贡献者在提交功能代码的同时,能够附带规范、完备的测试用例。

一个优秀的项目,其完备的单元测试是基本保障。Test-Driven Development(TDD)理念已经提出多年,它强调在编写功能代码之前先编写测试用例。通过编写单元测试,开发者可以更深入地理解代码中相关类和方法的作用,掌握核心逻辑,熟悉各种场景的运行情况。同时,单元测试也为开源项目提供了稳定安全的保障,使得项目在接受贡献者代码时,能够确保代码的质量和稳定性。 单元测试是质量保障的第一环,有效的单元测试能够提前发现90%以上的代码Bug问题,同时也能防止代码的腐化。在项目重构和演进过程中,单元测试起到了至关重要的作用,它能够确保重构后的代码仍然能够正常工作,不会引入新的Bug。

在社区看来,贡献合理的测试用例代码和贡献功能代码同样重要,为了帮助开发者编写出高质量的测试用例,本文给出一些基础的规范和建议。

推荐的框架

当前社区使用以下三个框架编写测试用例;

junit5

junit是Java中最常用的单元测试框架,用于编写和运行可重复的测试用例。

        <junit-jupiter.version>5.8.2</junit-jupiter.version><dependency><groupId>org.junit</groupId><artifactId>junit-bom</artifactId><version>${junit-jupiter.version}</version></dependency>

mockito

mockito是一个mock框架,主要是用来做mock测试,他可以模拟任何 Spring管理的 bean、模拟方法的返回值、模拟抛出异常等,可以让我们在缺乏一些依赖的情况下,完成测试及验证。

        <mockito.version>4.11.0</mockito.version><dependency><groupId>org.mockito</groupId><artifactId>mockito-core</artifactId><version>${mockito.version}</version></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-junit-jupiter</artifactId><version>${mockito.version}</version></dependency><dependency><groupId>org.mockito</groupId><artifactId>mockito-inline</artifactId><version>${mockito.version}</version></dependency>

assertj

assertj是一个断言库,提供了一组易于使用和可读性很强的断言方法,当junit的断言难以满足时,可以使用assertj进行断言;

请注意:我们在seata-dependencies的pom.xml中统一管理了这三个库的版本。

        <assertj-core.version>3.12.2</assertj-core.version><dependency><groupId>org.assertj</groupId><artifactId>assertj-core</artifactId><version>${assertj-core.version}</version></dependency>

规范

我们参考阿里巴巴JAVA开发手册,整理了一些建议及规范,分为不同的级别,其中【【强制】部分,开发者需要严格遵守,社区在合并代码时会按照强制规则进行review,【【推荐】【参考】部分,方便大家更好的了解我们对于测试用例的考量和原则。

1.【强制】单元测试必须遵守 AIR 原则。

说明:好的单元测试宏观上来说,具有自动化、独立性、可重复执行的特点。

  • A:Automatic(自动化)
  • I:Independent(独立性)
  • R:Repeatable(可重复)
2.【强制】单元测试应该是全自动执行的,并且非交互式的。

测试用例通常是被定期执行的,执行过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试。单元测试中不准使用 System.out 来进行人肉验证,必须使用 assert 来验证。

3.【强制】保持单元测试的独立性。为了保证单元测试稳定可靠且便于维护,单元测试用例之间决不能互相调用,也不能依赖执行的先后次序。

反例:method2 需要依赖 method1 的执行,将执行结果作为 method2 的输入。

4.【强制】单元测试是可以重复执行的,不能受到外界环境的影响。

说明:单元测试通常会被放到持续集成中,每次有代码 check in 时单元测试都会被执行。如果单测对外部环境(网络、服务、中间件等)有依赖,容易导致持续集成机制的不可用。

正例:为了不受外界环境影响,要求设计代码时就把 SUT 的依赖改成注入,在测试时用 spring 这样的 DI框架注入一个本地(内存)实现或者 Mock 实现。

5.【强制】对于单元测试,要保证测试粒度足够小,有助于精确定位问题。单测粒度至多是类级别,一般是方法级别。

说明:只有测试粒度小才能在出错时尽快定位到出错位置。单测不负责检查跨类或者跨系统的交互逻辑,那是集成测试的领域。

6.【强制】核心业务、核心应用、核心模块的增量代码确保单元测试通过。

说明:新增代码及时补充单元测试,如果新增代码影响了原有单元测试,请及时修正。

7.【强制】单元测试代码必须写在如下工程目录:src/test/java,不允许写在业务代码目录下。

说明:源码编译时会跳过此目录,而单元测试框架默认是扫描此目录。

8.【强制】单元测试的基本目标:语句覆盖率达到 70%;核心模块的语句覆盖率和分支覆盖率都要达到 100%。

说明:在工程规约的应用分层中提到的 DAO 层,Manager 层,可重用度高的 Service,都应该进行单元测试。

9.【推荐】编写单元测试代码遵守 BCDE 原则,以保证被测试模块的交付质量。
  • B:Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等。
  • C:Correct,正确的输入,并得到预期的结果。
  • D:Design,与设计文档相结合,来编写单元测试。
  • E:Error,强制错误信息输入(如:非法数据、异常流程、业务允许外等),并得到预期的结果。
10.【推荐】对于数据库相关的查询,更新,删除等操作,不能假设数据库里的数据是存在的,或者直接操作数据库把数据插入进去,请使用程序插入或者导入数据的方式来准备数据。

反例:删除某一行数据的单元测试,在数据库中,先直接手动增加一行作为删除目标,但是这一行新增数据并不符合业务插入规则,导致测试结果异常。

11.【推荐】和数据库相关的单元测试,可以设定自动回滚机制,不给数据库造成脏数据。或者对单元测试产生的数据有明确的前后缀标识。
12.【推荐】对于不可测的代码在适当的时机做必要的重构,使代码变得可测,避免为了达到测试要求而书写不规范测试代码。
13.【推荐】单元测试作为一种质量保障手段,在提交pr前完成单元测试的编写及验证。
14.【参考】为了更方便地进行单元测试,业务代码应避免以下情况:
  • 构造方法中做的事情过多。
  • 存在过多的全局变量和静态方法。
  • 存在过多的外部依赖。
  • 存在过多的条件语句。
    说明:多层条件语句建议使用卫语句、策略模式、状态模式等方式重构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/813853.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SecureCRT通过USB-Servial ch340串口无法连接单片机

通过USB To TTL连线 STM32F103-PRO&#xff0c;烧制程序到单片机上&#xff0c;通过SecureCRT通过USB-Servial ch340串口无法链接RS232升USB转TTL连接正确 开发板连接正确 问题&#xff1a;SecureCRT串口连接没有反应 问题分析&#xff1a;1、检查ch340串口驱动 查看设备管…

TQZC706开发板教程:在ZC706上运行ADRV9371(vivado2018.3)

首先需要在github上下载两个文件&#xff0c;本例程用到的文件以及最终文件&#xff0c;我都会放在网盘里面&#xff0c;地址在本文的末尾&#xff0c;需要自行提取 在github上搜索hdl选择第一个-->选择版本-->我所使用的vivado是2018.3版本&#xff0c;所以这里我下载的…

软考 - 系统架构设计师 - 面向对象架构设计案例

问题1&#xff1a; 解决该题&#xff0c;用例和参与者要一起进行分析&#xff0c;首先看到用例 U1 和 U2 是 U3 的扩展&#xff0c;分析用例列表中的用例&#xff0c;可以分析出 U1 和 U2 是Underpaid transaction 和 Record lllegal use&#xff0c;顺序可以颠倒&#xff0c;…

分享 GoLand 2024.1 激活的方案,支持JetBrains全家桶

大家好&#xff0c;欢迎来到金榜探云手&#xff01; GoLand 公司简介 JetBrains 是一家专注于开发工具的软件公司&#xff0c;总部位于捷克。他们以提供强大的集成开发环境&#xff08;IDE&#xff09;而闻名&#xff0c;如 IntelliJ IDEA、PyCharm、和 GoLand等。这些工具被广…

【QT学习】6.控件进阶,C与C++的强制类型转换,自定义控件,qt制作一个简易播放器

1.C与C的强制类型转换 2.自定义控件 要求&#xff1a;制作一个登录页面 1.使用控件拖拽一个页面出来 使用水平布局&#xff0c;垂直布局&#xff0c;网格布局 2.建立自定义控件 1.为项目添加自定义的类 自己写一个控件 2. &#xff08;1&#xff09;创建一个Group Box容器 &a…

springboot整合shiro之——拦截路径

简介Shiro: 1.基本功能 身份认证、授权、加密、会话管理 Web支持、缓存、多线程、测试、允许一个用户假装为另一个用户的身份进行访问、记住我 2. 执行过程 分为五步&#xff1a; Subject 用户主体&#xff1a;请求的发起者&#xff0c;即访问应用的用户 Security Manager 安…

xxl-job调度任务原理解析

xxljob可以对定时任务进行调度&#xff0c;现在看下定时任务调度的过程。XxlJobAdminConfig实现了InitializingBean接口&#xff0c;spring会调用afterPropertiesSet()进行初始化。大致有以下几个过程&#xff1a; admin服务端初始化 JobTriggerPoolHelper.java#toStart()方法…

1.Hexo安装和环境搭建引导

Hexo是一个依赖于一个名为nodejs的程序 因此安装它的方式在Mac和Windows上实际上是一样的 为了在电脑上安装Hexo 需要做两件事 nodejs&#xff0c;基本上是hexo依赖运行的JavaScript框架 Node.js — Run JavaScript Everywheregit&#xff0c;是一个程序&#xff0c;用来管理电…

Traefik和HAProxy全方位对比

在面对各种现代应用部署需求时&#xff0c;选择合适的反向代理和负载均衡器至关重要。Traefik&#x1f6a6;和HAProxy&#x1f6e1;️都是领先的解决方案&#xff0c;但它们各有特点&#xff0c;适用于不同的场景。本文将从多个维度全面对比Traefik&#x1f6a6;和HAProxy&…

【C++】类和对象②(类的默认成员函数:构造函数 | 析构函数)

&#x1f525;个人主页&#xff1a;Forcible Bug Maker &#x1f525;专栏&#xff1a;C 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性及用法 析构函数 概念 析构函数的特性及用法 结语 前言 本篇主要内容&#xff1a;类的6个默认成员函数中的构造函…

设计模式——外观(门面)模式10

外观模式&#xff1a;能为系统框架或其他复杂业务流程封装提供一个简单的接口。 例如抽奖过程中 设计模式&#xff0c;一定要敲代码理解 调用1&#xff08;抽奖系统&#xff09; /*** author ggbond* date 2024年04月08日 10:34*/ public class Lottery {public String getId…

OpenHarmony南向开发案例:【智能门锁】

一. 简介 本demo是基于Openharmony 3.1 Beta本版开发&#xff0c;不仅可以接收数字管家应用下发的指令来控制门锁开启&#xff0c;而且还可以通过数字管家设置不同的开锁密码以及一次性密码&#xff0c;实现给临时用户一个临时密码&#xff0c;保证门户安全。当然除了开锁的功…

遍历列举俄罗斯方块的所有形状

以前玩俄罗斯方块的时候&#xff0c;就想过一个问题&#xff0c;为什么俄罗斯方块就这7种形状&#xff0c;还有没有别的形状&#xff1f;自己也在纸上画过&#xff0c;比划来比划去&#xff0c;确实就这几种形状。 继续思考一下&#xff0c;那假如是3个块组合的形状&#xff0…

网页input框自动填充问题

autocomplete 大部分查询解决办法是设置&#xff0c;autocompleteoff&#xff0c;关于autocomplete的含义&#xff0c;官网参考如下: HTML attribute: autocomplete - HTML: HyperText Markup Language | MDN 在 autocomplete 的文档中说明了 value 为 off 时&#xff0c;浏览…

双子座 Gemini1.5和谷歌的本质

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

游戏软件测试流程

备注:本文为博主原创文章,未经博主允许禁止转载。如有问题,欢迎指正。 个人笔记(整理不易,有帮助,收藏+点赞+评论,爱你们!!!你的支持是我写作的动力) 笔记目录:学习笔记目录_pytest和unittest、airtest_weixin_42717928的博客-CSDN博客 个人随笔:工作总结随笔_8、…

【STL】list

目录 1. list的使用 1.1 list的构造 1.2 list iterator的使用 1.3 list capacity 1.4 list element access 1.5 list modifiers 1.6 list的迭代器失效 2. list的模拟实现 3. list与vector的对比 1. list的使用 1.1 list的构造 1.2 list iterator的使用 1. begin与end为…

JavaEE初阶Day 6:多线程(4)

目录 Day 6&#xff1a;多线程&#xff08;4&#xff09;1. 线程不安全的原因2. 锁3. synchronized Day 6&#xff1a;多线程&#xff08;4&#xff09; 前序&#xff1a;针对Day 5结尾的count 多线程的执行&#xff0c;是随机调度抢占式的执行模式&#xff0c;某个线程执行指…

KVM + GFS 分布式存储

目录 一、案例分析 1.1、案例概述 1.2、案例前置知识点 1&#xff09;Glusterfs 简介 2&#xff09;Glusterfs 特点 1.3、案例环境 1&#xff09;案例环境 2&#xff09;案例需求 3&#xff09;案例实现思路 二、案例实施 2.1、安装部署 KVM 虚拟化平台 1&…

Mac的终端配置

Mac的终端配置 参考教程包管理工具 - Homebrew出现的问题用虚拟环境解决方案&#xff1a;直接将解释器的路径放过去错误方法&#xff1a;用find查找到虚拟环境安装的路径&#xff0c;其链接的是brew安装的python路径 编辑器没有报错&#xff0c;但是运行过程中仍然找不到pandas…