背景
- 特性验证的问题
- 开发人员在进行开发、上线过程中,基本可以认为是 coding->testing->coding->testing 的循环。
- 随着项目复杂度越来越高,testing 的成本自然越来越大。
- 复杂度到达一定程度后,代码变更导致的 testing 成本会大到影响正常迭代,此时项目无法维护
- 代码 review 与 merge 操作,会对开发人员带来越来越大的心智负担
- 随着时间的推移,项目特性越来越多,越来越无法重构
- 重复行为问题
- 开发约束问题
分析
- 针对 coding 和 testing:coding 是不明确的工作,每次都会有不一样的内容;而 testing 则是明确的工作,每次都是重复工作
- 则针对 testing 的自动化,可以极大的释放生产力
单元测试落地
- 给项目添加单元测试,并不单纯只是工具使用上的变化和代码量的增加,更为本质的变化,是代码设计上的变化、开发工作模式的变化
- 上述变化,基本可以用一个词描述 – 学习成本
前端项目的单元测试落地针对的实际问题
- 在实现 web 前端应用前,至少会考虑几个要点
- 应用运行环境:pc 浏览器?移动端浏览器?app 内 webview?
- 应用展示内容:banner?文案?按钮?图片?等等
- 应用交互:点击按钮发生什么?输入文字发生什么?等等
- 故对于 web 前端应用,其项目代码中,除了纯函数部分,还充斥着大量的 io 操作(service api 调用、bom api 调用、dom api)调用
- 上述实现,就是一个个实际的测试用例
具体实践
针对上述问题对应的测试用例,基本可以分为以下几种:
- 纯函数测试:测试工具类纯函数是否符合预期
- 展示性测试:用于测试组件内容是否正常展示,展示的各项内容是否完整、正确
- 交互性测试:用于测试组件涉及的交互,是否可以正常输出,正常输出,并对输入、输出做校验
- 快照测试:快照测试让开发人员明确自身对组件的修改,会有多大的波及度,具体可看Snapshot Testing
其中交互测试是成本最高的测试,可以再细分为下面几种:
- 涉及 dom 操作的交互测试
- 涉及 bom 操作的交互测试
- 涉及 service api 的操作交互测试
另外,针对当前团队技术栈,还需要在 redux 场景下进行测试
上述测试用例具体实践方式,可以看 react+react-router+react-redux 项目单元测试实践记录
在具体实际中,针对一个组件的测试代码,其交互测试与其他测试测试代码对比,一般会是 6:1
成本与收益
持续集成落地
- 持续集成投入很低,但收益很高
- 持续集成,一般与 git 工作流结合使用,主要完成以下几个特性
- 代码推送后,完成 code lint\unit test,给出报告
- 代码请求合并前,完成 code lint\unit test,给出报告,有效减少 review 人的心智负担
- 代码 review 完成后,进行自动化部署
具体实践
- 当前团队使用 gitlab 服务进行版本管理,则可以使用 gitlab ci 对接 gitlab runner 完成持续集成
gitlab-runner 安装
- 申请好机器后,在机器下载的 gitlab runner
1
| sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-386
|
1
| sudo chmod +x /usr/local/bin/gitlab-runner
|
1
| sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
|
1 2
| sudo gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner sudo gitlab-runner start
|
gitlab-runner 注册
1
| sudo gitlab-runner register
|
1
| Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
|
- 然后输入注册 Runner 所需要的 token
- token 会分为两种:Shared Runner(针对所有项目),Specific Runner (针对特定项目)
1
| Please enter the gitlab-ci token for this runner
|
1 2
| Please enter the gitlab-ci tags for this runner (comma separated) fe-ci
|
1 2
| Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell: shell
|
1
| Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
|
- 最后回到 gitlab,使用 admin 权限账号管理 runner,找到 ‘fe-ci’ runner,在 runner 中对对应项目启用,则 runner 配置完成
.gitlab-ci.yml 文件
- 在项目根目录下创建 .gitlab-ci.yml 文件。以下是一份实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| stages: - install - codelint - test
cache: paths: - node_modules/
install:node_modules: stage: install script: - npm install tags: - fe-ci
codelint: stage: codelint script: - npm run lint tags: - fe-ci
test:coverage: stage: test script: - npm run test:coverage tags: - fe-ci
|
- 可以看到 ci 脚本分为三个阶段
- install: npm install – 安装依赖(node_modules)
- codelint: npm run lint – 代码校验
- test:coverage : npm run test:coverage – 全量单元测试并输出测试覆盖情况
cache: ...
部分表示 node_modules 需要缓存
tags: - fe-ci
表示此阶段指定使用 tags 为 ‘fe-ci’ 的 runner 进行执行
配置完成后实际运行
- 代码推送后自动运行 code lint 和 unit test
- 在 merge request settings 中打开 pipeline 相关的约束
- 则后续的 merge request 单,会需要 pipeline 运行成功后才能进行合并
参考
react+react-router+react-redux 项目单元测试实践记录
Gitlab 自动部署之二:安装 GITLAB-RUNNER