Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mochaをnode:testに変更する #1737

Merged
merged 5 commits into from
May 27, 2024
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 100 additions & 60 deletions source/use-case/nodecli/refactor-and-unittest/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,58 +46,60 @@ markedパッケージや、そのオプションに関する記述がひとつ
## ユニットテスト実行環境を作る {#create-env}

ユニットテストの実行にはさまざまな方法があります。
このセクションではテスティングフレームワークとして[Mocha][]を使って、ユニットテストの実行環境を作成します。
Mochaが提供するテスト実行環境では、グローバルに`it`や`describe`などの関数が定義されます。
`it`関数はその内部でエラーが発生したとき、そのテストを失敗として扱います。
このセクションではNode.jsの標準モジュールのひとつである[testモジュール][]から提供される`test`を使って、ユニットテストの実行環境を作成します。
`test`関数はその内部でエラーが発生したとき、そのテストを失敗として扱います。
つまり、期待する結果と異なるならエラーを投げ、期待どおりならエラーを投げないというテストコードを書くことになります。

今回はNode.jsの標準モジュールのひとつである[assertモジュール][]から提供される`assert.strictEqual`メソッドを利用します。
`assert.strictEqual`メソッドは第一引数と第二引数の評価結果が`===`で比較して異なる場合に、例外を投げる関数です。

Mochaによるテスト環境を作るために、まずは次のコマンドで`mocha`パッケージをインストールします。

```shell
$ npm install --save-dev mocha@10
```

`--save-dev`オプションは、パッケージを`devDependencies`としてインストールするためのものです。
`package.json`の`devDependencies`には、そのパッケージを開発するときだけ必要な依存ライブラリを記述します。

ユニットテストを実行するには、Mochaが提供する`mocha`コマンドを使います。
Mochaをインストールした後、`package.json`の`scripts`プロパティを次のように記述します。
ユニットテストを実行するには、Node.jsが提供する`node`コマンドの`--test`オプションを使います。
`package.json`の`scripts`プロパティには、次のように記述します。

```json
{
...
"scripts": {
"test": "mocha test/"
"test": "node --test"
},
...
}
```

この記述により、`npm test`コマンドを実行すると、`mocha`コマンドで`test/`ディレクトリにあるテストファイルを実行します。
試しに`npm test`コマンドを実行し、Mochaによるテストが行われることを確認しましょう
まだテストファイルを作っていないので、`Error: No test files found`というエラーが表示されます
この記述により、`npm test`コマンドを実行すると、`node --test`で`test/`ディレクトリにあるテストファイルを実行します。実行時にディレクトリの指定を省いていますが、`node --test`はデフォルトで`test/`ディレクトリを探索するようになってます
試しに`npm test`コマンドを実行し、テストが行われることを確認しましょう
まだテストファイルを作っていないので、0個のテストが実行されて正常終了します

```shell
$ npm test
> mocha

Error: No test files found
> test
> node --test

ℹ tests 0
ℹ suites 0
ℹ pass 0
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 7.3243

$ echo $?
0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ここは省略していいかなと思います。

Suggested change
$ echo $?
0

Windowsでは動かないため。

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Windowsを失念しておりました! ご指摘ありがとうございます!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@azu
ご指摘の点を修正しました!

```

## ユニットテストを記述する {#write-unit-test}

テストの実行環境ができたので、実際にユニットテストを記述します。
Mochaのユニットテストは`test`ディレクトリの中にJavaScriptファイルを配置して記述します
記述する際には、`test`ディレクトリの中にJavaScriptファイルを配置します
`test/md2html-test.js`ファイルを作成し、`md2html.js`に対するユニットテストを次のように記述します。

`it`関数は第一引数にテストのタイトルを入れ、第二引数にテストの内容を記述します
`test`関数は第一引数にテストのタイトルを入れ、第二引数にテストの内容を書きます

[import, title:"test/md2html-test.js"](./src/test/md2html-test.js)

`it`関数で定義したユニットテストは、`md2html`関数の変換結果が期待するものになっているかをテストしています。
`test`関数で定義したユニットテストは、`md2html`関数の変換結果が期待するものになっているかをテストしています。
`test/fixtures`ディレクトリにはユニットテストで用いるファイルを配置しています。
今回は変換元のMarkdownファイルと、期待する変換結果のHTMLファイルが存在します。

Expand All @@ -116,12 +118,20 @@ Mochaのユニットテストは`test`ディレクトリの中にJavaScriptフ

```shell
$ npm test
> mocha

✓ converts Markdown to HTML (GFM=false)
✓ converts Markdown to HTML (GFM=true)

2 passing (31ms)
> test
> node --test

✔ converts Markdown to HTML (GFM=false) (12.2419ms)
✔ converts Markdown to HTML (GFM=true) (4.4282ms)
ℹ tests 2
ℹ suites 0
ℹ pass 2
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 63.881902
```

