程序员的测试课

news2024/11/17 10:02:26

git项目地址:GitHub - dreamhead/geektime-todo: Geektime Todo is a demo todo project for Geektime column.

1、实现一个Todo应用

设计规范
1、对于输入参数的检测,由入口部分代码进行处理。如空字符串。
2、Repository 的问题以运行时异常 的形式抛出,业务层不需要做任何处理 如存储到Repository的时候出现问题如存储到磁盘但磁盘满了

先写单元测试代码,再写代码。

2、实现一个todo的应用下


 

 测试覆盖率给了我们发现代码问题的机会。
在构建脚本设定的测试覆盖率是 100%,所 以,只要有测试覆盖不到的地方就会被发现。

3、程序员的测试与测试人员的测试有什么不同?

有意识地在写代码的时候编写测试,尽自己所能把各种场景考虑到。
只要团队里有合格的测试人员,他总会以你想不到的角度,发现系统中意想不到的问题
程序员的出发点是实现,而测试人员的出发点是业务。
目前大多数团队的情况是,测试人员并没有得到充分的发挥。只有程序员做好了自己的测
试,测试人员才能从日常琐碎的验证工作中解脱出来,去做更有价值的测试
如果程序员能够把自己的测试做好,很多问题就应 该被消灭在萌芽状态,根本不应该到测试同学这里。


向测试学习


1、业务视角,
但无论是什么样的测试工具,都只是提升效率的一种手段。如果没有背后的测试思维支撑,再好的工具,也是没用的。
2、学会设计测试,找到更多的测试场景。
程序员每多想到一点,软件质量就能多提高一点
测试人员设计好用例后共享,让程序员能够又一个参考去编写自己的测试。(很少有写单元测试的开发)
测试从测试场景入手,多考虑各种情况,尤其是异常情况。

4、自动化测试:为什么程序员做测试其实是有优势的?

程序员在测试上的优势所在,也就是自动化
理解自动化测试框架,主要包含两个部分:组织测试的结构以及断言。组织测试的结构最
核心的就是测试用例如何写,以及 setUp 和 tearDown 函数。而断言则是保证了我们测试
的目标。断言程序库有很多,你可以根据自己的喜好进行选择。除了断言程序库,Mock
框架的 verify 也是一种断言。


如果今天的内容你只能记住一件事,那请记住:没有断言的测试不是好测试。

05 | 一个好的自动化测试长什么样?

1、把测试写简单,简单,到一目了然,不需要证明它的正确性。


2、一个自动化测试用例,的结构分别是准备、执行、断言和清理。其中,核心的部分是执行和断
言。一个测试既不能执行太多的东西,也不能没有断言。


3、如何衡量一个测试有没有做好?-A-TRIP标准
Automatic,自动化;--需要有断言
Thorough,全面的;-测试覆盖各种场景
Repeatable,可重复的; 能够反复执行,并且结果都是一样


影响一个测试可重复性的主要因素是外部资源,
常见的外部资源包括文件、数据库、中间件、第三方服务等等。如果在测试中遇到这些外
部资源,我们就要想办法让这些资源在测试结束后,恢复原来的样子。


Independent,独立的; 测试和测试之间不应该有任何依赖。
Professional,专业的 按照代码的标准去维护。这就意味着你的测试代码也要写得清晰,比如良好的命名、把函数写小、要重构甚至要抽象出测试的基础库、测试的模式


测试用例命名:
should_ 测试场景;
should_ 测试效果 _while_ 测试条件。
 

 06 | 测试不好做,为什么会和设计有关系?

测试不好做,实际是可测试性不好,原因是代码没设计好。
如何编写可测试的代码,最简单的回答就是让自己的代码符合软件设计原则。
编写可测试的代码,如果只记住一个通用规则,那就是编写可组合的代码。

07 | Mock 框架:怎么让测试变得可控?

Mock 框架的基本逻辑很简单,创建一个模拟对象并设置它的行为,主要就是用什么样的
参数调用时,给出怎样的反馈。


08 | 单元测试应该怎么写?

如何去写单元测试。很多团队由于多方面的原因(比如设计做得不好),导 致单元测试写得少。但为了提高代码质量以及更准确地定位问题,我们应该多写单元测 试。

单元测试最好是和实现代码一起写,以便减少后续补测试的痛苦。想写好测试,关键要做 好任务分解,否则,面对一个巨大的需求,没有人知道如何去给它写单元测试。

