jest-fail-on-consoleを使って、テスト実行時のconsole.error/warnを撲滅した話

2024/10/10に公開

お疲れ様です!株式会社 CastingONEで働いているフロントエンドエンジニアの岡本です。

今回は、テスト実行時に出力されるconsole.errorconsole.warnを撲滅するために、npmパッケージjest-fail-on-consoleを導入した話を書きます。

はじめに

弊社のアプリケーションのフロントはjestとtesting-libraryを使ってテストを書いています。jestはテスト実行結果のログが大変見やすく、FAILしたテストの詳細も表示されるので、テストを書いているときには非常に助かります。

ですが、テスト実行時にconsole.errorconsole.warnが発生すると、テスト結果のログにそれらが出力され、ログが非常に見づらくなります。 console.errorconsole.warnが出力されても、テスト自体に問題なければPASSしてしまうため、気づかないまま放置されることが多く、結果的にこれがログのノイズとなってしまっていました。

console.errorconsole.warnが出力されるテストをStackblitzで用意したので、ターミナルを確認してみてください。

実際に弊社のアプリケーションでも以下のようなconsole.errorconsole.warnが散見していました。
'console.error'
'console.warn'

このような状態が続いていると、いわゆる「割れ窓理論」のようにログのノイズが増えていき、どんどんテスト結果のログが読みにくくなってしまい、FAILした箇所のような 本当に確認したいログを見つけるのに時間がかかってしまいます。。


この状態を改善するために、以下の2つの目標を設定しました。

  1. console.errorconsole.warnが出力されたテストをFAILにし、恒久的に発生しない仕組みづくり
  2. すでにログが出力されているテストのログを撲滅

1に関して、「console.errorconsole.warnが出力されるテストケースをFAILにしたいなぁ」と思い、機能を自作するつもりで色々調査をしていたところ、jest-fail-on-consoleというnpmパッケージを見つけ、これが筋が良さそうだと思い、導入することにしました!

https://www.npmjs.com/package/jest-fail-on-console

jest-fail-on-consoleについて

jest-fail-on-consoleは、jestのテスト実行時にconsole.errorconsole.warnのような、console系のログが出力された際にテストをFAILにすることができるnpmパッケージです。簡単な導入方法を以下に記載します。

インストール

npm install --save-dev jest-fail-on-console

セットアップ

jest.setup.tsのような、setupFilesAfterEnvに指定されているファイルに以下のコードを追加します。

jest.setup.ts
import failOnConsole from 'jest-fail-on-console';

failOnConsole()

// 他のjestの設定....

デフォルトの設定で、console.errorconsole.warnをテストをFAILにしてくれます。もし、console.infoconsole.logなどもFAILにしたい場合は、以下のようなオプションを設定することでFAILにすることができます。

jest.setup.ts
import failOnConsole from 'jest-fail-on-console';

- failOnConsole()
+ failOnConsole({
+   shouldFailOnLog: true,
+   shouldFailOnInfo: true,
+ })

// 他のjestの設定....

先の章で使用したStackblitzのサンプルコードにjest-fail-on-consoleを導入したものを用意したので、ターミナルを確認してみてください。

以下の画像のように、console.errorconsole.warnが出力された場合、テストがFAILするようになりました!

導入前 導入後
'jest-fail-on-console導入前の実行ログ' 'jest-fail-on-console導入後の実行ログ'

console.error/warn撲滅活動

jest-fail-on-consoleを導入することによって、console.errorconsole.warnが出力されるテストをFAILにすることができるようになり、1つ目の目標が完了しました!

しかし、この対応だけだと、すぐに2つ目の目標のすでにログが出力されているテストも修正しないと テストがFAILになってしまい、CIなどでテストが通らなくなり、開発に支障が出てしまいます。

そこでskipTestというオプションを使い、以下のような対応を行いました。

すでにログが出力されているテストのFAILを回避

jest-fail-on-consoleにはskipTestというオプションがあり、特定のファイルに対してはコンソール出力があってもFAILにしない設定ができます。これを使って、すでにログが出力されているテストファイルを一時的にスキップし、FAILを回避しました。

FAILしているテストファイルの取得

jest-fail-on-consoleのセットアップ後に、以下のコマンドを実行して、FAILしているテストファイルのパスを取得します。

npm run test 2>&1 | grep 'FAIL' | uniq

このコマンドはFAILというキーワードを含む行だけを抽出し、重複している行を取り除く処理を行っています。

skipTestオプションの設定

上で取得したテストファイルのパスをignoreListのような変数に格納し、skipTestオプション内でチェックするようにします。

jest.setup.ts
import failOnConsole from 'jest-fail-on-console';

const ignoreList = [
  'src/components/Console.test.tsx',
  'src/components/Console2.test.tsx',
]

failOnConsole({
  skipTest({ testPath }) {
    const isMatch = ignoreList.some((path) => testPath.endsWith(path))
    if (isMatch) {
      return true
    }
    return false
  },
})

skipTestのコールバック関数で、testPathという実行されるテストのファイルパスを受け取り、そのテストがignoreListに含まれているかどうかをチェックしています。含まれている場合はtrueを返し、FAILにしないようにしています。

これにより、すでにログが出力されているテストファイルを指定して、FAILを回避することができました!


あとはignoreListに格納されているテストファイルを元にログを確認しながら該当コードを修正し、console.errorconsole.warnを撲滅していく作業を進めていきました!

まとめ

以上が、jest-fail-on-consoleを使って、テスト実行時のconsole.errorconsole.warnをFAILにして、ログのノイズを撲滅したお話でした。撲滅するにあたって、jest-fail-on-consoleのようなツール作る必要あるなぁと思ってましたが、やりたかったこと全てを兼ね備えていた、最高のnpmパッケージでした!みなさんもぜひ導入してみてください!

Discussion