ユニットテストが通らなかった場合は、次のことを確認してみましょう。
Expand All @@ -134,36 +144,66 @@ $ npm test

```shell
$ npm test
> mocha test/

✔ converts Markdown to HTML (GFM=false)
1) converts Markdown to HTML (GFM=true)

1 passing (17ms)
1 failing

1) converts Markdown to HTML (GFM=true):

AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected ... Lines skipped

'<h1 id="サンプルファイル">サンプルファイル</h1>\n' +
'<p>これはサンプルです。\n' +
...
'<li>サンプル1</li>\n' +
'<li>サンプル2</li>\n' +
+ '</ul>'
- '</ul>\n' +
- ';;;'
+ expected - actual

<a href="https://jsprimer.net/">https://jsprimer.net/</a></p>
<ul>
<li>サンプル1</li>
<li>サンプル2</li>
-</ul>
+</ul>
+;;;

> test
> node --test

✔ converts Markdown to HTML (GFM=false) (11.568601ms)
✖ converts Markdown to HTML (GFM=true) (5.6456ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected ... Lines skipped

'<h1 id="サンプルファイル">サンプルファイル</h1>\n' +
'<p>これはサンプルです。\n' +
...
'<li>サンプル1</li>\n' +
'<li>サンプル2</li>\n' +
+ '</ul>'
- '</ul>\n' +
- ';;;'
at TestContext.<anonymous> (file:///Users/laco/nodecli/test/md2html-test.js:29:10)
at async Test.run (node:internal/test_runner/test:632:9)
at async Test.processPendingSubtests (node:internal/test_runner/test:374:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '<h1 id="サンプルファイル">サンプルファイル</h1>\n<p>これはサンプルです。\n<a href="https://jsprimer.net/">https://jsprimer.net/</a></p>\n<ul>\n<li>サンプル1</li>\n<li>サンプル2</li>\n</ul>',
expected: '<h1 id="サンプルファイル">サンプルファイル</h1>\n<p>これはサンプルです。\n<a href="https://jsprimer.net/">https://jsprimer.net/</a></p>\n<ul>\n<li>サンプル1</li>\n<li>サンプル2</li>\n</ul>\n;;;',
operator: 'strictEqual'
}

ℹ tests 2
ℹ suites 0
ℹ pass 1
ℹ fail 1
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 64.548503

✖ failing tests:

test at file:/Users/laco/nodecli/test/md2html-test.js:21:1
✖ converts Markdown to HTML (GFM=true) (5.6456ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
+ actual - expected ... Lines skipped

'<h1 id="サンプルファイル">サンプルファイル</h1>\n' +
'<p>これはサンプルです。\n' +
...
'<li>サンプル1</li>\n' +
'<li>サンプル2</li>\n' +
+ '</ul>'
- '</ul>\n' +
- ';;;'
at TestContext.<anonymous> (file:///Users/laco/nodecli/test/md2html-test.js:29:10)
at async Test.run (node:internal/test_runner/test:632:9)
at async Test.processPendingSubtests (node:internal/test_runner/test:374:7) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '<h1 id="サンプルファイル">サンプルファイル</h1>\n<p>これはサンプルです。\n<a href="https://jsprimer.net/">https://jsprimer.net/</a></p>\n<ul>\n<li>サンプル1</li>\n<li>サンプル2</li>\n</ul>',
expected: '<h1 id="サンプルファイル">サンプルファイル</h1>\n<p>これはサンプルです。\n<a href="https://jsprimer.net/">https://jsprimer.net/</a></p>\n<ul>\n<li>サンプル1</li>\n<li>サンプル2</li>\n</ul>\n;;;',
operator: 'strictEqual'
}
```

このテスト結果では `converts Markdown to HTML (GFM=true)` というタイトルのテストが1つ失敗していることがわかります。
Expand Down Expand Up @@ -195,10 +235,10 @@ npmを使ったパッケージ管理や外部モジュールの利用、`fs`モ
## このセクションのチェックリスト {#section-checklist}

- Markdownの変換処理をECMAScriptモジュールとして`md2html.js`に切り出し、`main.js`から読み込んだ
- mochaパッケージをインストールし、`npm test`コマンドで`mocha`コマンドを実行できることを確認した
- `npm test`コマンドで`node --test`が実行できることを確認した
- `md2html`関数のユニットテストを作成し、テストの実行結果を確認した

[ECMAScriptモジュール]: ../../../basic/module/README.md
[moduleオブジェクト]: https://nodejs.org/api/modules.html#modules_the_module_object
[Mocha]: https://mochajs.org/
[testモジュール]: https://nodejs.org/api/test.html
[assertモジュール]: https://nodejs.org/api/assert.html
Loading