编写单元测试的过程,实际上就是一个任务开发的过程。一个任务代码的完成,不仅仅是 写了实现代码,还要通过相应的测试。一般而言,任务开发要先设计相应的接口,确定其 行为,然后根据这个接口设计相应的测试用例,最后,把这些用例实例化成一个个具体的 单元测试。

单元测试常见的一个问题是代码一重构,单元测试就崩溃。这很大程度上是由于测试对实 现细节的依赖过于紧密。一般来说,单元测试最好是面向接口行为来设计,因为这是一个 更宽泛的要求。其实,在测试中的很多细节也可以考虑设置得宽泛一些,比如模拟对象的 设置、模拟服务器的设置等等。

如果今天的内容你只能记住一件事,那请记住:做好任务分解,写好单元测试。

09 | 测试覆盖率:如何找出没有测试到的代码?

测试覆盖率是一种度量指标,指的是在运行一个测试集合时,代码被执行的比例
常见的测试覆盖率指标
有下面这几种:

函数覆盖率(Function coverage):代码中定义的函数有多少得到了调用;
语句覆盖率(Statement coverage):代码中有多少语句得到了执行;
分支覆盖率(Branches coverage):控制结构中的分支有多少得到了执行(比如 if 语
句中的条件);
条件覆盖率(Condition coverage):每个布尔表达式的子表达式是否都检查过 true
和 false 的不同情况;
行覆盖率(Line coverage):代码中有多少行得到了测试


JaCoCo:一个 Java 的测试覆盖率工具

JaCoCo 是 Java 社区常用的一个测试覆盖率工具JaCoCo 是 Java 社区常用的一个测试覆盖率工具
把测试覆盖率与提交过程联系起来。我们在实战中,提交之前要运行检查过程。

         测试覆盖率是帮我们发现在测试中没有覆盖到的代码,也就是帮助我们在测试之外查缺补漏。
        测试覆盖率实际上是一组不同指标的组合,所谓覆盖率就是运行一组测试,执行到的元素
和总的元素比例。大部分指标都比较好理解,只是条件覆盖率要求比较高,与其通过测试
覆盖那么多的条件,不如把代码本身写简单,降低测试的难度。
     我以 JaCoCo 为例,给你介绍了一个测试覆盖率工具,其中的 counter 对应着测试覆盖率
的指标。在实际的项目中使用测试覆盖率工具,关键是要把它与自动化的过程结合起来,
让它不是独立的存在。每次提交,每次 CI 过程都要进行测试覆盖率的检查。
     最后我们还讲到了如何通过测试覆盖率的报告找到未覆盖的代码,定位到问题之后,补齐
测试对于大多数程序员来说还是相对容易的。
       如果今天的内容你只能记住一件事,那请记住:将测试覆盖率的检查加入到自动化过程之
中。

10 | 为什么 100% 的测试覆盖率是可以做到的?

要尽可能地把自己的工作数字化

要想写好测试,一个关键点是要有良好的软件设计,而且代码
本身要尽可能地消除坏味道。

我们强调的 100% 测试覆盖,主要指的是对自己编写的代码 100% 测试覆盖。这就意味
着,我们一方面要保证自己的代码完全可控,另一方面,对于影响到测试覆盖的第三方代
码要进行隔离。

要想做到 100% 的测试覆盖,技术上说,要有可测试的设计以及编写整洁
的代码,实践上看,要测试和代码同步产出。

100% 的测试覆盖并不是说代码没有问题了,而应该是程序员对自己编写代码的一种质量
保证,它是一个帮助我们查缺补漏的过程。
对于无法测试到第三方代码,要用一个薄薄的隔离层将代码隔离出去,在构建脚本中将隔
离层排除在外。有一点需要注意的是,排除脚本千万别被滥用了。

如果今天的内容你只能记住一件事,那请记住:100% 的测试覆盖率是程序员编写高质量
代码的保证。

TDD写出来的代码一般情况覆盖率都是100%

11 | 集成测试:单元测试可以解决所有问题吗?

今天我们讲了集成测试,相对于单元测试只关注单元行为,集成测试关注的多个组件协同 工作的表现。今天我们讨论了两类典型的集成问题,一种是代码之间的集成,一种是代码 与外部组件的集成。 对代码之间的集成来说,一方面要考虑我们自己编写的各个单元如何协作;另一方面,在 使用各种框架的情况下,要考虑与框架的集成。如果我们有了单元测试,这种集成主要是 关心链路的通畅,所以一般来说我们只要沿着一条执行路径,把相关的代码组装到一起进 行测试就可以了

