apeescape2.com
  • メイン
  • 収益性と効率性
  • 収益と成長
  • Webフロントエンド
  • 財務プロセス
技術

ReactコンポーネントがUIテストを容易にする方法

バックエンドのテストは簡単です。選択した言語を選択し、それをお気に入りのフレームワークと組み合わせて、いくつかのテストを作成し、「実行」をクリックします。あなたのコンソールは言う 'わーい!できます!' 継続的インテグレーションサービスは、プッシュするたびにテストを実行します。人生は素晴らしいものです。

確かに、テスト駆動開発(TDD)は最初は奇妙ですが、予測可能な環境、複数のテストランナー、フレームワークに組み込まれたテストツール、継続的インテグレーションのサポートにより、作業が楽になります。 5年前、私はテストがこれまでに経験したすべての問題の解決策だと思っていました。

その後、バックボーンが大きくなりました。



私たちは皆に切り替えました フロントエンド MVC。テスト可能なバックエンドは、栄光のデータベースサーバーになりました。最も複雑なコードがブラウザに移動しました。そして、私たちのアプリは実際にはテストできなくなりました。

これは、フロントエンドコードをテストして UIコンポーネント ちょっと難しいです。

モデルが正常に動作することを確認するだけであれば、それほど悪くはありません。または、関数を呼び出すと正しい値が変更されます。 Reactユニットテストのために必要なことは次のとおりです。

  • 整形式の分離されたモジュールを作成します。
  • JasmineまたはMochaテスト(またはその他)を使用して関数を実行します。
  • KarmaやChutzpahなどのテストランナーを使用します。

それでおしまい。私たちのコードはユニットテストされています。

昔はそうだった ランニング フロントエンドテストは難しい部分でした。すべてのフレームワークには独自のアイデアがあり、ほとんどの場合、テストを実行するたびに手動で更新するブラウザーウィンドウが表示されます。もちろん、あなたはいつも忘れるでしょう。少なくとも、私はそうしました。

2012年、VojtaJinaは カルマランナー (当時はTestacularと呼ばれていました)。 Karmaを使用すると、フロントエンドテストはツールチェーンの完全な市民になります。 Reactテストはターミナルまたは継続的インテグレーションサーバーで実行され、ファイルを変更すると自動的に再実行されます。また、複数のブラウザーで同時にコードをテストすることもできます。

これ以上何を望むことができますか?さて、 実際に フロントエンドコードをテストします。

フロントエンドテストには、単体テスト以上のものが必要です

単体テストは優れています。アルゴリズムが毎回正しいことを行うかどうかを確認したり、入力検証ロジック、データ変換、その他の分離された操作を確認したりするのに最適な方法です。ユニットテストはファンダメンタルズに最適です。

ただし、フロントエンドコードは、データの操作に関するものではありません。ユーザーイベントと適切なビューを適切なタイミングでレンダリングすることが重要です。フロントエンドはユーザーに関するものです。

これが私たちができることをしたいことです:

  • Reactユーザーイベントをテストする
  • それらのイベントへの応答をテストします
  • 適切なものが適切なタイミングでレンダリングされることを確認してください
  • 多くのブラウザでテストを実行する
  • ファイルの変更に対してテストを再実行します
  • Travisのような継続的インテグレーションシステムと連携する

これを行ってきた10年間、Reactを突っ込み始めるまで、ユーザーインタラクションをテストしてレンダリングを表示する適切な方法を見つけられませんでした。

Reactユニットテスト:UIコンポーネント

Reactは、これらの目標を達成するための最も簡単な方法です。部分的には、それが私たちにアプリを設計することを強制する方法のために テスト可能なパターン 、部分的には、素晴らしいReactテストユーティリティがあるためです。

これまでReactを使用したことがない場合は、私の本をチェックしてください。 React + d3.js 。視覚化を対象としていますが、 「素晴らしい軽量イントロ」 反応する。

Reactは、すべてを「コンポーネント」として構築することを強制します。 Reactコンポーネントは、ウィジェット、またはいくつかのロジックを備えたHTMLのチャンクと考えることができます。それらは、オブジェクトであることを除いて、関数型プログラミングの多くの最良の原則に従います。

