淘系用户平台技术团队单元测试建设

简介: 单元测试是工程交付前质量保障的第一环,也无疑是软件工程质量保障的重要基石,有效的单元测试能够提前发现90%以上的代码Bug问题,同时也能防止代码的腐化,在工程重构演进时起到至关重要的作用。

image.png

作者 | 问元
来源 | 阿里开发者公众号

为什么需要单元测试

纵观优秀的开源工程,完备的单元测试总是必须的条件。通过这些单元测试,我们可以充分了解代码中相关类和方法的作用和核心逻辑,熟悉各种场景的运行情况。同时也因为有了单元测试,开源作者在接受各种feature的代码提交时才有稳定安全的保障。其实单元测试的重要性所有开发同学应该都了然于胸,同样TDD(测试驱动开发)也不是一个新的概念,但是真当我们落地实践时,又总会找出各种各样的理由来劝服自己下次一定好好写单元测试,这一次先放过自己。这些理由无外乎,开发周期太紧了; 测试同学能保证功能正确性;写单元测试代码量比业务代码还大; 又不是不能跑。所以虽然我们总是在追逐工程师文化,却又时不时放纵在放弃工程师底蕴的路上。

单元测试是工程交付前质量保障的第一环,也无疑是软件工程质量保障的重要基石,有效的单元测试能够提前发现90%以上的代码Bug问题,同时也能防止代码的腐化,在工程重构演进时起到至关重要的作用。

怎么写单元测试

好的单元测试的几个要点

摘自阿里巴巴开发规约

  • 单元测试必须遵守AIR原则,单元测试必须具备Automatic(自动化),Independent(独立性),Repeatable(可重复)性;
  • 单元测试应该是全自动执行的,并且非交互式的。测试用例通常是被定期执行的,执行过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试;
  • 单元测试要保证测试粒度足够小。单元测试测试粒度足够小,有助于精确定位问题。单测粒度至多是类级别,一般是方法级别;
  • 单元测试要遵守BCDE原则,Border,边界值测试,包括循环边界、特殊取值、特殊时间点、数据顺序等;Correct,正确的输入,并得到预期的结果;Design,与设计文档相结合,来编写单元测试;Error,强制错误信息输入(如:非法数据、异常流程、非业务允许输入等),并得到预期的结果;
  • 核心业务、核心应用、核心模块的增量代码要确保单元测试通过;

单元测试编码范式

这里主要以Mockito单元测试框架为模版

  1. Mock : 通过when().thenReturn/thenAnswer/thenThrow 或者doReturn().when()等mock方式将依赖类方法进行模拟,模拟服务依赖或者中间结果
  2. DO : 调用被测试类方法,执行测试链路
  3. Verify : 校验执行结果正确性,通过Assert校验数据结果准确,通过Verify校验链路执行准确,通过expected=Exception.class校验异常链路
public class Test {
    // 0. 依赖类
    @Mock
    DependencyClass dependencyClass;
    // 0. 待测试类
    @InjectMocks
    TestClass testClass;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testMethod() {
        // 1. Mock, 依赖方法,构造中间层数据
        when(dependencyClass.someMehod(any())).thenReturn(mockData());
        // 2. Do, 调用被测试类
        Result result = testClass.testMehod();
        // 3. Verify, 校验结果数据
        Assert.assertEquals("some expected result string", result.getModel());
    }
}

当然写单元测试用例虽然套路比较模版化,但是我们也要充分利用单元测试框架(Junit/Mockito/PowerMock/Spock),掌握其中的一些技巧,才能写出快准狠的单元测试用例,这也是研发同学必须要掌握的基本功。关于如何利用单元测试框架这里不再赘述(详细可以参考阿里技术《Java编程技巧之单元测试用例编写流程》)。

单元测试编码提效

IDEA上有很多单元测试插件,能够半自动化生成单元测试类文件,这里重点推荐TestMe插件。TestMe插件可以智能分析被测试类的依赖类,结合Mockito+Junit等单元测试框架,生成Mock/InjectMocks依赖关系,自动生成单元测试类。

image.png

假设业务代码如下:

@Component
public class DefaultMemberManager implements MemberManager {
    @Autowired
    private MemberDAO memberDAO;
    @Autowired
    private CacheManager cacheManager;

    @Override
    public Date queryActivationTime(long userId) {
        Date activationTime = cacheManager.getActivationTime(userId);
        if (activationTime == null) {
            MemberDO memberDO = memberDAO.queryByUserId(userId);
            if (memberDO != null) {
                cacheManager.saveActivationTime(userId, memberDO.getActiveTime());
                activationTime = memberDO.getActiveTime();
            }
        }
        return activationTime;
    }
}