如果涉及框架,最好是能够把框架集成一起做了,设计得比较好的框架是对于测试的支持 比较好的(比如像 Spring Boot),可以让我们很方便地进行测试。 对于外部组件的集成而言,难点在于如何控制外部组件的状态。数据库在这方面相对已经 有比较成熟的解决方案:使用单独的数据库,以及在测试结束之后进行回滚。 但大部分系统没有这么好的解决方案,尤其是第三方的服务。这时候,我们就要看有没有 合适的替代方案。对于大多数 REST API,我们可以采用模拟服务器对服务进行模拟。 通过今天的讨论你会发现,严格地说,有些代码由于基础设施的问题是不容易在自动化场 景覆盖的,这也是我们为什么要强调与框架结合的代码一定要薄,让这种代码的影响尽可 能少。这也是在减少用上层测试覆盖的工作量。

到这里,大部分的场景我们都已经可以用自动化测试进行覆盖了,我们对自己的系统已经 有了更完整的理解。其实,测试的种类还有更多,比如系统测试,把整个系统集成起来测 试;验收测试,交由业务人员或测试人员进行测试。但这些测试对于很多团队来说,已经 到了测试人员的工作范畴了。作为程序员,我们能够把单元测试和集成测试做好,整个软 件的质量已经是初步合格了。

如果今天的内容你只能记住一件事,那请记住:想办法将不同组件集成起来进行测试。

12 | 实战:将 ToDo 应用扩展为一个 REST 服务

集成测试回滚数据,保证测试的可重复 性。

13 | 在 Spring 项目中如何进行单元测试?

15 | 测试应该怎么配比?

冰淇淋模型

金字塔模型

 

 

 从实用的角度上看,我们不 太可能用各种类型的测试做所有代码的覆盖,这是一种浪费。 在决定如何配比各种类型的测试前,你首先要了解各种测试的特点。比如,单元测试速度 快成本低,但覆盖面小;集成测试和系统测试覆盖面大,但速度慢成本高。

行业中目前有两种典型的测试模型:冰淇淋蛋卷和测试金字塔。二者对于测试的配比要求 刚好相反,冰淇淋蛋卷要求多写高层测试,而测试金字塔则希望多写低层测试。 行业中的最佳实践是测试金字塔,这是每个新项目都应该做到的。

对于遗留项目,我们可 以在一开始的时候,先采用冰淇淋蛋卷建立基础的安全网,在有了最低保障之后,开始向测试金字塔方向努力。 如果今天的内容你只能记住一件事,那请记住:新项目采用测试金字塔,遗留项目从冰淇 淋蛋卷出发。

16 | 怎么在遗留系统上写测试?

今天我们谈到了在遗留系统上写测试。遗留系统就是那些没有测试的系统,给遗留系统写 测试就是让一个系统恢复正常的过程。 在遗留系统上做改进,关键是要知道改进成什么样子。在一个遗留系统上写测试,不仅是 写测试,还会牵扯到写代码。 完整地给一个遗留系统写测试是比较困难的。一个实用的改进策略是,动到哪里,改哪 里。具体如何写测试,最好是测试的层次越低越好,但低层次的测试就会涉及代码耦合的 问题,而这里就需要我们对代码进行解耦。 解耦,主要是把业务代码和具体实现分开。通过提取方法,把一段耦合紧密的代码隔离 开,再创建一个新的封装类把它挪进去。如果代码里有很多具体类,我们还可以通过引入 接口进行解耦。这里面的关键是利用 IDE 给我们提供的重构功能,减少手工改代码的操 作。 如果今天的内容你只能记住一件事,那请记住:改造遗留系统的关键是解耦。

17 | TDD 就是先写测试后写代码吗?

TDD 的一个关键要素,TDD 的节奏:红 - 绿 - 重构

 测试先行开发和测试驱动开发的差异就在重构上。

重构就是一个消除代码坏味道的过程。

测试驱动开发要从任务分解 开始。

为了写测试,首先“驱动”着我们把需求分解成一个一个的任务,然 后会“驱动”着我们给出一个可测试的设计,而在具体的写代码阶段,又会“驱动”着我 们不断改进写出来的代码。把这些内容结合起来看,我们真的是在用测试“驱动”着开 发。

