Day 29 - 浅谈测试 - 令人安心的保护网

前言

前两天我们讨论了 Clean CodeThe Clean Coder,这两本书都要提到一件很重要的事情,但前两天没有讨论到,就是关於「测试」。

所以我们今天会花一点时间聊聊测试的种类、流程,当然还有最重要的 - 「为什麽要做测试?」

但如你所见,今天已经是 29 天了,我的余日不多了(笑),所以我们会将焦点放在概念与原因,如果想要偏向实作方面的需求,欢迎到我队友的系列文 - React 前端工程师的两把刷子,有足足 30 天陪你度过欢乐测试生活!

测试是什麽?

要了解测试是什麽,可以先来看看软件开发生命周期(Software Development Lifecycles),简称 SDLC:

image alt

其实不一定是五块,有的会把两块合在一起,或者多一个 maintenance,你可以 google SDLC 看很多不同版本

虽然图上没有标示顺序,但是起点通常都是 Planning,所以循环的顺序会是这样:

  1. Planning
  2. Analysis
  3. Design
  4. Implementation
  5. Testing & integration
  6. Planning
  7. ...

从这张图你可以得知几件事:

  • 前一个要先完成,下一个才可以开始做(瀑布式开发)
  • 这五件事是一个循环这样你才会一直有工作
  • 一个专业的软件开发团队,需要人员至少就要五种(但人不一定有五个,可能更少)

透过这张图,你也能更能够理解公司或专案内其它同事,只要属於产品开发的,分别都在做什麽事。

  • 需要有人规划产品,市场上的定位是什麽,未来要走到什麽方向
  • 需要有人分析需求,设计业务及系统流程,通常会是专案内的 BA(Business Analytics) 或 SA(System Analytics)负责
  • 需要有人设计画面与流程,通常会是专案内的 UI/UX
  • 需要有人写 code,嘿对就是你
  • 需要有人测试整合交付,其实这两个职责比较远一点,通常是专案内的 QA(Quality Assurance)与 SRE(Site Reliability Engineering)

扯远了,今天的主题是测试,它是介於「程序开发之後」与「程序交付之前」的一个步骤。

测试要找出什麽?

在这个步骤,最重要的就是要把,程序中会出现 bug 的,或者不符合规格需求的东西抓出来

