序章
スナップショットテストを使用すると、出力が引き続き期待どおりに動作することを確認できます。 これは、コードを再検討して時間の経過とともに更新を行うと、それらの変更によって何かが破損する可能性が高くなるため、便利です。
厳密なテスト駆動開発(TDD)とは異なり、標準的な方法では、最初に失敗したテストを記述してから、テストに合格するためのコードを記述しますが、スナップショットテストは別のアプローチを取ります。
Reactコンポーネントのスナップショットテストを作成するときは、最初にコードを動作状態にする必要があります。 次に、特定のデータを指定して、期待される出力のスナップショットを生成します。 スナップショットテストは、コンポーネントと一緒にコミットされます。 テストフレームワークであるJestは、スナップショットをテスト用にレンダリングされた出力と比較します。
テストが失敗した場合、それは2つのことを意味する可能性があります。 テスト結果が予期しないものである場合は、コンポーネントの問題に対処する必要がある場合があります。 テスト結果が予想される場合は、新しい出力をサポートするためにスナップショットテストを更新する必要があることを意味する場合があります。
このチュートリアルでは、スナップショットテストと、それらを使用してユーザーインターフェイス(UI)が予期せず変更されないようにする方法について説明します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Node.jsはローカルにインストールされます。これは、Node.jsのインストール方法とローカル開発環境の作成に従って実行できます。
- ReactとJestにある程度精通していると有益な場合がありますが、必須ではありません。
このチュートリアルでは、 Visual Studio Code をコードエディターとして使用し、統合端末を実行するのに便利です。 ただし、これを選択したエディターとターミナルに置き換えることができます。
このチュートリアルは、Nodev14.7.0で検証されました。 npm
v6.14.7、 react
v16.13.1、および jest
v24.9.0。
ステップ1—テストするReactコンポーネントを作成する
まず、何かをテストするために、 Create ReactAppを使用してReactアプリを作成する必要があります。 このチュートリアルでは、プロジェクトは呼び出されます react-snapshot-tests
.
ターミナルを開き、次のコマンドを実行します。
- npx create-react-app@3.4.1 react-snapshot-tests
次に、新しく作成したアプリディレクトリに移動します。
- cd react-snapshot-tests
次に、アプリを起動します。
- npm start
この時点で、Reactアプリが実行され、Webブラウザーで表示できるようになります。 次に、テストできるコンポーネントを作成する必要があります。
このチュートリアルでは、作成するコンポーネントがレンダリングを行います。 items
それが受け取る小道具。
ターミナルで、 components
下のサブディレクトリ src
:
- mkdir src/components
次に、を作成します Items.js
成分:
- nano src/components/Items.js
次のコードをに追加します Items.js
:
import React from 'react';
import PropTypes from 'prop-types';
/**
* Render a list of items
*
* @param {Object} props - List of items
*/
function Items(props) {
const { items = [] } = props;
// A single item in the list, render a span.
if (items.length === 1) {
return <span>{items[0]}</span>;
}
// Multiple items on the list, render a list.
if (items.length > 1) {
return (
<ul>
{items.map(item => <li key={item}>{item}</li>)}
</ul>
);
}
// No items on the list, render an empty message.
return <span>No items in list</span>;
}
Items.propTypes = {
items: PropTypes.array,
};
Items.defaultProps = {
items: []
};
export default Items;
このコードは items
量に基づく小道具:
- 複数のアイテムがある場合、アイテムは順序付けられていないリストに表示されます(
<ul>
). - アイテムが1つしかない場合、そのアイテムは
<span>
エレメント。 - アイテムがない場合は、エラーメッセージが表示されます。
最後に、更新します App.js
コンポーネントをレンダリングするには:
- nano src/App.js
の内容を置き換えます App.js
次のように:
import React, { Component } from 'react';
import Items from './components/Items';
class App extends Component {
render() {
const items = [
'Shark',
'Dolphin',
'Octopus'
];
return (
<Items items={items} />
);
}
}
export default App;
ブラウザでアプリにアクセスすると、設定した値のリストが表示された画面が表示されます App.js
:
Output* Shark
* Dolphin
* Octopus
複数あったので items
、順不同で表示されます。
次に、スナップショットテストを追加します。
ステップ2—スナップショットテストの作成
開始するには、を削除します App.test.js
Create React Appによって生成されたファイル:
- rm src/App.test.js
このチュートリアルでは必要ありません。
次に、 react-test-renderer をインストールします。これは、DOMを必要とせずにReactコンポーネントをJavaScriptオブジェクトとしてレンダリングできるようにするライブラリです。
- npm install react-test-renderer@16.13.1
最初のテストを追加しましょう。 開始するには、を作成します Items.test.js
ファイル:
- nano src/components/Items.test.js
をレンダリングするテストを作成します Items
小道具として渡されたアイテムのないコンポーネント:
import React from 'react';
import renderer from 'react-test-renderer';
import Items from './Items';
it('renders correctly when there are no items', () => {
const tree = renderer.create(<Items />).toJSON();
expect(tree).toMatchSnapshot();
});
次に、テストを実行しましょう。 Create React Appは、テストを設定するためのすべての初期化を処理しました。
- npm test
合格テストを受ける必要があります "renders correctly when there are no items"
:
スナップショットテストを初めて実行するときは、新しいスナップショットファイルが内部に作成されることに注意してください。 __snapshots__
ディレクトリ。 テストファイルの名前が Items.test.js
、スナップショットファイルには適切な名前が付けられています Items.test.js.snap
.
の内容 Items.tests.js.snap
次のようになります。
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders correctly when there are no items 1`] = `
<span>
No items in list
</span>
`;
このスナップショットは、コンポーネントの正確な出力と一致します。
Jestはpretty-formatを使用して、スナップショットファイルを人間が読める形式にします。
これで、1つのアイテムがあり、複数のアイテムがある他の2つのシナリオのテストを作成できます。
開ける Items.tests.js
:
- nano src/components/Items.test.js
次のコード行を追加します。
// ...
it('renders correctly when there is a single item', () => {
const items = ['one'];
const tree = renderer.create(<Items items={items} />).toJSON();
expect(tree).toMatchSnapshot();
});
it('renders correctly when there are multiple items', () => {
const items = ['one', 'two', 'three'];
const tree = renderer.create(<Items items={items} />).toJSON();
expect(tree).toMatchSnapshot();
});
この時点で、3つのテストが作成されています。1つはアイテムなし、1つは単一アイテム、もう1つは複数アイテムです。
テストを再実行します。
- npm test
3つのテストすべてに合格するはずです。これで、3つのスナップショットが作成されます。 __snapshots__
ディレクトリ。
次に、スナップショットテストを更新して、失敗したテストに対処します。
ステップ3—スナップショットテストの更新
スナップショットテストが必要な理由をよりよく理解するために、 Items
コンポーネントを作成し、テストを再実行します。 これは、開発中のプロジェクトに変更が加えられたときに何が起こるかをシミュレーションしたものです。
開ける Items.js
:
- nano src/components/Items.js
クラス名をに追加します span
と li
要素:
...
/**
* Render a list of items
*
* @param {Object} props - List of items
*/
function Items(props) {
const { items = [] } = props;
// A single item in the list, render a span.
if (items.length === 1) {
return <span className="item-message">{items[0]}</span>;
}
// Multiple items on the list, render a list.
if (items.length > 1) {
return (
<ul>
{items.map(item => <li key={item} className="item-message">{item}</li>)}
</ul>
);
}
// No items on the list, render an empty message.
return <span className="empty-message">No items in list</span>;
}
Items.propTypes = {
items: PropTypes.array,
};
Items.defaultProps = {
items: [],
};
export default Items;
テストを再実行してみましょう。
- npm test
失敗したテスト結果が観察されます。
Jestは、既存のスナップショットを、更新された変更を使用してレンダリングされたコンポーネントと照合し、コンポーネントにいくつかの追加があったために失敗しました。 次に、スナップショットテストに導入された変更の差分が表示されます。
変更が予期されていない場合は、変更がデプロイされる前にエラーをキャッチし、エラーに対処できるようになりました。 変更が予想される場合は、スナップショットテストを更新して、正しく合格させる必要があります。
チュートリアルでは、これは予想される変更であると想定できます。 コンポーネントにクラス名を追加するつもりでした。 次に、スナップショットテストを更新する必要があります。
Jestがインタラクティブモードのときに、を押してスナップショットテストを更新できます。 u
提供されるオプションを使用して:
注:または、Jest をグローバルにインストールしている場合、実行できます jest --updateSnapshot
また jest -u
.
これにより、スナップショットが更新され、行った更新と一致するようになり、テストに合格します。
アイテムがない場合の以前のスナップショットテストは次のとおりです。
// ...
exports[`renders correctly when there are no items 1`] = `
<span>
No items in list
</span>
`;
// ...
そして、これがアイテムなしの新しく更新されたスナップショットテストです:
// ...
exports[`renders correctly when there are no items 1`] = `
<span
className="empty-message"
>
No items in list
</span>
`;
// ...
テストを更新した後、それらは合格します:
これで、テストに再び合格しました。 これが開発中のプロジェクトである場合は、意図した変更が将来の開発のために文書化されていることを知って、コードをデプロイできます。
結論
このチュートリアルでは、Reactコンポーネントのスナップショットテストを作成しました。 また、テストの失敗を経験するようにコンポーネントを変更しました。 最後に、スナップショットを更新してテストを修正しました。
これは、ライブプロジェクトの小さなシミュレーションでした。 テストの合格、失敗、および失敗への対処のこのサイクルは、開発ワークフローの一部になります。
スナップショットテストは、さまざまなテストツールの1つです。 したがって、アクションとレデューサーのテストを作成する必要がある場合があります。
スナップショットテストの基本を探求している間、より良いスナップショットテストを書くことについて学ぶことができることがたくさんあります。 スナップショットテストの詳細については、Jestのドキュメントのスナップショットのベストプラクティスをご覧ください。
Reactの詳細については、Reactトピックページで演習とプログラミングプロジェクトを確認してください。