则通过TestMe快捷键COMMOND+N, 可以极速自动生成如下的单元测试类

public class DefaultMemberManagerTest {
    @Mock
    MemberDAO memberDAO;
    @Mock
    CacheManager cacheManager;
    @InjectMocks
    DefaultMemberManager defaultMemberManager;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testQueryActivationTime() throws Exception {
        when(memberDAO.queryByUserId(anyLong())).thenReturn(null);
        when(cacheManager.getActivationTime(anyLong())).thenReturn(
            new GregorianCalendar(2022, Calendar.MARCH, 5, 23, 2).getTime());
        Date result = defaultMemberManager.queryActivationTime(0L);
        Assert.assertEquals(new GregorianCalendar(2022, Calendar.MARCH, 5, 23, 2).getTime(), result);
    }
}

团队单元测试建设

覆盖率概念

覆盖率是类JaCoCo插件通过javaagent挂载的方式,在单元测试命令运行时执行代码覆盖率检测,计算单元测试执行过程中所覆盖的代码比例来生成覆盖率。常见的覆盖率指标,又可进一步细分为语句覆盖率,条件覆盖率,分支覆盖率,路径覆盖率等。这里我们当前更为关注语句覆盖率和分支覆盖率,尤其是增量代码的覆盖率,更能体现变更代码的单元测试覆盖情况。

如何进行单元测试

这里我们借助于阿里研发平台Aone的测试实验室功能,Aone实验室支持测试任务插件的编排组合,通过独立的测试资源执行测试任务。所以我们将代码拉取插件,单元测试插件和覆盖率计算插件进行编排配置,形成最终的执行流:拉取代码;执行单元测试命令;单元测试结果解析;计算覆盖率。最终完成整个工程的单元测试覆盖率计算。

image.png

单元测试覆盖率结果示例如下

image.png

什么时候触发单元测试

单元测试任务主要通过持续交付流水线pipeline来集成,当前几个主要触发策略如下

  1. 代码提交时,保证单元测试执行及时性
  2. 代码审核时,保证代码审核通过的代码分支符合单元测试标准
  3. 发布流程中,保证最终集成发布的所有分支代码符合单元测试标准

单元测试覆盖率卡点

用户平台技术团队单元测试规范如下:

  • 单元测试用例通过率为100%
  • 单元测试增量代码行覆盖率为85%
  • 代码规范扫描增量问题总数为0个

单元测试覆盖率报表

为了更好的衡量单元测试的覆盖率情况,我们采用报表的形式统计每个应用,每个团队的代码单元测试覆盖率。

image.png

总结

当前团队内各应用(除边缘应用外)的单元测试增量代码覆盖率在2022年已经全部达到85%标准,最新平均增量代码行覆盖率达到88%,整体全量代码覆盖率平均提高20%。诚然单元测试覆盖率的提高不是最终的目的,覆盖率高不能完全代表工程质量高,但是一个没有单元测试或者单元测试覆盖率低的工程,其代码质量和稳定性必然不高。同时团队内研发同学对单元测试也有了新的认识,自测和提测质量显著提升,全年未发生由于代码质量产生的线上故障,有效提升了工程质量和服务稳定性。

后续规划,持续优化单元测试质量,提升分支覆盖率,优化边界异常覆盖;关注单元测试编码效率的提升,优化测试用例和测试数据分离;关注核心链路单元测试覆盖率;熟练将TDD思维运用到业务开发过程中。

团队介绍

大淘宝技术-用户平台技术团队是一支集研发、数据、算法一体的团队,负责淘系的用户增长,游戏互动,平台会员和私域运营等消费者核心业务。在对用户争夺进入白热化的时期,团队正承担着捍卫电商主板块增长的重要使命,是阿里核心电商战场的参与者,用持续的技术创新来驱动阿里电商引擎的稳步前行。

这是一支年轻开放的团队,在这里你将收获超大规模高并发场景的架构设计能力,洞悉用户增长最前沿的实践方法,在数字化时代收获最核心的竞争力。团队技术氛围浓厚,倡导创新和工程师文化,鼓励用数据和代码发现解决问题。团队研发流程规范,代码质量高,学习成长速度快。

如果您有兴趣可将简历发至wangliyuan.wly@alibaba-inc.com,期待您的加入。


Serverless Develpoer Meetup 课程

阿里云首场线下 Serverless Developer Meetup 即将亮相,来自阿里云、淘宝、闲鱼、百富旅行的技术大咖,洞察 Serverless 在中国的发展趋势;深度分享 Serverless 在 双11 和企业的落地经验;首次披露 Serverless Devs 开源细节。