AWSソリューションアーキテクト認定の準備方法

たとえば、同じパラメーターセットが与えられた場合、Reactコンポーネントは常に同じ出力をレンダリングします。何度レンダリングしても、誰がレンダリングしても、出力をどこに配置しても。いつも同じ。その結果、Reactコンポーネントをテストするために複雑なスキャフォールディングを実行する必要がありません。それらはプロパティのみを気にし、グローバル変数と構成オブジェクトの追跡は必要ありません。

私たちは、状態を回避することによってこれを大部分達成します。あなたはこれを呼ぶでしょう 参照の透明性 関数型プログラミングで。 Reactにはこれに特別な名前はないと思いますが、公式ドキュメントでは、状態の使用をできるだけ避けることを推奨しています。

ユーザーインタラクションのテストに関しては、Reactは関数コールバックにバインドされたイベントでカバーしています。テストスパイを設定し、クリックイベントが適切な関数を呼び出すことを確認するのは簡単です。また、Reactコンポーネントはそれ自体をレンダリングするため、クリックイベントをトリガーして、HTMLの変更を確認するだけです。これは、Reactコンポーネントがそれ自体のみを気にするために機能します。クリック ここに 物事を変えない そこ 。明確に定義された関数呼び出しだけで、イベントハンドラーのネストを処理する必要はありません。

ああ、Reactは魔法なので、DOMについて心配する必要はありません。 Reactはいわゆる 仮想DOM コンポーネントをJavaScript変数にレンダリングします。そして、仮想DOMへの参照は、実際にReactコンポーネントをテストするために必要なすべてです。

とても甘いです。

ReactのTestUtils

Reactには一連の組み込みTestUtilsが付属しています。 Jestというおすすめのテストランナーもいますが、私は好きではありません。その理由を少し説明します。まず、TestUtils。

require('react/addons').addons.TestUtilsのようなことでそれらを取得します。これは、ユーザーインタラクションをテストして出力を確認するためのエントリポイントです。

React TestUtils Reactコンポーネントをページに挿入する代わりに、そのDOMを変数に配置してレンダリングしましょう。たとえば、Reactコンポーネントをレンダリングするには、次のようにします。

var component = TestUtils.renderIntoDocument( );

次に、TestUtilsを使用できますすべての子がレンダリングされたかどうかを確認します。このようなもの:

var h1 = TestUtils.findRenderedDOMComponentWithTag( component, 'h1' );

findRenderedDOMComponentWithTag子を調べて、探しているコンポーネントを見つけて、それを返します。戻り値はReactコンポーネントのように動作します。

その後、getDOMNode()を使用できます生のDOM要素にアクセスし、その値をテストします。 h1を確認するにはコンポーネントのタグは言う 'タイトル' 、これを書きます:

expect(h1.getDOMNode().textContent) .toEqual('A title');

まとめると、完全なテストは次のようになります。

it('renders an h1', function () { var component = TestUtils.renderIntoDocument( ); var h1 = TestUtils.findRenderedDOMComponentWithTag( component, 'h1' ); expect(h1.getDOMNode().textContent) .toEqual('A title'); });

すばらしい点は、TestUtilsでユーザーイベントもトリガーできることです。クリックイベントの場合、次のように記述します。

var node = component .findRenderedDOMComponentWithTag('button') .getDOMNode(); TestUtils.Simulate.click(node);

これはクリックをシミュレートし、潜在的なリスナーをトリガーします。リスナーは、出力、状態、またはその両方を変更するコンポーネントメソッドである必要があります。これらのリスナーは、必要に応じて親コンポーネントの関数を呼び出すことができます。

すべてのケースをテストするのは簡単です。変更された状態はcomponent.stateにあり、通常のDOM関数で出力にアクセスでき、スパイで関数呼び出しを行うことができます。

なぜジェストではないのですか?

