视频:COMP1531 Week 3 Lecture 1(2026-09-29,约 1:50) 来源:本地 ASR 转写 + 视频截帧整理,非官方材料,细节以视频和 spec 为准。时间均为视频时间,点链接直接跳转。
本讲两位讲师:前半节 Rani Jiang 讲 Iteration 1,并用 clearData 演示一个 feature 的完整流程;后半节讲 Dynamic Verification 和 Code Coverage。
- 0:24:59–0:30:51 是现场 debug,可以跳过。
- 0:53:30–1:04:20 是课间休息。
Demo 0 · 前端 sample 演示(0:04:20–0:05:35)
- 演示 tutor 写的终端界面(TUI)闪卡 app:新建卡片(Q: best CSE course / A: COMP1531),建 deck,再往 deck 里加卡。
- 讲师说这只是 sample,不是 reference solution,他们实现时也做了自己的假设。
Demo A · 用 clearData 走完一个 feature 的完整流程(0:14:42–0:50:28)
- 0:14:44:合并 GitLab 上的 "[Iteration 1] Updated Starter Code" MR(不用 approve,有冲突就照常解决)
- 0:15:52:在 Issue board 新建 work item
clearData,打标签 core、critical、in progress,链接 spec,设 due date - 0:17:45:
git checkout -b iter1-clearData - 0:18:26:在
interface.js写 stub:clearData()返回{}。data对象是{cards: [], decks: [], studySessions: []};clearData 把三个数组都重置成[],然后 commit - 0:23:00:新建
src/clearData.test.js。测试按三类想:返回值、副作用、错误(clearData 没有错误情况)。第一个测试是test('return value', () => expect(clearData()).toStrictEqual({})) - 0:24:59–0:30:51:现场 debug,可以跳过:报 vitest not found,接着是
ERR_MODULE_NOT_FOUND。最后的解法:rm -rf node_modules、删掉package-lock.json、npm cache clean --force、npm install - 0:32:31 / 0:33:26:先讲 automarking 也会看 coverage,然后跑
npm run coverage。屏幕上interface.js是 Stmts 62.5%、Funcs 50%,未覆盖第 16–27 行 - 0:34:07:为什么要测副作用:把清空的代码注释掉,返回值测试照样能过。副作用测试的思路是
cardsCreate→clearData→cardsView应该查不到;deck 同理 - 0:35:17:循环依赖:
cardsView、decksList队友还没写完怎么办?三种办法:先注释掉并在 MR 里写明、用test.todo(...)、用test.skip(...) - 0:40:27:
git commit -m "feat: add initial tests for clear" - 0:41:29:重构拆文件:新建
clearData.js(放doClearData),interface.js里只写return doClearData();data挪到dataStore.js里 export。重跑测试全部通过,有测试才敢放心重构。commit 是"feat: refactor clear to be in separate file" - 0:44:00:
git push --set-upstream origin iter1-clearData,建 MR,标题带 issue 号("43 - clearData feature"),assign 自己并加 reviewer。要不要删源分支问 tutor。之后队友 review、留评论、approve、merge,最后把 issue 拖到 closed - 0:46:36:提交前检查:在 CSE 上跑
1531 iter1-dryrun,加--show-tests能看到测试内容。现场 dryrun 报错了,讲师说之后会修 - 0:49:21:跑课程前端做 sanity check:报
decksList failed: Not implemented,现场补一个 stub 后又报下一个没实现的函数 - 0:50:28:Q&A:要不要一个函数一个文件?组里自己取舍,有理由就行
要点
- 一个 feature 的完整流程:issue → branch → 实现 + 测试 → commit → push → MR → review → merge → 关 issue。
- 只测返回值不够,要测副作用。
- 依赖的函数还没写完时,用
test.todo/test.skip先占位。 interface.js只负责转发,实现放在独立文件里,这样文件更整洁,也能减少 merge conflict。
Demo B · 动态验证 + Code Coverage(1:30:29–1:49:47)
代码在 GitLab 的 lecture 仓库 3.1-Dynamic-Verification,文件夹是 2.4-dynamic-verification。
- 1:32:02:回顾
removeVowels.test.js的 import/export;clone 下来没有node_modules,先npm install - 1:34:23:跑测试,代码里故意留的错误让测试失败,改好后通过
- 1:35:20:
package.json的 scripts:"test": "vitest run"、"coverage": "vitest run --coverage"。对比npm test(跑全部)和只跑单个文件 - 1:36:24:
grade.js的computeGrade(mark):≥85 HD、≥75 DN、≥65 CR、≥50 PS,其余 FL - 1:37:24:删掉 DN 的测试,测试仍然全部通过,说明全绿不等于测全了
- 1:39:04:加
--coverage:grade.js是 Stmts 77.77%、Branch 75%、Funcs 100%,未覆盖第 7、13 行 - 1:41:12:打开
coverage/index.html网页报告,没覆盖的行会高亮 - 1:42:11:补回 DN 测试后变成 88.88%、Branch 87.5%,只剩第 13 行(FL 分支)
- 1:43:06:讨论:要盯着没覆盖的部分,而不是追百分比;branches 比 functions 更重要;一个函数一个文件对 coverage 没帮助
- 1:46:40:一句话定义:dynamic verification 就是测输出是否符合预期
- 1:48:15:加
test('returns FL for below 50'),computeGrade(45)应返回'FL'(AI 补全的),到 1:49:40 达到 100% - 1:49:07:100% 覆盖仍然不够:负分和超过 100 的分数也会被接受,边界情况没测到
要点
- 看 coverage 报告时,先看 Uncovered Line #s 和 HTML 报告里高亮的行,不要只盯着百分比。
- Branch coverage 比 function coverage 更能说明问题。
- 覆盖率 100% 不代表测试足够,边界情况(edge cases)要另外考虑。