テストを実行する
注: この機能は
react-scripts@0.3.0
以降で使用できます。
Create React App は Jest をテストランナーとして使用します。この統合の準備として、Jest の 大規模な改修 を行いました。そのため、数年前の悪い噂を耳にしていた場合、もう一度お試しください。
Jest は、Node ベースのランナーです。つまり、テストは常に Node 環境で実行され、実際のブラウザでは実行されません。これにより、高速なイテレーション速度が有効になり、不安定性が防止されます。
jsdom のおかげで、Jest は window
などのブラウザグローバルを提供しますが、これらは実際のブラウザの動作の近似に過ぎません。Jest は、DOM の癖ではなく、論理とコンポーネントの単体テストに使用することを目的としています。
必要に応じてブラウザのエンドツーエンドテスト用に別のツールを使用することをお勧めします。これらは、Create React App の範囲を超えています。
ファイル名の規則
Jest は、次の一般的な命名規則のいずれかでテストファイルを探します。
__tests__
フォルダ内の.js
サフィックスのファイル。.test.js
サフィックスのファイル。.spec.js
サフィックスのファイル。
.test.js
/.spec.js
ファイル (または __tests__
フォルダ) は、src
の最上位フォルダ下の任意の階層に配置できます。
テストファイル (または __tests__
フォルダ) をテスト対象のコードの隣に配置して、相対インポートが短く表示されるようにすることをお勧めします。たとえば、App.test.js
と App.js
が同じフォルダにある場合、テストは長い相対パスではなく import App from './App'
を実行するだけです。共存により、大規模なプロジェクトでもテストをより迅速に見つけることができます。
コマンドラインインターフェイス
npm test
を実行すると、Jest がウォッチモードで起動します*。ファイルを保存するたびに、テストが再実行されます。これは、npm start
がコードを再コンパイルするのと同じです。
ウォッチャーには、すべてのテストを実行したり、検索パターンのみに絞って実行したりできる対話型のコマンドラインインタフェースが含まれます。この機能は、ウォッチャーを開いたままにして高速に再実行できるように設計されています。コマンドは、ウォッチャーが各実行後に表示する「ウォッチの使用に関する」メモから学習できます。
*開発中にはウォッチモードでテストを実行することを推奨していますが、
--watchAll=false
フラグを渡すことでこの動作を無効にすることができます。ほとんどのCI環境では、この処理は自動的に行われます(CIサーバー上を参照してください)。
バージョン管理の統合
デフォルトでは、npm test
を実行すると、Jestは前回のコミット以降に変更されたファイルに関連するテストのみを実行します。これは、テストの数に関係なく高速にテストを実行できるように設計された最適化です。ただし、テストに合格していないコードはあまりコミットしないと想定しています。
Jestは、前回のコミット以降に変更されたファイルに関連するテストのみを実行したことを常に明確に示します。また、ウォッチモードでa
を押して、Jestにすべてのテストを実行させることもできます。
Jestは、継続的インテグレーションサーバー上か、プロジェクトがGitまたはMercurialリポジトリ内に入っていない場合に、常にすべてのテストを実行します。
テストの作成
テストを作成するには、テストの名前とそのコードを含むit()
(またはtest()
)ブロックを追加します。論理的グループ化を行うためにdescribe()
ブロックで囲むこともできますが、これは必須でも推奨でもありません。
Jestは主張を行うための組み込みのexpect()
グローバル関数を提供しています。基本的なテストは次のようになります。
import sum from './sum';
it('sums numbers', () => {
expect(sum(1, 2)).toEqual(3);
expect(sum(2, 2)).toEqual(4);
});
Jestでサポートされるすべてのexpect()
マッチャーは、ここで詳細に文書化されています。
「スパイ」またはモック関数を作成するには、jest.fn()
とexpect(fn).toBeCalled()
を使用することもできます。
コンポーネントのテスト
コンポーネントテスト手法には幅広いものがあります。コンポーネントがスローすることなくレンダリングされていることを検証する「スモークテスト」から、一部の出力をシャローレンダリングおよびテストし、コンポーネントのライフサイクルおよび状態の変化をフルレンダリングおよびテストするものまであります。
コンポーネントが変更される頻度と、それらに含まれるロジックの量に基づいて、プロジェクトによってテストのトレードオフが異なります。まだテスト戦略を決定していない場合は、コンポーネントの基本的なスモークテストを作成することから始めることをお勧めします。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
it('renders without crashing', () => {
const div = document.createElement('div');
ReactDOM.render(<App />, div);
});
このテストはコンポーネントをマウントし、レンダリング中にそれがスローしなかったことを確認します。このようなテストは、非常に少ない労力で多くの価値を提供するため、出発点として優れています。これらはsrc/App.test.js
にあるテストです。
コンポーネントの変更によって引き起こされるバグが発生した場合は、アプリケーションでテストする価値のある部分がさらに詳しくわかります。ここで、特定の期待される出力または動作をアサートする、より具体的なテストを導入するとよいでしょう。
Reactテストライブラリ
レンダリングされた子コンポーネントからコンポーネントを単独でテストする場合は、react-testing-library
を使用することをお勧めします。 react-testing-library
は、エンドユーザーによってコンポーネントが使用される方法に似た方法でReactコンポーネントをテストするためのライブラリです。Reactコンポーネントおよびアプリケーションのユニット、インテグレーション、およびエンドツーエンドテストに適しています。DOMノードとより直接的に動作するため、アサーションを向上させるためにjest-dom
とともに使用することをお勧めします。
react-testing-library
とjest-dom
をインストールするには、以下を実行できます。
npm install --save @testing-library/react @testing-library/jest-dom
代わりにyarn
を使用することもできます
yarn add @testing-library/react @testing-library/jest-dom
テストファイルの定型句を避けたい場合は、src/setupTests.js
ファイルを作成できます
// react-testing-library renders your components to document.body,
// this adds jest-dom's custom assertions
import '@testing-library/jest-dom';
react-testing-library
とjest-dom
を使用して<App />
コンポーネントが「Reactについて学ぶ」をレンダリングするかテストする例を次に示します。
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
it('renders welcome message', () => {
render(<App />);
expect(screen.getByText('Learn React')).toBeInTheDocument();
});
非同期インタラクションのテストを容易にする、およびreact-testing-library
ドキュメントや例からフォーム要素を選択するために、react-testing-library
で提供されるユーティリティの詳細を確認してください。
サードパーティの主張ライブラリの使用
アサーションにはexpect()
を使用し、スパイにはjest.fn()
を使用することをお勧めします。それらに問題がある場合は、それらをJestに提出してください、修正します。Reactのサポートを強化し、たとえばReact要素をJSXとしてきれいに印刷することをサポートする予定です。
ただし、ChaiやSinonなど、他のライブラリに慣れている場合、またはこれらを使用した既存のコードを移植したい場合は、次のように通常のそれらをインポートできます
import sinon from 'sinon';
import { expect } from 'chai';
テストで通常どおり使用します。
テスト環境の初期化
注:この機能は
react-scripts@0.4.0
以上で利用できます。
アプリがテストでモックする必要があるブラウザAPIを使用している場合、またはテストを実行する前にグローバルなセットアップが必要な場合は、プロジェクトにsrc/setupTests.js
を追加します。テストの実行前に自動的に実行されます。
例
src/setupTests.js
const localStorageMock = {
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
clear: jest.fn(),
};
global.localStorage = localStorageMock;
注:
src/setupTests.js
を作成する前に「eject」する場合は、生成されるpackage.json
ファイルにはそれに関して参照が含まれないため、プロパティsetupFilesAfterEnv
をJestの設定に手動で作成する必要があります。次のようなもの
"jest": {
// ...
"setupFilesAfterEnv": ["<rootDir>/src/setupTests.js"]
}
テストの焦点を当てて、除外する
it()
をxit()
に置き換えると、テストが実行されないように一時的に除外できます。
同様に、fit()
を使用すると、他のテストを実行せずに特定のテストに焦点を当てることができます。
カバレッジレポート
JestにはES6で適切に機能し、構成を必要としない統合されたカバレッジレポーターがあります。
次のようにnpm test -- --coverage
(真ん中に追加の--
に注意)を実行して、次のようなカバレッジレポートを含めます
テストはカバレッジによりはるかに遅く実行されるため、通常のワークフローとは別に実行することをお勧めします。
構成
Create React AppがJestに使用する既定の構成は、package.jsonにサポートされている次のキーのいずれかをJestの構成に追加することでオーバーライドできます。
サポートされているオーバーライド
clearMocks
collectCoverageFrom
coveragePathIgnorePatterns
coverageReporters
coverageThreshold
displayName
extraGlobals
globalSetup
globalTeardown
moduleNameMapper
resetMocks
resetModules
restoreMocks
snapshotSerializers
testMatch
transform
transformIgnorePatterns
watchPathIgnorePatterns
package.jsonの例
{
"name": "your-package",
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}",
"!<rootDir>/node_modules/",
"!<rootDir>/path/to/dir/"
],
"coverageThreshold": {
"global": {
"branches": 90,
"functions": 90,
"lines": 90,
"statements": 90
}
},
"coverageReporters": ["text"],
"snapshotSerializers": ["my-serializer-module"]
}
}
継続的インテグレーション
デフォルトではnpm test
はインタラクティブなCLIでウォッチャーを実行します。ただし、CI
という環境変数を設定することで、テストが一度だけ実行され、プロセスが終了するように強制できます。
npm run build
でアプリケーションのビルドを作成する場合、リンターの警告はデフォルトではチェックされません。npm test
のように、環境変数CI
を設定することで、ビルドにリンター警告チェックの実行を強制できます。警告が見つかった場合、ビルドは失敗します。
一般的なCIサーバーはCI
環境変数を標準で設定していますが、自分でも行うことができます。
CIサーバーで
Travis CI
- Travisスタートガイドに従って、GitHubリポジトリをTravisに同期してください。手動でプロフィールページでいくつかの設定を初期化する必要がある場合があります。
.travis.yml
ファイルをgitリポジトリに追加します。
language: node_js
node_js:
- 8
cache:
directories:
- node_modules
script:
- npm run build
- npm test
- git pushを使用して最初のビルドを実行します。
- 必要に応じてTravis CIビルドをカスタマイズします。
CircleCI
この記事に従って、React Appの作成プロジェクトでCircleCIを設定します。
独自環境で
Windows (cmd.exe)
set CI=true&&npm test
set CI=true&&npm run build
(注意:空白がないのは意図的です)。
Windows (Powershell)
($env:CI = "true") -and (npm test)
($env:CI = "true") -and (npm run build)
Linux、macOS (Bash)
CI=true npm test
CI=true npm run build
テストコマンドはJestをCIモードで実行するように強制し、テストはウォッチャーを起動するのではなく、1回だけ実行されます。
非CI環境の場合、テストウォッチを無効にするには--watchAll=false
フラグを渡すことができます。
ビルドコマンドはリンターの警告を確認し、見つかった場合は失敗します。
jsdomの無効化
テストがjsdomに依存していないことがわかっている場合は、--env=node
を安全に設定でき、テストはより高速に実行されます。
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
- "test": "react-scripts test"
+ "test": "react-scripts test --env=node"
決断を下すために、jsdomが必要なAPIのリストを次に示します。
window
やdocument
などのブラウザグローバルReactDOM.render()
TestUtils.renderIntoDocument()
(上記のショートカット)mount()
in Enzymerender()
in React Testing Library
対照的に、jsdomは不要です以下のAPIの場合
TestUtils.createRenderer()
(シャローレンダリング)shallow()
in Enzyme
最後に、スナップショットテストではjsdomも必要ありません。
スナップショットテスト
スナップショットテストは、コンポーネントのテキストスナップショットを自動的に生成し、ディスクに保存する Jest の機能です。これにより、UI の出力が変化した場合はコンポーネントの出力に対して手動でアサーションを記述しなくても通知されます。スナップショットテストの詳細を読む
エディターの統合
場合 Visual Studio コードを使用すると、 Jest 拡張機能があり、Create React App と連携してすぐに機能します。これによって、テキストエディターを使用中にテストの実行状況と潜在的な失敗メッセージをインラインで表示したり、監視の開始と停止を自動的に行ったり、ワンクリックのスナップショット更新を提供したりする、多くの IDE 的な機能が提供されます。