Reactの公式ドキュメントでは、https://facebook.github.io/jest/をテストランナーおよびReactテストフレームワークとして使用することを推奨しています。 JestはJasmine上に構築されており、同じ構文を使用します。 Jasmineから得られるすべてのものに加えて、Jestはテストしているコンポーネント以外のすべてをモックします。これは理論的には素晴らしいですが、私はそれが面倒だと思います。まだ実装していないもの、またはコードベースの別の部分からのものは、undefinedです。これは多くの場合問題ありませんが、静かに失敗するバグにつながる可能性があります。

たとえば、クリックイベントのテストに問題がありました。私が何を試しても、リスナーを呼び出さないだけです。それから私は関数がジェストによって嘲笑されたことに気づきました、そしてそれは私にこれを決して教えませんでした。

しかし、Jestの最悪の犯罪は、これまで、新しい変更を自動的にテストするための監視モードがなかったことでした。一度実行してテスト結果を取得することができ、それだけです。 (私は仕事中にバックグラウンドでテストを実行するのが好きです。そうでなければ、テストを実行するのを忘れます。)現在、これはもはや問題ではありません。

ああ、Jestは複数のブラウザでのReactテストの実行をサポートしていません。これは以前ほど問題ではありませんが、まれな機会に重要な機能だと思います。 特異なバグ Chromeの特定のバージョンでのみ発生します…

編集者のメモ:この記事が最初に書かれて以来、Jestは大幅に改善されました。あなたは私たちのより最近のチュートリアルを読むことができます、 酵素とジェストを使用したReactユニットテスト 、そしてJestテストが今日のタスクに対応しているかどうかを自分で判断します。

Reactテスト:統合された例

とにかく、理論的には、優れたフロントエンドReactテストがどのように機能するかを見てきました。短い例でそれを実行に移しましょう。

Reactとで作成された散布図コンポーネントを使用して乱数を生成するさまざまな方法を視覚化します。 d3.js 。コードとそのデモも Githubで 。

Karmaをテストランナーとして、Mochaをテストフレームワークとして、Webpackをモジュールローダーとして使用します。

セットアップ

ソースファイルは/srcになりますディレクトリを作成し、テストを/src/__tests__に配置しますディレクトリ。 src内に、主要コンポーネントごとに1つずつ、それぞれ独自のテストファイルを持つ複数のディレクトリを配置できるという考え方です。このようにソースコードとテストファイルをバンドルすると、さまざまなプロジェクトでReactコンポーネントを簡単に再利用できます。

ディレクトリ構造が整ったら、次のような依存関係をインストールできます。

$ npm install --save-dev react d3 webpack babel-loader karma karma-cli karma-mocha karma-webpack expect

何かがインストールに失敗した場合は、インストールのその部分を再実行してみてください。 NPMは、再実行時に消える方法で失敗することがあります。

私たちのpackage.json完了すると、ファイルは次のようになります。

// package.json { 'name': 'react-testing-example', 'description': 'A sample project to investigate testing options with ReactJS', 'scripts': { 'test': 'karma start' }, // ... 'homepage': 'https://github.com/Swizec/react-testing-example', 'devDependencies': { 'babel-core': '^5.2.17', 'babel-loader': '^5.0.0', 'd3': '^3.5.5', 'expect': '^1.6.0', 'jsx-loader': '^0.13.2', 'karma': '^0.12.31', 'karma-chrome-launcher': '^0.1.10', 'karma-cli': '0.0.4', 'karma-mocha': '^0.1.10', 'karma-sourcemap-loader': '^0.3.4', 'karma-webpack': '^1.5.1', 'mocha': '^2.2.4', 'react': '^0.13.3', 'react-hot-loader': '^1.2.7', 'react-tools': '^0.13.3', 'webpack': '^1.9.4', 'webpack-dev-server': '^1.8.2' } }

いくつかの構成が完了すると、npm testのいずれかを使用してテストを実行できるようになります。またはkarma start。

テストの実行

構成

構成にはあまり意味がありません。 Webpackがコードの検索方法を知っていること、およびKarmaがテストの実行方法を知っていることを確認する必要があります。

