質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
Jest

Jestは、JavaScriptのテストフレームワークです。設定が不要で、高速且つ安全にテストを開始できます。コードカバレッジを生成できる他、テストスコープ外のオブジェクトを容易にモック化できるなど、豊富な機能によりテストの導入を簡単にします。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

意見交換

クローズ

2回答

770閲覧

【Jest/nodejs 初心者】テストしやすいコードの書き方についてアドバイスが欲しい

sasa0330

総合スコア64

Jest

Jestは、JavaScriptのテストフレームワークです。設定が不要で、高速且つ安全にテストを開始できます。コードカバレッジを生成できる他、テストスコープ外のオブジェクトを容易にモック化できるなど、豊富な機能によりテストの導入を簡単にします。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

1グッド

1クリップ

投稿2023/06/11 08:12

編集2023/06/11 08:12

1

1

テーマ、知りたいこと

初めてユニットテストを書いているのですが、コードが複雑でテストケースを書くのが難しくなります。

ユニットテストに適したコード設計などあるのでしょうか?
参考になるサイトなどがあれば教えていただきたいです。
かなり漠然とした質問で申し訳ございません。

イメージ

コード例)

app.js

1const main = () => { 2 while(true){ 3 func1(); 4 if(func2()==="retry"){ 5 continue; 6 } 7 if(func2()==="finish"){ 8 break; 9 } 10 } 11} 12main();

・理想
main処理の中はロジックを書かず、ロジック部分は関数化する。
それぞれ関数化した部分にのみテストを実行したい。

・現実
whileやfor文を使うと、どうしてもmain処理にもロジックが入る。
func1、func2にのみテストを実行したい。

Lhankor_Mhy👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

回答2

#1

Zuishin

総合スコア28662

投稿2023/06/11 09:16

編集2023/06/12 03:17

whileやfor文を使うと、どうしてもmain処理にもロジックが入る。

入っていいんじゃないですかね。
コード例に関して言えば、func2 は boolean を返すようにするか、もしくはそのようなラッパーを被せると、次のように簡単になります。

JavaScript

1do { 2 func1(); 3} while (func2());

更に do while を行う高階関数を作れば、次のようになります。

JavaScript

1doWhile(func1, func2);

この場合、func1 func2 doWhile をテストすれば main のテストは不要です。

また、他の関数を呼び出す複雑なロジック(仮にここで main が複雑だったとしましょう)をテストするには、依存性の注入という方法がよく使われます。

ここでは func1 と func2 がリリース時と同じ関数ですが、そうではなくテストの時だけテスターの望む結果を出す関数(モック)に取り替えることで、それらを呼び出すロジックをテストします。
仮に func1 をログを取る関数に取り替え、func2 を二回目に false を返す関数に取り替えてテストすると、func1 が二回呼び出されたかどうかはログを確認すればわかります。

main は func1 と func2 に依存していますが、この依存された関数を取り替えるのが依存性の注入です。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

#2

miyabi-sun

総合スコア21158

投稿2023/06/12 07:25

現実問題 main 関数の中身がぐちゃぐちゃになるのはしょうがないところがあります。
コマンドラインツールをNode.jsで作ってて、コマンドライン引数process.argvに追従して動作が変わるようなことになればmain全体をテスト仕切る事は大変です。

初めてユニットテストを書いているのですが、

ユニットテストは和訳すると単体試験(単体テスト)です。

質問文のmain関数のすべての挙動をテスト・確認することではありません。
main関数をテスト・確認するのは結合テストや総合テストの分野になります。

ユニットテストに該当するのは質問文のfunc1func2を指します。
このfunc1func2が完璧に動作できるとユニットテストで証明できた後、
もしmain関数内で変な動作が出たのであれば、
whileやif文の使い方が間違っているだけって事がわかるでしょ?


ユニットテストに適したコード設計などあるのでしょうか?

「テストしやすいコード」を書くことが重要になります。
この「テストしやすいコード」とはなんぞや?というわけで、多くのITエンジニア達が勉強・研究してきました。
なので「テストしやすいコード」などで検索すると色々出てきます。

例としてはこの記事
テストしやすいコードについて考えてみた | 株式会社クイックのWebサービス開発blog

その中でも数学の関数の定義に近い挙動をする関数を作る事を推奨します。
どういうことか?というと
「この引数を入れて関数を実行すると、必ずこの戻り値が帰ってくる」という関数を作る事です。

fizzbuzzなんかがわかりやすいですね。

js

1const fizzbuzz = it => { 2 if (it % 15 === 0) return "FIzzBuzz"; 3 if (it % 3 === 0) return "Fizz"; 4 if (it % 5 === 0) return "Buzz"; 5 return it; 6} 7 8// 2回実行したからと言って結果が変わる訳では無い 9console.log(fizzbuzz(3)); // Fizz 10console.log(fizzbuzz(3)); // Fizz

実際にはこのような一発で表現できる問題は少ないですが、
JavaScriptの引数には関数やオブジェクト、配列等を好き勝手指定できるので、
複雑な処理も、ちゃんと練って設計すれば、このような形に落とし込む事ができます。

……が、まずはこのように書きやすい箇所を抽出して関数化
関数化できたものをユニットテストで検証するようにする習慣を見に付けてください。

参考になるサイトなどがあれば教えていただきたいです。

和田卓人氏が書いた「テスト駆動開発」という書籍を読むことを勧めます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

最新の回答から1ヶ月経過したため この意見交換はクローズされました

意見をやりとりしたい話題がある場合は質問してみましょう!

質問する

関連した質問