无论你是否采用 TDD 的实践,在动手写代码之前,从测试的角度进行思考都是非常有价值 的一件事,这也是编写高质量代码的重要一环。 如果今天的内容你只能记住一件事,那请记住:从测试的视角出发看待代码。

18 | BDD 是什么东西?

今天最流行的 BDD 框架应该是 Cucumber

BDD,也就是行为驱动开发。这种思想是站在 xUnit 的框架基础之上, 让测试用例的表达更贴近业务行为。

BDD示例

核心点就是它的描述格 式:“Given…When…Then”。Given 表示一个假设前提,When 表示具体的操作, Then 则对应着这个用例要验证的结果。

BDD是站在业务的角度

想 写好 BDD 的测试用例,关键点在用业务视角描述。 

了 BDD 的延伸,无论是 BDD 风格的单元测试框架,还是活文档、实例 化需求,这些都是你可以进一步探索的东西。 如果今天的内容你只能记住一件事,那请记住:技术团队要更加贴近业务。

总结

软件质量的病不在外部,而在内部。一个没有质量意识的团队只靠外部的推动很难做出高 质量软件

软件质量要想得到真正的提升,要将做到 内建质量(Build Quality In)。

内建质量,就是将质量的思考内建于软件开发的全生命周期中。

内建质量就是要把软件开发中的每一个环节都加入 质量的考虑:

业务负责人不能只要求上线日期,也要给出需求验证的业务目标和业务的验收标准; 产品经理不只是要给出产品说明,更要给出每个需求点的验收标准; 程序员不只给出代码,还要给出覆盖每行代码的自动化测试。

所谓内建质量,本质上就是用任务分解的方式,让每个环节都交付满足一定质量标准的交 付物

写代码时问问自己,这段代码应该怎么测

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

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

相关文章

Django+Celery+Flower实现异步和定时任务及其监控告警

用Django框架进行web开发非常的快捷方便,但Django框架请求/响应是同步的。但我们在实际项目中经常会碰到一些耗时的不能立即返回请求结果任务如:数据爬取、发邮件等,如果常时间等待对用户体验不是很好,在这种情况下就需要实现异步…

SOFA Weekly|2023 我们一起加油、本周 Contributor QA

SOFA WEEKLY | 每周精选 筛选每周精华问答,同步开源进展欢迎留言互动~SOFAStack(Scalable Open Financial Architecture Stack)是蚂蚁集团自主研发的金融级云原生架构,包含了构建金融级云原生架构所需的各个组件&#…

RocketMQ 搭建

目录 1、什么是MQ?为什么要用MQ? 2、MQ的优缺点 3、几大MQ产品特点比较 4.RocketMQ在Windows的启动 1.下载RocketMQ 4.7.1版本 2.解压到本地磁盘并配置好JAVA_HOME和ROCKETMQ_HOME 3.修改runserver.cmd 4.启动server 5.修改runbroker.cmd 6.启动…

ROS2 基础概念 服务

ROS2 基础概念 服务1. Services2. 服务类型3. 查找服务4. 服务请求1. Services 服务基于 请求-应答 模型,而不是话题的 发布-订阅 模型 虽然话题允许节点订阅数据流并获得持续更新,但服务 仅在客户端专门调用时提供数据 还是启动海龟及其遥控节点为例&…

[标准库]STM32F103R8T6 点灯以及按键扫描

刚开始学32的时候,选择了基于HAL库进行开发,原因是HAL比较容易上手,像点灯、输出PWM、按键输入这种操作都很快捷。但是到ADCDMA这部分的时候发现,HAL库有一些地方我认为不是很合理和方便。比如DMA中断这部分,ST官方给出…

音视频开发系列--H264编解码总结

一、概述 H264,通常也被称之为H264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC) 对摄像头采集的每一帧视频需要进行编码,由于视频中存在空间和时间的冗余,需要用算法来去除这些冗余。H264是专门去除这些冗余的算法…

王者荣耀崩溃解决记录

王者荣耀竟然崩溃了 上周玩王者荣耀,突然就进不去了,点击开始游戏后应用直接就崩溃退出了。 第一反应,肯定是反馈给游戏客服。但是果然腾讯的游戏是找不到真客服的,全部都是机器人处理的,给了我一个毫无用处的官方回…

