单元测试是为了提高代码的质量规范代码,单元测试不仅可以保证当前代码的正确性,也能保证在持续迭代的过程中保证代码的正确性
实现自动化的目标
- 实现项目的单元测试覆盖率目标
- gitlab ci和单元测试结合
- 可视化单元测试报告
要实现以上目标,需要大致了解gitlab相关知识和jest测试框架的基本使用。
方案
方案一
- 完成本地代码修改 - 修改业务代码
- 代码提交Gitlab - 通将修改好的代码通过git命令提交到仓库
- 触发Gitlab CI - 通过gitlab-ci.yml配置CI脚本,触发相对应的job。并执行脚本
- 执行测试脚本 - CI在执行脚本的过程中,执行项目中的测试命令
- 可视化测试覆盖率 - 将测试结果展示在Homepage上
方案二
- 完成本地代码修改 - 修改业务代码
- 代码提交Gitlab - 通将修改好的代码通过git命令提交到仓库
- 通过Git Hook触发测试脚本 - 通过husky配置当代码在本地进行提交的过程中,执行test ci脚本
- 代码上传 - 提交代码致仓库
- 通过Gitlab Page可视化单侧结果 - 配置gitlab setting配置静态网站展示执行单侧结果
由于方案二的一定局限性,所以选择方案一:
- 方案二在开发过程中,由于切换分支会进行暂时commit 操作,导致执行单侧,不是目标策略。
- 方案二代码会提交单侧报告,代码冗余
- 方案二由于gitlab权限问题,没有page设置权限,无法进行静态资源展示配置
- 方案一具有分支控制优势,可配置仅在master分支改动时执行单元测试
依赖
当前主要依赖于jest和jest-junit,进行单侧编辑时,需要依赖@types/jest
包 | 版本 | 备注 |
---|---|---|
jest | ^27.2.5 | Complete and ready to set-up JavaScript testing solution |
jest-junit | ^13.0.0 | A Jest reporter that creates compatible junit xml files |
使用
依赖测试框架实现测试用例。
代码示例如下:
import { Test, TestingModule } from '@nestjs/testing'
import { Module } from './*.module'
import { Service } from './*.service'
describe('Service', () => {
let service: Service
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [Module]
}).compile()
service = module.get<Service>(Service)
})
describe('checkPermission', () => {
it('checkPermission', async () => {
// 业务代码
})
})
})
配置
目前配置主要分为两个部分
- jest 相关配置
- gitlab ci相关配置
- gitlab 配置
jest配置
jest test脚本执行规则。
比较重要的几个参数:
- 文件匹配: testRegex
- 别名映射: moduleNameMapper
- 输出目录: coverageDirectory
- 报告文件: coverageReporters
"jest": {
"moduleFileExtensions": [
"ts",
"js",
"json",
"node"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"moduleNameMapper": {
"^@/(.*)$": "<rootDir>/src/$1"
},
"collectCoverage": true,
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"coverageReporters": [
"cobertura",
"text",
"html",
"text-summary"
],
"testEnvironment": "node",
"coverageThreshold": {
"global": {
"statements": 80
}
}
},
gitlab-ci.yml配置
主要目的是触发gitlab CI pipeline
这部分使用到gitlab ci相关配置项,建议阅读官方文档docs.gitlab.com/ee/ci/yaml/…
image: node:12-slim
# CI_MERGE_REQUEST_TARGET_BRANCH_NAME 合并请求的目标分支名称。
# CI_MERGE_REQUEST_SOURCE_BRANCH_NAME 合并请求的源分支名称
# CI_COMMIT_BRANCH 提交分支名称。在分支管道中可用,包括默认分支的管道。在合并请求管道或标签管道中不可用。
stages:
- build
- test
- deploy
build:
stage: build
script:
- yarn
cache:
paths:
- node_modules/
artifacts:
expire_in: 1 days
when: on_success
paths:
- node_modules/
test:
stage: test
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
allow_failure: true
dependencies:
- build
script:
- npm run test:ci
cache:
paths:
- coverage/
artifacts:
when: always
reports:
junit:
- junit.xml
cobertura: coverage/cobertura-coverage.xml
pages:
stage: deploy
dependencies:
- test
script:
- mkdir .public
- cp -r coverage/* .public
- - mv .public public
artifacts:
paths:
- public
only:
- master
gitlab 配置
主要目的是为了让单元测试覆盖率可视化
大致流程
gitlab展示
找到Test coverage parsing 配置项,输入以下字符
Lines\s*:\s*(\d+.?\d*)%
创建自定义Badges
根据提示自定义pipelines 图标和coverage图标
配置Readme.md
在readme.md加上配置好的图标,这里可以参考配置项的地址
[](https://example.gitlab.com/%{project_path}/-/commits/feat-v1.0.0)
最终我们可以得到以下展示:
命令
执行test:ci脚本
"test:ci"`` : ``"jest --config ./jest.config.js --collectCoverage --coverageDirectory="./coverage" --ci --reporters=default --reporters=jest-junit --watchAll=false"
结束语
2022.2.11
木更