フロントエンド開発環境の続きです。コードチェック(ESLint)、コード整形(Prettier)ときて、次はコードテストです!JSをTestするからJestというわかりやすい名前w テスト駆動開発(TDD)とは何か?それでは行きましょう!
【目次】
- テスト駆動開発とは何か
- Jestのインストール
- テストの対象の元ファイルを作成(内税計算)
- テストファイルを作る
- テスト実行!するがnpm ERR…
- package.jsonのscriptsを書き直す
- 初テスト成功!(結果はレッド)
- コードを書き直してテスト再実行(ついにグリーン!)
- 単なる足し算に書き直してみる
- debug.logが書き出されている
- npmログを切って再実行(--silentオプション)
- 最後に
※参考:【JS】ESLintで構文チェックを事始める - クモのようにコツコツと
※参考:【コードフォーマッター】PrettierでHTML、CSS、JSのコードを整形してみた - クモのようにコツコツと
Web開発環境まとめ
qiita.com
テスト駆動開発とは何か
Jestは「テスト駆動開発(TDD)」のツールと言われる。ナンチャラ駆動開発はたくさんあって、その中の一つ。
「○○ Driven Development」のDrivenはDriveの過去形。
テスト駆動開発には3つのサイクルが存在します。
レッド → グリーン → リファクタリング
です。
テスト駆動開発(TDD)はレッド(失敗)、グリーン(成功)、リファクタリング(修正)のサイクルを回しながら、一つ一つの部品の安全性を高めて次の工程に進む作り方をするようだ。信号みたいなイメージ。
※参考:テスト駆動開発って何だろう | Developers.IO
フロントエンド開発でテストってどんな物なのだろう。
※参考:フロントエンドでTDDを実践する(理論編) - Qiita
フロントエンドのテストの難しさ。(コードのロジックではなくブラウザに依存する問題など)
※参考:フロントエンドの負債と向き合う - mizchi's blog
とにかくテストがどんなものか体験してみないとイメージしづらかった。ということでJestで体験してみる。
Jestのインストール
Jestも前回のPretterと同じような流れでインストールでけた。
いつものようにNode.jsとnpmは既に入っている前提(ターミナルで下記を叩くとバージョン番号が出る)
node -v npm -v
Jestを入れるフォルダを作る。今回は「jest_test」とした。
cdコマンドでjest_testフォルダに移動。
cd (フォルダのパス)/jest_test
package.jsonの作成
npm init -y
ローカルにJestをインストールする。
npm install -D jest
package.jsonにjestが記述された!
"devDependencies": { "jest": "^25.1.0" }
テストの対象の元ファイルを作成(内税計算)
ではさっそくテストを作成してみよう。公式サイトを参考に進めてみる。
まずテストの対象になる元ファイルsum.js
を作る。
元ファイルsum.js
にはやりたい処理のコードを書く。
function uchizei(goukei, zeiritsu) { return goukei * zeiritsu / ( 100 + zeiritsu ); } module.exports = uchizei;
- 関数
uchizei()
で消費税の内税を計算する処理。 module.exports
でuchizei
をモジュール(部品)としてエクスポート
消費税の内税の計算式はこちらを参考にした。
※参考:消費税の内税の計算方法、簡単な計算式[8%、10%]|KW BLOG
税率が10%になって外税は計算しやすくなったが、内税は相変わらず計算しづらいよなーと思い。
テストファイルを作る
次にテストを実行するファイルsum.test.js
を作る。
テスト用ファイルは下記の構成で書くようだ。
const hoge = require('./(パス)'); test('テスト名', () => { expect(処理).toBe(予想結果); });
- 変数
hoge
にrequire()
で元ファイルを読み込む。 test()
の中、第一引数はテスト名、第二引数は無名関数- 無名関数の中、
expect()
の引数に処理、toBe()
の引数に予想結果を書く
書いてみた。
const uchizei = require('./sum'); test('内税計算', () => { expect(uchizei(860, 10)).toBe(78); });
uchizei()
の第一引数(合計)に860円、第二引数(税率)に10%を入れると結果は78円になるはずだよ、と想定している。
テスト実行!するがnpm ERR…
さあ、テスト実行!
npm run test
結果
> jest_test@1.0.0 test /(パス)/jest_test > echo "Error: no test specified" && exit 1 Error: no test specified npm ERR! (後略)
おや?エラー?
「テストが指定されていません」となった。その下にnpm ERR
が何行か連なっている。
package.jsonのscriptsを書き直す
原因はpackage.json
にありそう。
自動的に作られたscripts
オプションはこうだった。
"scripts": { "test": "echo \"Error: no test specified\" && exit 1" },
公式サイトによるとscripts
はこれだけでいいみたい。
"scripts": { "test": "jest" }
上記に書き直す。
初テスト成功!(結果はレッド)
テスト再実行!
npm run test
結果
FAIL ./sum.test.js ✕ 内税計算 (6ms) ● 内税計算 expect(received).toBe(expected) // Object.is equality Expected: 78 Received: 78.18181818181819 2 | 3 | test('内税計算', () => { > 4 | expect(uchizei(860, 10)).toBe(78); | ^ 5 | }); at Object.<anonymous> (sum.test.js:4:28) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 1.846s Ran all test suites. npm ERR! …(後略)
お、テストが実行された!人生初テスト成功です!
FAIL
のところが赤色になっている。レッドはテスト失敗という意味。テスト実行は成功したがテスト結果は失敗という。ややこしやw
また、結果の後にはnpm ERR
はまだいくつか続いている。
大元のnpmのバージョンが古いからか?と思いグローバルのnpmを入れ直してみた。
※参考:【初心者】npm ERR! の対処法 - Qiita
結果は解消されず…。うーむ、なんだろう。
コードを書き直してテスト再実行(ついにグリーン!)
とはいえテストの実行結果自体が出たのは前進!
さっそくコードを修正してみよう。先ほどのレッドでは内税の計算結果に78.18181818181819
と小数があるのことを指摘された。
Math.floor()
関数を使って小数を切り下げに書き直してみる。
function uchizei(goukei, zeiritsu) { return Math.floor(goukei * zeiritsu / ( 100 + zeiritsu )); } module.exports = uchizei;
※参考:【JavaScript】桁指定して四捨五入・切り上げ・切り捨て - Qiita
テスト再実行!
npm run test
おお、今度は通った!
PASS ./sum.test.js ✓ 内税計算 (2ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 2.24s Ran all test suites.
PASS
のところが緑色になっている!グリーンは成功!
あと、先ほどようなnpm ERR
が今回は出なかった。これはテストの結果が失敗すると出るのかな?
単なる足し算に書き直してみる
レッドの時の挙動を確かめるべく、元のコードを単なる足し算に変えててみると…
function uchizei(goukei, zeiritsu) { //return Math.floor(goukei * zeiritsu / ( 100 + zeiritsu )); return goukei + zeiritsu; } module.exports = uchizei;
テスト再々実行
npm run test
お、FAIL
(レッド)になった。
FAIL ./sum.test.js ✕ 内税計算 (5ms) ● 内税計算 expect(received).toBe(expected) // Object.is equality Expected: 78 Received: 870 2 | 3 | test('内税計算', () => { > 4 | expect(uchizei(860, 10)).toBe(78); | ^ 5 | }); at Object.<anonymous> (sum.test.js:4:28) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 2.153s Ran all test suites. npm ERR! …(後略)
またnpm ERR
が続いている。
テストの方の予測結果も足し算に変えてみると…
const uchizei = require('./sum'); test('内税計算', () => { //expect(uchizei(860, 10)).toBe(78); expect(uchizei(860, 10)).toBe(870); });
今度はPASS
(グリーン)。テストが通った。
PASS ./sum.test.js ✓ 内税計算 (3ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 0.958s, estimated 1s Ran all test suites.
そしてnpm ERR
はない。やはりレッドの時だけ出るようだ。
debug.logが書き出されている
先ほどのnpm ERR
の中にdebug.log
というファイルが書き出されている。
npm ERR! /(パス)/.npm/_logs/2020-01-27T20_56_43_142Z-debug.log
ログを見るとエラー内容の詳細が書き出されている。翻訳してみたがいまいちよくわからず…
そもそもdebug.log
とは何か?
「不具合の調査をするときに役に立つかもしれないから、取りあえずメモっておこうかな」な内容が書いてあります。
※参考:https://wa3.i-3-i.info/word1418.html
ふむ、やはりまだ不具合があるのかな?
npmログを切って再実行(--silentオプション)
Jestのdebug.log
について調べるとこちらの記事が同じ状況ぽい。
※参考:npm run testするときはnpmログを切ったほうがいい - Qiita
npm ERR!ってでてるのでシステムエラーかとも思うんですが、よく見るとテストのコマンドのところで、Exit status 1ってなっているのが原因のようです。
確かに最初のpackage.json
のscripts
にもnpm ERR
ないにもExit status
という記述がある!
Exit status
コマンドは「終了ステータス」のことで成功は0
、失敗は1
らしい。
※参考:終了ステータス | UNIX & Linux コマンド・シェルスクリプト リファレンス
なるほど。テストが失敗したらエラーログが出る設定になっているんだ。
これを解消する方法、先ほどの記事によると--silent
というオプションを付けると出なくなるようだ。
npm run test --silent
公式サイトにも記述があった。
--silent
コンソール経由でメッセージを表示しないようにします。
という事、内税計算に戻してから--silent
オプション付きテストを実行してみる。
function uchizei(goukei, zeiritsu) { return Math.floor(goukei * zeiritsu / ( 100 + zeiritsu )); //return goukei + zeiritsu; } module.exports = uchizei;
どうだ!?
npm run test --silent
おお、今度は結果のみでnpm ERR
が出なくなった。
FAIL ./sum.test.js ✕ 内税計算 (7ms) ● 内税計算 expect(received).toBe(expected) // Object.is equality Expected: 870 Received: 78 3 | test('内税計算', () => { 4 | //expect(uchizei(860, 10)).toBe(78); > 5 | expect(uchizei(860, 10)).toBe(870); | ^ 6 | }); at Object.<anonymous> (sum.test.js:5:28) Test Suites: 1 failed, 1 total Tests: 1 failed, 1 total Snapshots: 0 total Time: 2.228s Ran all test suites.
テスト実行のたびにデバッグログが出るのは少し猥雑なので、必要に応じてということにしようかな(デバッグログの解読能力もまだ足りない…)
最後に
ということで人生初テストが成功しました!
npm ERR
が出たのでちょっと戸惑いましたがそれはシステムエラーではなかったようで安心しました。
テストが通ったコードを積み重ねていって全体が完成する頃にはエラーが起こらない形になる、というテスト駆動開発(TDD)。
いつもはブラウザで挙動を確認してからエラーの原因を探すというやり方でした。テストしながら進めると最初からロジックを意識したコードが書けそうに感じました。それではまた!
Web開発環境まとめ
qiita.com