所以,今天如果是一个老师,要尽最大善意让他的学生成绩可以合格,所以写了一个程序,帮所有同学的分数开根号乘以 10 ((佛

如果有学生缺考没分数,程序会算出错误的答案:

程序没有 crash,但同学你的新成绩是 NaN

const students = [
    { name: 'Jack', grade: 25 },
    { name: 'Allen', grade: 49 },
    { name: 'Alice' },
    { name: 'Susan', grade: 81 }
];

const newStudents = students.map(student => {
    const newGrade = Math.sqrt(student.grade) * 10;
    return { ...student, grade: newGrade };
});

console.log(newStudents);

执行结果

[
    { name: "Jack", grade: 50 },
    { name: "Allen", grade: 70 },
    { name: "Alice", grade: NaN },
    { name: "Susan", grade: 90 }
]

下面这段 code 不会有程序方面的 bug,但是没有照着规格写:

佛心到直接帮你调成 60 分!太佛了全部的学生都哭了

const students = [
    { name: 'Jack', grade: 25 },
    { name: 'Allen', grade: 49 },
    { name: 'Alice' },
    { name: 'Susan', grade: 81 }
];

const newStudents = students.map(student => {
    const newGrade = 60;
    return { ...student, grade: newGrade };
});

console.log(newStudents);

执行结果

[
    { name: "Jack", grade: 60 },
    { name: "Allen", grade: 60 },
    { name: "Alice", grade: 60 },
    { name: "Susan", grade: 60 }
]

也就是说,测试的重点在这两项:

  • Verification - build the product right,是否符合效能、安全性、架构、设计风格等
  • Validation - build the right product,是否符合使用者需求

测试的范围

根据测试的范围来区分的话,最主要分成三块,可以用这张「测试金字塔」来表示:

testing pyramid

由下而上分别是:

  • Unit Test
    测试单一模组、可独立运作的最小单位,通常是 function,因为范围小,因此专注在 input 产出 output 的过程中,由 developer 开发後自行写 unit test,数量最多。
  • Integration Test
    构成一个模组component 的几个 function 一起测试,可能会有前後相依性(比如先取得资料库的资料,然後呈现在画面上)。
    这时会根据着重点在「过程」还是「结果」而比较有差别:
    • 过程:专注在 input 产出 output 的过程中,console、DB、API 的状况,通常由 developer 执行
    • 结果:只关注在 input 是否产出正确的 output,通常由 QA 执行
  • E2E Test
    QA 的重点戏,使用与 end-user 近似的手机版本、萤幕尺寸、Wifi 等执行环境下测试,基本上就是模拟真实的使用情境了,可以手动点点点测试,也可以写自动化测试的程序。

从上面的范围可以看到,测试其实没有一个非常清楚的分野,有的是 developer 负责,有的是 QA 负责,甚至也要看公司/专案内人力的调配,也有可能 developer 会包办 QA 的工作。

Developer 如何看待测试

对於写 code 的人来说,最不希望听到的,就是 QA 走向你的声音...

但我们自己都知道,在时间有限的情况下,开发出来的程序一定都会有 bug(不然 QA 就失业了),所以才要写测试,目的就是要确保程序「稳定」。

蛤?稳定?测试不就是要抓错误吗?

是的,正是因为测试可以「很稳定地把某个情境的错误抓出来」,所以当我们想要修改程序,提升效能或重构架构时,在不影响商业逻辑的前提下,我们可以透过测试,保障那些已经写好测试的情境,都能够正常运作(因为如果不正常就会立刻被抓出来)。

听起来很赞啊!那为什麽不是大家都在写测试?

写测试虽然看起来像是写 code 之後的事情,但事实上,testing code 应该被视为产品的一部分

因为当产品本身的商业逻辑,因为客户要求被改动了,测试的部分也要同步跟上,不然测试旧的 case 就没意义了。

如果把一个功能写完要 10 天,那加上测试大约会需要 1.5 ~ 2 倍的时间,也就是这个「产品」需要 15 ~ 20 天才算是完成。

如果站在 PM 的角度,心里肯定是五味杂陈,因为你很清楚测试是重要的,但居然要花这麽多时间!很容易就会因为时程压力,选择放弃测试,或者没有太多时间测试。

因此这部分也是 trade-off,做为 developer 的角色能做的,除了提升对於测试框架的熟练度,不然就是先针对重点、复杂功能,先写测试,用 20% 的时间测 80% 的 bug(或者应该说严重度 80%)。

结语

测试是对一个产品成熟度的指标,虽然不是说测试写得多就一定稳,但起码可以确保主要的功能都有被保护到,经过测试之後再交付出去的程序,更能够提升客户对於产品的信任度。

但很可惜的是,目前台湾看到的软件专案/公司,有满多地方其实都没有在写测试的,一来 PM 有时程压力,二来 developer 写测试的熟练度,也还没有到能够跟 PM 报告「请给我时间写测试!」的地步。

所以,如果公司有机会练习,请好好把握!如果没机会,就创造机会吧!

边境的沙漠与极地的雪
在熠熠星光的守护下
前行

参考资料

测试一定要写好写满?时间有限怎麽办?
Clean Code
The Clean Coder


<<:  卡夫卡的藏书阁【Book30】- Kafka - Sum up

>>:  【Day 29】Google Apps Script - 延伸篇 - Google sites 协作平台与 Charts Service 图表绘制服务

高档爆大量,请提高警觉

在入场,且获利後,第一件事就是要保护获利,而不是不要赔钱。 通常有几个转折点需要注意,其中高档爆大量...

DAY14 Kotlin基础 Class 2!兼第二周回顾

昨天有稍微提到 public、private 这样的东西,直接把昨天的程序拿来修改一下: fun m...

Jetpack Compose - Stateful and Stateless

相较於传统的 Android View,Jetpack Compose 在 Android 开发上还...

Day 27: 人工智慧在音乐领域的应用 (索尼-Flow Machine、谷歌-Magenta )

今天开始我们来介绍一些已经有公开发布成果或是已经有成熟软件提供用户使用的公司产品。 索尼 (Sony...

R语言-正规化回归预测-ridge & lasso (ridge & lasso regression in r)

废话不多说,直接附上code 影片含有程序码详细解说,若有误再烦请告知,谢谢 library(glm...