首页 > 其他分享 >公司最大的内卷,偷偷做单元测试

公司最大的内卷,偷偷做单元测试

时间:2024-08-23 09:49:07浏览次数:5  
标签:断言 代码 单元测试 偷偷 expect 测试 内卷 我们

一位读者在看过我的《理解这八大优势,才算精通单元测试》后,问我:知道单元测试有好处,但实在没空写。看完文章后又想重新落实一下,有没有啥写好单元测试的技巧?

这位读者绝对不是第一个和我抱怨单元测试的人。这很好理解,中国互联网公司太多太卷,想要抢夺市场就要推出不同功能,而这些压力一部分落在了程序员身上,拼命赶需求。单元测试这种费力不讨好的事情,自然而然就没有人做。

就我多年的经验来看,写单元测试其实不会拖延项目,反而能够加快功能研发进度。单元测试的好处我就不在这里赘述了,只有真正尝试过的人才能理解。

马克·吐温曾说:“取得成功的秘诀就是开始。”本篇文章想和大家分享一下写好单元测试的技巧,希望可以给大家带来新方向。

 

一、单元测试的注意事项

单元测试是为了让我们快速查找并隔离损坏的代码片段。正因如此,这些函数和类在测试时不应该依赖于mock(模拟)和stub(存根)以外的其他元素。在测试中,如果试图覆盖的逻辑过于复杂,就难以确保覆盖的可靠性,也难以准确找出失败的原因。

因此,我们要注意单元测试包括以下几点。

01 简洁性

