🔍
Jestのカバレッジをお手軽にチェックする
結論
- Jestは実行時に
--coverageReporters=json-summary
オプションをつけることでsummaryのjsonを出力してくれる - summaryのjsonからtotalのpercentを取得できる
- totalのpercentを基に簡易的なカバレッジのしきい値チェックができる!
はじめに
ふと急に、circleci上でお手軽にカバレッジのしきい値チェックがしたくなった
circleciのドキュメントに書いてあるが、コードカバレッジ用に便利な機能が包括された良さげなサービスにお任せすればやりたいことはできそうだったが、Jestだけで気軽にできないかしらとオプション調べてたら良さげなオプションがあったので、このオプションを使って、しきい値チェックのscriptを作ることにした
記事のターゲット
- Jestで簡単な[1]カバレッジのチェックがしたい人
環境
package.json
{
"devDependencies": {
"jest": "26.6.3",
"ts-node": "10.2.1",
"typescript": "4.4.3",
}
}
カバレッジの結果をjsonに出力する
結論でも書きましたが、summaryの結果を出力するオプションを追加してJestを実行します
package.json
{
"scripts": {
"test-total-coverage": "jest --collectCoverage=true --coverageReporters=json-summary",
}
}
デフォルトではcoverage/coverage-summary.json
に出力されるはず
しきい値チェックのscriptを作る
-
coverage/coverage-summary.json
の読み込み - チェックしたい項目の値を取得
- しきい値より低くないかチェックする
coverage-summary.jsonはこんな感じ
coverage/coverage-summary.json
{
"total": {
"lines":{
"total":1480,
"covered":413,
"skipped":0,
"pct":27.91
},
"statements":{
"total":1566,
"covered":423,
"skipped":0,
"pct":27.01
},
"functions":{
"total":594,
"covered":193,
"skipped":0,
"pct":32.49
},
"branches":{
"total":763,
"covered":171,
"skipped":0,
"pct":22.41
}
},
// 以降、ディレクトリやファイルごとの値がつらつらと出力される
}
pctが低いことに気づいたそんな感の良い人はキライです
今回はFunctionsのパーセントが80%より下回ったらCIが落ちるように書いてみました(項目としきい値はテキトウです)
scripts/check-coverage/index.ts
import { readFileSync } from 'fs'
// 出力されるjsonを見て、型をお気持ち程度に定義
type CoverageColumn = {
total: number
covered: number
skipped: number
pct: number
}
type CoverageType = 'lines' | 'statements' | 'functions' | 'branches'
type CoverageValue = { [key in CoverageType]: CoverageColumn }
type Coverage = { [key: string]: CoverageValue }
const main = () => {
try {
// NOTE:(yota-hada) 今回はこのscriptをscripts/check-coverage/index.tsにおいたので、root直下からcoverage/coverage-summary.jsonにアクセスするために余分なpathを消してる
const dirNames = __dirname.split('/')
const filterNames = dirNames.filter(
(dirName) => dirName !== 'scripts' && dirName !== 'check-coverage',
)
const dir = filterNames.join('/')
const input = JSON.parse(
readFileSync(`${dir}/coverage/coverage-summary.json`, 'utf-8'),
) as Coverage
const functionCoverage = input.total.functions.pct
// しきい値ってどれくらいが良いんでしょね
const mustCoverage = 80
if (functionCoverage < mustCoverage) {
// HACK:(yota-hada) 別途カバレッジをcircleciのartifactsなどにアップロードしておき、詳細を確認できるようにしとくともっと良き
const errMsg = 'テストのカバレッジ(Functions)が低すぎます。今すぐテストを書くのです'
throw new Error(errMsg)
}
} catch (e) {
console.error(e)
process.exit(1)
}
}
main()
CIでスクリプトを実行する
ciで呼びやすいようにscriptsに使うものは登録しときます
package.json
{
"scripts": {
"test-total-coverage": "jest --collectCoverage=true --coverageReporters=json-summary",
"check-coverage": "ts-node --project scripts/tsconfig.json scripts/check-coverage/main.ts",
}
}
※ts-nodeを実行する時はscript用のtsconfigを指定してます
あとは定義したスクリプトを呼んであげる(下記はcircleciの場合)
これで簡単なカバレッジのしきい値チェックがCI上できるようになりやす
config.yml
- run:
name: Report total coverage
command: yarn test-total-coverage
- run:
name: Check total coverage
command: yarn check-coverage
宣伝
Jest逆引き テストケース
ってタイトルでスクラップを作っており、他の方の投稿も許可してるので、コメントでも新しいテストケース(Jest単体のでも、Testing Libraryを使ったのでも、なんでも)でも書いてもらえるとうれしいデス!
-
ここで言う
簡単な
とは、StatementsやBranches、Functionsのtotalのパーセントが一定の値を下回ってないかCIで軽くチェックしたいぐらいの温度感を指しています ↩︎
Discussion