springboot中配置文件优先级以及分类,这你都可以不会吗?不会赶紧进来学( ̄(∞) ̄)

各位小伙伴大家好呀┗( ▔, ▔ )┛,马上过年了,但是感觉没啥期待的哈哈哈哈哈,现在的年说实话真的挺没劲的呜呜。 言归正传,我们大家在使用springboot时难免会写各种各样的配置信息,比如port,jdbc啊这些&am…

2022这一年:阳了、变轨和逆风

又到年末了,2022这一年应该会让人记忆深刻,于我而言这一年的感受有明显的分界线,在此之前的世界温暖一些,提供着能量,让人心生探索它的纷繁多彩;今年世界变得寒冷了,展示着它的严酷与无情。阳了…

再学C语言20:循环控制语句——for循环

在while循环中,建立一个重复执行固定次数的循环涉及到3个动作: 1)初始化一个计数器 2)计数器与某个有限的值比较 3)每次执行循环,要在循环体中让计数器的值递增 其中,计数器的初始化在循环之…

【pandas】教程:6-如何计算摘要统计

Pandas 计算摘要统计 本节使用的数据为 data/titanic.csv,链接为 pandas案例和教程所使用的数据-机器学习文档类资源-CSDN文库 加载数据 import pandas as pdtitanic pd.read_csv("data/titanic.csv") titanic.head()PassengerId Survived Pclass \…

#Z0424. 树上的旅行

题目 Description 给出一棵有N个结点的树,给出Q个询问,求结点xj过结点K到节点yj的最短距离 Format Input 第一行一个数n 接下来共有n-1行,三个数u,v,len表示u和v之间存在一条边长为len 再给你Q,K。代表有Q个询问&#xff0…

视频 | bedtools使用介绍1

点击阅读原文跳转完整教案。基因组中的趣事(二)- 最长的基因2.7 million,最短的基因只有8 nt却能编码基因组中的趣事(一):这个基因编码98种转录本1 Linux初探,打开新世界的大门1.1 Linux系统简介…

10000+条数据的内容滚动功能如何实现?

遇到脑子有问题的产品经理该怎么办?如果有这么一个需求要你在一个可视区范围内不间断循环滚动几千上万条数据你会怎么去实现? 且不说提这个需求的人是不是脑子有问题,这个需求能不能实现?肯定是可以的,把数据请求回来渲…

2022蓝桥杯省赛C++A组初尝试

前言 耗时三个半小时,看看自己不懂的有多少,以便明确后续备赛2023方向 耗时3个半小时,只拿了18分,没学过,时间再多也做不出来,有奥数那感觉了 据说蓝桥杯省3得做对 2填空 2大题(30分&#x…

PMP®项目管理|不同场景使用不同沟通方式

不同沟通方式的确有适用场景和不适用场景。无效沟通的重要原因之一就是错误选择沟通方式。 我们会在工作中用到很多沟通方式,每种沟通方式都有适用的场合,也有不适用的场合,错误选择将使沟通变得低效甚至无效。 沟通方式主要有三种&#xf…

一百种语言的LOVE

2023年快要到来啦,很高兴这次我们又能一起度过~ 目录 一、前言 二、详细介绍 三、效果展示 四、代码编写 index.html script.js style.css 五、获取代码 需要源码,可以私信我(⊙o⊙)?关注我? 一、前言 时光荏苒&#xf…

vue element-ui 手机号校验 验证码校验 获取验证码倒数60秒无样式实现

这段时间被迫搞前端搞裂开了,记录一下手机号验证码校验登录的极简无样式前端实现 巨丑!希望大佬们不介意 下面是先演示效果 点击登陆后显示校验信息 输入手机号点击获取验证码 输入符合校验的内容后点击登录提示成功 无后端交互!&#…

从档案信息管理到档案知识管理

今年6月份的时候,笔者发过一篇文章《DIKW模型在档案信息资源开发中的应用》,简要阐述了知识管理领域非常著名的DIKW模型,即从数据(Data)→信息(Information)→知识(Knowledge&#x…

基于SpringBoot和微信小程序的餐馆点餐系统的设计和实现

作者主页:Designer 小郑 作者简介:Java全栈软件工程师一枚,来自浙江宁波,负责开发管理公司OA项目,专注软件前后端开发(Vue、SpringBoot和微信小程序)、系统定制、远程技术指导。CSDN学院、蓝桥云…