Erlang 从零 · 第 24 课(展开目录)
01 · 先打开 erl02 · 先认常见 term03 · 分清两种文字04 · 变量只接一次05 · 拆开一列,再筛一次06 · 把文字安全变成整数07 · 用 case 选一条路08 · 让函数继续走09 · 把代码放进模块10 · 条件必须说真话11 · 一层一层取数据12 · 文字先说清编码13 · 让函数子句排好队14 · 带着累加器往前走15 · 先看值,再选路16 · 给模块立规矩17 · 让 rebar3 管项目18 · 让结果有固定形状19 · 把磁盘当成会失败的邻居20 · 把函数交给 list21 · record 留在院里22 · 先写模块之间的约定23 · 把 term 形状写出来24 · 小测试与整段路25 · 把应用磨成命令26 · 先把小项目圈住27 · 把真实文件洗干净28 · 公开入口越少越稳29 · 把约定留在源码旁30 · 打包,也留下线索31 · 按最初任务交卷
ERLANG · 进阶 · LESSON 2445 分钟

小测试与整段路

用 EUnit 守住纯函数,用 Common Test 检查较长场景。

01 · 先看完整例子

把折扣边界写进 EUnit

生成器返回多条测试,任一失败会指出对应断言。

Erlang
-include_lib("eunit/include/eunit.hrl").

discount_test_() ->
  [
    %% 满 10 件打九折
    ?_assertEqual(90.0, discount:price(100, 10)),

    %% 9 件仍按原价
    ?_assertEqual(100, discount:price(100, 9))
  ].
先对照结果
  • 实现符合规则时,两条 EUnit 测试通过。
02 · 回头拆代码

从第一行往下读

  1. 两个输入落在规则边界两侧。
  2. EUnit 不需要外部资源,适合并保持快速。
  3. 若以后测试文件服务或多进程协作,再考虑 Common Test fixture。
03 · 认清新符号

符号不是暗号

?assertEqual

EUnit 的相等断言。

_test_

EUnit 测试生成器命名后缀。

rebar3 ct

运行 Common Test suite。

04 · 代码里的概念

把名字和意思对上

01

test fixture

测试运行前准备、运行后清理的资源或数据。

02

test suite

Common Test 中按场景组织的一组测试用例。

05 · 再说清楚

这些写法为什么有用

EUnit 适合一个函数、一个模块的短测试。Common Test 用 suite 组织更长场景,常见于多个组件或真实资源。

先用最轻工具。两行能讲清的纯函数测试,不必搭一整套 suite。

正常、边界、错误输入都要考虑。测试名或生成器结构应让失败位置清楚。

06 · 自己改一次

合上答案,动手

增加数量为 0 的边界测试。

练习起点
?_assertEqual(____, discount:price(80, ____))

目标结果: 期待 discount:price(80,0) 返回 80。

卡住了,再看提示

两个空分别是 80 和 0。

运行过以后,再看一种答案
一种答案
%% 零也是值得保存的边界
?_assertEqual(80, discount:price(80, 0))
想一想:所有 Erlang 测试都应该使用 Common Test 吗?

不应该。纯函数与小模块先用 EUnit;需要 suite 生命周期和较长集成场景时再用 Common Test。

带走

记住三句

  1. 1

    测试工具按场景大小选择。

  2. 2

    EUnit 适合快速单元测试。

  3. 3

    Common Test 适合带 fixture 的长场景。

本课结束代码也跑过一次,就把这一课收好。