相关实践学习
【AI破次元壁合照】少年白马醉春风,函数计算一键部署AI绘画平台
本次实验基于阿里云函数计算产品能力开发AI绘画平台,可让您实现“破次元壁”与角色合照,为角色换背景效果,用AI绘图技术绘出属于自己的少年江湖。
从 0 入门函数计算
在函数计算的架构中,开发者只需要编写业务代码,并监控业务运行情况就可以了。这将开发者从繁重的运维工作中解放出来,将精力投入到更有意义的开发任务上。
相关文章
|
3月前
|
关系型数据库 MySQL 测试技术
【分享】AgileTC测试用例管理平台使用分享
AgileTC 是一个脑图样式测试用例管理平台,支持用例设计、执行与团队协作,帮助测试人员高效管理测试流程。
293 116
【分享】AgileTC测试用例管理平台使用分享
|
3月前
|
人工智能 数据可视化 测试技术
AI测试平台自动遍历:低代码也能玩转全链路测试
AI测试平台的自动遍历功能,通过低代码配置实现Web和App的自动化测试。用户只需提供入口链接或安装包及简单配置,即可自动完成页面结构识别、操作验证,并生成可视化报告,大幅提升测试效率,特别适用于高频迭代项目。
|
3月前
|
人工智能 测试技术 调度
写用例写到怀疑人生?AI 智能测试平台帮你一键生成!
霍格沃兹测试开发学社推出AI智能测试用例生成功能,结合需求文档一键生成高质量测试用例,大幅提升效率,减少重复劳动。支持自定义提示词、多文档分析与批量管理,助力测试人员高效完成测试设计,释放更多时间投入核心分析工作。平台已开放内测,欢迎体验!
|
3月前
|
人工智能 测试技术 项目管理
测试不再碎片化:AI智能体平台「项目资料套件」功能上线!
在实际项目中,需求文档分散、整理费时、测试遗漏等问题常困扰测试工作。霍格沃兹推出AI智能体测试平台全新功能——项目资料套件,可将多个关联文档打包管理,并一键生成测试用例,提升测试完整性与效率。支持套件创建、文档关联、编辑删除及用例生成,适用于复杂项目、版本迭代等场景,助力实现智能化测试协作,让测试更高效、更专业。
|
4月前
|
存储 人工智能 算法
AI测试平台实战:深入解析自动化评分和多模型对比评测
在AI技术迅猛发展的今天,测试工程师面临着如何高效评估大模型性能的全新挑战。本文将深入探讨AI测试平台中自动化评分与多模型对比评测的关键技术与实践方法,为测试工程师提供可落地的解决方案。
|
6月前
|
存储 测试技术 虚拟化
VMmark 4.0.3 - 虚拟化平台基准测试
VMmark 4.0.3 - 虚拟化平台基准测试
204 0
VMmark 4.0.3 - 虚拟化平台基准测试
|
3月前
|
人工智能 自然语言处理 测试技术
AI测试平台的用例管理实践:写得清晰,管得高效,执行更智能
在测试过程中,用例分散、步骤模糊、回归测试效率低等问题常困扰团队。霍格沃兹测试开发学社推出的AI测试平台,打通“用例编写—集中管理—智能执行”全流程,提升测试效率与覆盖率。平台支持标准化用例编写、统一管理操作及智能执行,助力测试团队高效协作,释放更多精力优化测试策略。目前平台已开放内测,欢迎试用体验!
|
4月前
|
存储 人工智能 文字识别
从零开始打造AI测试平台:文档解析与知识库构建详解
AI时代构建高效测试平台面临新挑战。本文聚焦AI问答系统知识库建设,重点解析文档解析关键环节,为测试工程师提供实用技术指导和测试方法论
|
4月前
|
人工智能 安全 数据可视化
安全测试平台的选型标准与搭建思路
随着企业安全需求升级,传统漏洞扫描和渗透测试已无法满足要求。构建安全测试平台(STP)成为趋势,实现漏洞扫描、权限评估、接口测试等工作的平台化运营。本文从选型标准、平台架构、模块功能等六个方面,系统讲解如何搭建企业级安全测试平台,提升安全能力。
|
7月前
|
安全 前端开发 Linux
Immunity CANVAS Professional 7.27 (macOS, Linux, Windows) - 渗透测试和漏洞利用平台
Immunity CANVAS Professional 7.27 (macOS, Linux, Windows) - 渗透测试和漏洞利用平台
220 3
Immunity CANVAS Professional 7.27 (macOS, Linux, Windows) - 渗透测试和漏洞利用平台