2行のJavaScriptを./tests.webpack.jsに配置しますKarmaとWebpackが一緒にプレイするのに役立つファイル:

// tests.webpack.js var context = require.context('./src', true, /-test.jsx?$/); context.keys().forEach(context);

これにより、Webpackは-testで何でも考慮するようになります。テストスイートの一部となるサフィックス。

Karmaの構成には、もう少し作業が必要です。

// karma.conf.js var webpack = require('webpack'); module.exports = function (config) { config.set({ browsers: ['Chrome'], singleRun: true, frameworks: ['mocha'], files: [ 'tests.webpack.js' ], preprocessors: { 'tests.webpack.js': ['webpack'] }, reporters: ['dots'], webpack: { module: { loaders: [ {test: /.jsx?$/, exclude: /node_modules/, loader: 'babel-loader'} ] }, watch: true }, webpackServer: { noInfo: true } }); };

これらの行のほとんどは、デフォルトのKarma構成からのものです。 browsersを使用しましたテストはChromeで実行する必要があると言うと、frameworks使用しているテストフレームワークを指定し、singleRunデフォルトでテストを1回だけ実行するようにします。 karma start --no-single-runを使用すると、カルマをバックグラウンドで実行し続けることができます。

これらの3つは明らかです。 Webpackのものはもっと面白いです。

Webpackはコードの依存関係ツリーを処理するため、filesですべてのファイルを指定する必要はありません。アレイ。必要なのはtests.webpack.jsだけで、必要なすべてのファイルが必要です。

webpackを使用しますWebpackに何をすべきかを指示する設定。通常の環境では、この部分はwebpack.config.jsになります。ファイル。

また、Webpackに使用するように指示します babel-loader JavaScript用です。これは私たちにからのすべての素晴らしい新機能を与えます ECMAScript2015 そして ReactのJSX 。

webpackServerで構成では、デバッグ情報を出力しないようにWebpackに指示します。それは私たちのテスト出力を台無しにするだけです。

Reactコンポーネントとテスト

テストスイートを実行すると、残りは簡単です。ランダムな座標の配列を受け入れ、多数の点を持つ要素を作成するコンポーネントを作成する必要があります。

Reactテストのベストプラクティスに従う-つまり標準的なTDDプラクティス-最初にテストを記述し、次に実際のReactコンポーネントを記述します。 src/__tests__/のバニラテストファイルから始めましょう。

// ScatterPlot-test.jsx var React = require('react/addons'), TestUtils = React.addons.TestUtils, expect = require('expect'), ScatterPlot = require('../ScatterPlot.jsx'); var d3 = require('d3'); describe('ScatterPlot', function () { var normal = d3.random.normal(1, 1), mockData = d3.range(5).map(function () { return {x: normal(), y: normal()}; }); });

まず、React、そのTestUtils、d3.js、expectが必要です。ライブラリ、およびテストしているコード。次に、describeを使用して新しいテストスイートを作成し、ランダムデータを作成します。

最初のテストでは、ScatterPlotを確認しましょう。タイトルをレンダリングします。私たちのテストはdescribeの内部に入りますブロック:

// ScatterPlot-test.jsx it('renders an h1', function () { var scatterplot = TestUtils.renderIntoDocument( ); var h1 = TestUtils.findRenderedDOMComponentWithTag( scatterplot, 'h1' ); expect(h1.getDOMNode().textContent).toEqual('This is a random scatterplot'); });

ほとんどのテストは同じパターンに従います。

  1. レンダリングします。
  2. 特定のノードを検索します。
  3. 内容を確認してください。

前に見たように、renderIntoDocumentコンポーネントをレンダリングしますfindRenderedDOMComponentWithTagテストしている特定の部分を見つけ、getDOMNode生のDOMアクセスを提供します。

最初、私たちのテストは失敗します。合格するには、タイトルタグをレンダリングするコンポーネントを作成する必要があります。