短函数更容易阅读和理解。我们每次只测试一个逻辑点,因此测试代码应该控制在几行之内。但如果逻辑可能具有多个依赖项,这就需要大量样板代码来初始化模拟和存根。此外,单元测试同样适用DRY原则(Don't repeat yourself,一次且仅一次),我们在写单元测试时要避免到处复制粘贴混乱的代码,最好使用组合而不是继承。爱因斯坦曾说:“当你在生活中感到困顿时,也许是你把事情复杂化了。”所以,当我们对单元测试产生困惑时,也许是因为我们在单元测试中使用复杂的逻辑。注意一点:单元测试的目的在于测试代码,不要让单元测试本身也成为测试的一部分。

02 明确性

单元测试要使用详尽的长名称。这样的名称不仅能清楚表达信息,还能起到索引作用、快速定位相应测试。就算需求发生变化,我们只需要针对相应的测试进行更改,不必查看所有内容并检查受影响的内容。

好的单元测试一般只有一个断言,因此命名起来也很容易。例如,在处理金额计算时,It('should return 0 for an empty cart')要比It('works for 0')或者It('empty cart')好得多。对于使用函数名称作为测试名称的框架也是如此,shouldReturnZeroForAnEmptyCart就是一个很不错的的命名。

正如丁玲所言:“人生就像爬坡,要一步一步来。”单元测试也是如此,不要一次性测试整个方法,要一步一步来。我们只针对单个需求写单元测试,代码就会变得易于阅读和维护。

03 可维护性

测试框架需要提供各种断言方法。它们提供不同的方法来检查结果,并且当断言失败时,它们还会显示更具体的错误消息,从而提供更多上下文来查看错误所在。

例如,

expect(result === expected).toBeTruthy();

将会失败

expect(received).toBeTruthy()
Received: false

尽管

expect(result).toBe(expected);

将提供更多有关具体失败原因的信息:

expect(received).toBe(expected) // Object.is equality
Expected: "John Doe"
Received: "JohnDoe"

框架还为不同的测试方式提供了各种断言。例如,在使用Jest进行测试时,toBe使用Object.is测试是否完全相等,而toEqualtoStrictEqual则深入比较对象,确保他们的类型和结构一致。

为了判断浮点数是否相等,我们需要采用一种特殊的匹配器,这种匹配器能够忽略由于浮点数在内存中的表示方式导致的微小舍入误差。在Jest中,匹配器是toBeCloseTo。虽然toEqual有时也能适用,但即使是看似简单的测试,如expect(0.1+0.2).toEqual(0.3)也可能无法通过。

 

二、单元测试的AAA原则

遵循AAA原则(Arrange、Act、Assert,安排、执行、断言),可以娴熟提升单元测试代码的清晰度、可靠性和可维护性。

第一步,安排阶段(Arrange)。我们需要完成变量赋值、对象实例化对象以及测试运行所需的其余前置设置,并且定义预期结果。这样做的好处在于:一方面,我们需要在执行测试逻辑前就有明确预期;另一方面,这更方便在输入数据后立即查看预期输出,有助于避免代码混淆。

第二步,执行阶段(Act)。我们将执行测试函数并存储其结果。结果存储其实是准备工作的自然延伸,有助于我们对结果进行回顾总结。

第三步,断言阶段(Assert)。我们在这个阶段可以判断假设的正确性了。这正是单元测试的核心所在,因为这一环节实际上是对某些具体内容的测试。其目的在于是检查实际得到的结果否与预期结果相匹配。

我们要确保代码可靠性,避免错误输入、缺少参数、空数据、调用函数中的异常等情况的出现。代码覆盖率工具可以帮助我们查漏补缺,找到未测试的代码分支。我们要始终明确我们单元测试的目标,过于追求100%测试覆盖率反而会让单元测试代码越来越繁杂。这与《吕氏春秋》中的论点不谋而合:“不知轻重,‌则重者为轻,‌轻者为重矣。‌若此,‌则每动无不败”。

三、单元测试的优化和维护

为了提高单元测试效率,我们需要模拟所有可能影响速度的外部依赖项,例如API调用、数据库或文件系统访问。我们在写单元测试时,应尽量避免线程休眠、等待和超时。如果必须设置超时,就应该将其缩短至几毫秒。在处理多线程或异步竞争条件时,精确控制出发条件比简单的等待要有效得多。

单元测试应当确保不会改变作用域外的任何内容。如果测试仅在按照特定顺序执行时才能成功,这可能表明测试用例或测试代码存在问题。每个测试用例应独立运作。由于现代测试框架默认并行执行测试,因此我们不应依赖全局变量或之前测试的遗留效应。这也是全局变量常被视为不良编程习惯的原因之一,这会隐藏真正的依赖关系,导致代码耦合度升高,并在处理多线程问题时需要格外留意。

当测试需要复杂的重复配置时,应利用框架提供的设置和清理功能。这些功能保障了在每个测试用例或整个测试套件开始前后,相关代码能够得到执行。这样,无论是单独运行测试还是作为测试套件的一部分,都能确保测试结果的确定性,执行顺序不会对测试结果造成影响。

四、单元测试贵在坚持

《荀子·大略》:“夫尽小者大,积微成著,德至者色泽洽,行尽而声问远。”单元测试的作用只有经过长期积累才会变得显著。其实,写单元测试更多的是对自己的代码负责。有测试用例的代码,别人更容易看懂,以后别人接手你的代码时,也可能放心做改动。

根据上述方法开始行动,单元测试也不是什么难事,毕竟“世上无难事,只怕有心人”。我发现关于单元测试有很多读者感兴趣,还有人曾问我单元测试到底该由测试进行还是开发进行。如果大家感兴趣,我也可以写一篇文章和大家简单分享一下。

*参考文章:Andriy Obrizan,How to Write Good Unit Tests: 14 Tips

标签:断言,代码,单元测试,偷偷,expect,测试,内卷,我们
From: https://www.cnblogs.com/chenqiAaron/p/18375301

相关文章

  • WebAPI中写单元测试
    首次在WebAPI中写单元测试xUnit这次我使用的是xUnit测试框架,而不是VS自带的MSTest框架。在添加新建项目时选择xUnit测试项目就行了。目前只体验到了一个差别,即xUnit可以使用特性向测试方法传参,而不用在测试方法中一个赋值语句一个个去定义参数,这是比较方便的。单元测试有一个......
  • 产线一直在用的 RabbitMQ 搭建教程(含负载均衡配置,验证脚本,监控案例),偷偷抄出来的,建议收
    本文介绍公司一直在用的rabbitmq集群安装部署过程,版本不算太新,但一直稳定运行,对其他版本安装也有一定的参考价值,建议收藏备用。简介官网:https://www.rabbitmq.com/RabbitMQ是一个开源的遵循AMQP(AdvancedMessageQueuingProtocol)协议实现的基于Erlang语言编写,支......
  • mavn 执行 junit 单元测试的结果为 Tests run: 0, Failures: 0, Errors: 0, Skipped:
    mavn执行junit单元测试的结果为Testsrun:0,Failures:0,Errors:0,Skipped:0  [INFO]---surefire:3.2.5:test(default-test)@joyupx-trade---[INFO]Usingautodetectedproviderorg.apache.maven.surefire.junitplatform.JUnitPlatformProvider[INFO][INF......
  • 深入探究 Java 中的单元测试 Mock 技术
    在软件开发中,单元测试是确保代码质量和稳定性的重要手段。而Mock技术在单元测试中扮演着至关重要的角色,它能够帮助我们隔离外部依赖,更有效地对单个模块进行测试。本文将深入探讨Java中的单元测试Mock技术。一、单元测试与Mock技术概述单元测试是对软件中的最小可测试......
  • 深入理解单元测试:技巧与最佳实践
    之前分享过如何快速上手开源项目以及如何在开源项目里做集成测试,但还没有讲过具体的实操。今天来详细讲讲如何写单元测试。......
  • 安卓手机被偷偷安装下载App?也许问题在这里
    自己的安卓手机,设置中所有的未知来源安装已经设置为不允许,单个应用安装第三方和自动更新也已关闭,但是有一天在微博上突然还是遇到了难以关闭的强制页面和偷偷直接安装了很多推广应用, 百思不得其解,终于还是要打算研究下到底怎么回事?首先,在设置中安装未知来源这个选项下的应用......
  • 单元测试框架 powermock
    单元测试框架powermock  在pom.xml加入依赖包:<dependency><groupId>org.powermock</groupId><artifactId>powermock-api-mockito2</artifactId><version>${powermock.version}</version><scope>test</scope&......
  • 单元测试框架 mockito
    单元测试框架mockito 1、在项目的pom.xml引入 mockito的依赖:<dependency><groupId>org.mockito</groupId><artifactId>mockito-inline</artifactId><scope>test</scope></dependency>2、模拟Spring的消息源对象:@MockMes......
  • 编写 Django 单元测试的更优雅的方法
    我目前正在使用Django的单元测试(基于Python标准库模块:unittest)编写测试。我已经为我的Contact模型编写了这个测试,它通过了:classContactTestCase(TestCase):defsetUp(self):"""Createmodelobjects."""Contact.objects.create(nam......
  • 超快速的百度网盘不限速下载技巧,建议偷偷使用!
    小伙伴们,你们是否曾经为百度迅雷网盘限速而烦恼呢?动不动就要冲svip会员,不仅费钱,开通后还慢的气死,我现在来介绍一种全新的高效下载方法吧,只需要下载并安装一款神奇的软件,接着简单操作即可轻松实现快速下载,节省时间,这款神奇的软件具体信息在文章最后有说明。第一:你只需要将要下载的......