多くの開発者は、コードをテストする際に課題に直面しています。適切なテストがなければバグがすり抜け、ユーザーの不満や高額な修正につながる可能性があります。
この記事では、Node.js と MongoDB を使用して構築された非常に単純な例に、Jest、Supertest、および Puppeteer を使用して単体テスト、統合テスト、エンドツーエンド テストを効果的に適用する方法を示します。
この記事を読み終えるまでに、この種のテストを独自のプロジェクトに適用する方法を明確に理解していただければ幸いです。
??このリポジトリで完全な例を見つけてください。
依存関係をインストールする前に、まず例を紹介します。これは、ユーザーが登録ページを開いて登録の詳細を設定し、登録ボタンをクリックして、その情報をデータベースに保存できる非常に単純な例です。
この例では、次のパッケージを使用します:
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
これらの依存関係のほとんどは簡単ですが、いくつかについては以下で説明します。
わかりました。これをコードに変換しましょう。
予測できない動作を起こさずに単体テストを実行するには、各テストの前にモック関数をリセットする必要があります。これは、beforeEach フックを使用して実現できます:
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
この場合、validateInput 関数をテストします。
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
これは、提供された入力に有効な電子メールが含まれているかどうかを検証する非常に単純な関数です。これがその単体テストです:
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
await Expect(async () => {}).rejects: Jest ドキュメントに基づいて、これは拒否された Promise の理由を予想する方法です。
データベース内に重複した電子メールが存在するかどうかを確認する別の関数をテストしてみましょう。実際、これは興味深いものです。なぜなら、データベースを扱わなければならないと同時に、単体テストでは外部システムを扱うべきではないからです。それでは何をすべきでしょうか?そうですね、Mock を使用する必要があります。
まず、テストする必要がある emailShouldNotBeDuplicated 関数を見てください。
// register.controller.js const validator = require('validator'); const registerController = async (input) => { validateInput(input); ... }; const validateInput = (input) => { const { name, email, password } = input; const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 }); if (!isValidName) throw new Error('Invalid name'); ... };
ご覧のとおり、この関数はデータベースにリクエストを送信し、同じ電子メールを持つ別のユーザーがいるかどうかを確認します。データベース呼び出しをモックする方法は次のとおりです:
// __tests__/unit/register.test.js const { registerController } = require('../controllers/register.controller'); describe('RegisterController', () => { describe('validateInput', () => { it('should throw error if email is not an email', async () => { const input = { name: 'test', email: 'test', password: '12345678' }; await expect(async () => await registerController(input)).rejects.toThrow('Invalid email'); }); }); });
私たちは、モック関数を作成し、その呼び出しを追跡する jest.spyOn(object, methodName) を使用して、データベースの findOne メソッドをモック (スパイ) しました。その結果、toHaveBeenNthCalledWith.
を使用して、スパイされた findOne メソッドの呼び出し数と渡されたパラメーターを追跡できます。統合テストを作成する前に、環境を構成する必要があります。
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
これで、統合テストを実行する準備が整いました。
登録リクエストの送信からデータベースへのユーザー詳細の保存、成功ページへのリダイレクトまで、サーバー側の登録プロセス全体をテストしてみましょう:
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
ご覧のとおり、registerController 関数は、validateInput、emailShouldNotBeDuplicated、createUser 関数といった複数のコンポーネント (関数) を統合しています。
それでは、統合テストを書いてみましょう:
// register.controller.js const validator = require('validator'); const registerController = async (input) => { validateInput(input); ... }; const validateInput = (input) => { const { name, email, password } = input; const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 }); if (!isValidName) throw new Error('Invalid name'); ... };
例に移りましょう。
実際、この例では、エンドツーエンド テストの環境構成は統合テストの環境構成と似ています。
この場合、登録ページを開いて詳細 (名前、電子メール、パスワード) を入力し、「登録」ボタンをクリックして、最終的に成功ページにリダイレクトされるまでの、実際のユーザー登録動作を正確にシミュレートする必要があります。 。コードを見てください:
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
このコードを分解してみましょう:
Unsplash の Nathan Dumlao による写真
この時点で、それぞれに独自の構成がある場合に、すべてのテスト タイプを同時に実行する方法を疑問に思うかもしれません。例:
では、それぞれのテスト タイプが対応する設定を確実に尊重しながら、すべてのテスト タイプを同時に実行するにはどうすればよいでしょうか?
この問題に対処するには、次の手順に従ってください:
1. 3 つの異なる設定ファイル jest.unit.config.js を作成しましょう:
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
jest.integration.config.js:
// register.controller.js const validator = require('validator'); const registerController = async (input) => { validateInput(input); ... }; const validateInput = (input) => { const { name, email, password } = input; const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 }); if (!isValidName) throw new Error('Invalid name'); ... };
jest.e2e.config.js:
// __tests__/unit/register.test.js const { registerController } = require('../controllers/register.controller'); describe('RegisterController', () => { describe('validateInput', () => { it('should throw error if email is not an email', async () => { const input = { name: 'test', email: 'test', password: '12345678' }; await expect(async () => await registerController(input)).rejects.toThrow('Invalid email'); }); }); });
2. 次に、package.json ファイル内の npm スクリプトを次のように更新します。
// register.controller.js const { User } = require('../models/user'); const registerController = async (input) => { ... await emailShouldNotBeDuplicated(input.email); ... }; const emailShouldNotBeDuplicated = async (email) => { const anotherUser = await User.findOne({ email }); if (anotherUser) throw new Error('Duplicated email'); };
--config: Jest 構成ファイルへのパスを指定します。
npm-run-all --Parallel: すべてのテストを並行して実行できます。
3. 次に、setup.unit.js、setup.integration.js、setup.e2e.js という名前の 3 つのセットアップ ファイルを作成します。これには、前のセクションで使用した必要なセットアップ コードが含まれています。
4. 最後に、このコマンド npm run test を実行して、すべてのテストを実行します。このコマンドは、すべての単体テスト、統合テスト、およびエンドツーエンド テストをそれぞれの構成に従って並行して実行します。
この記事では、単体テスト、統合テスト、エンドツーエンド (E2E) テストについて検討し、信頼性の高いアプリケーションを構築するためのそれらの重要性を強調しました。 Node.js と MongoDB を使用した簡単なユーザー登録の例で、Jest、Supertest、Puppeteer を使用してこれらのテスト メソッドを実装する方法を示しました。
実際、堅実なテスト戦略はコードの品質を向上させるだけでなく、開発者の自信を高め、ユーザーの満足度も高めます。
この記事が、あなた自身のプロジェクトに適用できる有益な洞察を提供することを願っています。テストを楽しんでください!
この記事が役立つと思われた場合は、次の記事もチェックしてください:
ここまでお付き合いいただき、誠にありがとうございました。この記事を楽しんで読んでいただければ幸いです。
以上がJest を使用した一例におけるユニット、統合、ETestingの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。