var React = require('react/addons'); var d3 = require('d3'); var ScatterPlot = React.createClass({ render: function () { return ( {this.props.data.map(function (pos, i) { var key = 'circle-'+i; return ( ); }.bind(this))}; ); }

このコードはthis.props.dataを通過します配列し、各データポイントの要素を追加します。シンプル。

Reactコンポーネントのテストで、UIテストに絶望することはもうありません。 つぶやき

Reactとd3.jsを組み合わせてデータ視覚化コンポーネントを作成する方法について詳しく知りたい場合は、私の本をチェックするもう1つの大きな理由です。 React + d3.js 。

自動化されたReactコンポーネントテスト:思ったより簡単

Reactを使用してテスト可能なフロントエンドコンポーネントを作成するために知っておく必要があるのはこれだけです。 Reactコンポーネントをテストするその他のコードを確認するには、前述のように、GithubでReactテストのサンプルコードベースを確認してください。

私たちはそれを学びました:

  1. Reactは、モジュール化とカプセル化を強制します。
  2. これにより、ReactUIテストを簡単に自動化できます。
  3. フロントエンドには単体テストだけでは不十分です。
  4. カルマは素晴らしいテストランナーです。
  5. ジェストには可能性がありますが、まだ十分ではありません。 (または多分今はそうです。)

この記事が気に入ったら、 Twitterでフォローしてください 以下にコメントを残してください。読んでくれてありがとう、そして幸せなReactテスト!

関連: コンポーネントを最適化してReactのパフォーマンスを向上させる方法

基本を理解する

コンポーネントテストとは何ですか?

コンポーネントテストはユニットテストに似ていますが、より高いレベルであり、ユニット間のある程度の統合が含まれます。場合によっては、これはアプリケーション全体のコンテキストで実行する必要があります。

Reactコンポーネントをどのようにテストしますか?

ベストプラクティスを使用して設計された場合のReactコンポーネントのモジュール式で反復可能な性質により、アプリケーションの残りの部分を必要とせずに、単体テストのようにコンポーネントテストを実行できます。テストフレームワーク(例:ジャスミン)とテストランナー(例:カルマ)のみが必要です。

ユニットテストとはどういう意味ですか?

単体テストは、機能ごとに、可能な限り最高かつ最も分離されたレベルでテストします。入力のセットが与えられた場合、関数が正しい出力を返すかどうかがわかります。

参謀長

その他

参謀長
情報アーキテクチャの包括的なガイド

情報アーキテクチャの包括的なガイド

Uxデザイン

人気の投稿
Go言語に対する4つの批判
Go言語に対する4つの批判
SVGアニメーションのハウツーガイド
SVGアニメーションのハウツーガイド
説得力のあるデザイン:高度な心理学を効果的に使用する
説得力のあるデザイン:高度な心理学を効果的に使用する
eコマース101:ショッピングカートの放棄を理解する(インフォグラフィック付き)
eコマース101:ショッピングカートの放棄を理解する(インフォグラフィック付き)
開発者向けAndroidM(Android 6.0):正しい方向への進化の一歩
開発者向けAndroidM(Android 6.0):正しい方向への進化の一歩
 
フロントエンドコードのMonoreposガイド
フロントエンドコードのMonoreposガイド
Terraform AWSクラウド:健全なインフラストラクチャ管理
Terraform AWSクラウド:健全なインフラストラクチャ管理
ブロックチェーンテクノロジーの説明:ビットコインへの電力供給
ブロックチェーンテクノロジーの説明:ビットコインへの電力供給
サブスクリプションビジネスモデルに疲れた
サブスクリプションビジネスモデルに疲れた
同じマシンでのMySQLマスタースレーブレプリケーション
同じマシンでのMySQLマスタースレーブレプリケーション
人気の投稿
  • アルゴリズム取引の方法
  • コンサルティングビジネスのクライアントを見つける方法
  • javascriptの現在の日付と時刻
  • 国際課税における国境調整の役割
  • Webアプリケーション開発のベストプラクティス
  • cとc ++とは何ですか
カテゴリー
Webフロントエンド トレンド アジャイルタレント 仕事の未来 ブランドデザイン プロジェクト管理 Uxデザイン モバイル 人とチーム プロセスとツール

© 2021 | 全著作権所有

apeescape2.com