「Jest+Enzymeに基づくReactユニットテスト|掘金技術募集文」

14476 ワード

Reactユニットテストを学びたいなら、この文章から始めましょう.Starプロジェクト、cloneはローカルに行って、チュートリアルに従って1回歩いて、どんな問題がissueの討論を歓迎します.
プロジェクトGitHubアドレス:react-test-demo
文章の主な内容は以下の通りです.
  • JestとEnzymeの基本紹介
  • テスト環境構築
  • テストスクリプト作成
  • UIコンポーネントテスト
  • Reducerテスト
  • 実行およびデバッグ
  • 参考資料
  • Jest、Enzyme紹介


    JestはFacebookが発表したオープンソースのJasmineフレームワークに基づくJavaScriptユニットテストツールです.内蔵されたテスト環境DOM APIサポート、ブレークスルーライブラリ、Mockライブラリなど、Spapshot Testing、Instant Feedbackなどの特性も含まれています.
    AirbnbオープンソースのReactテストクラスライブラリEnzymeは、シンプルで強力なAPIを提供し、jQueryスタイルの方法でDOM処理を行い、開発体験が非常に友好的です.オープンソースコミュニティだけでなく、React公式の推薦も受けた.

    テスト環境構築


    Reactアプリケーションを開発した上で(デフォルトではWebpack+Babelで構築アプリケーションをパッケージ化しています)、Jest Enzymeと対応するbabel-jestをインストールする必要があります.
    npm install jest enzyme babel-jest --save-dev
    

    npm依存パッケージをダウンロードした後、package.jsonに属性を追加し、Jestを構成する必要があります.
      "jest": {
        "moduleFileExtensions": [
          "js",
          "jsx"
        ],
        "moduleNameMapper": {
          "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/__mocks__/fileMock.js",
          ".*\\.(css|less|scss)$": "/__mocks__/styleMock.js"
        },
        "transform": {
          "^.+\\.js$": "babel-jest"
        }
      },
    
    test scriptsを追加
    "scripts": {
        "dev": "NODE_ENV=development webpack-dev-server  --inline --progress --colors --port 3000 --host 0.0.0.0 ",
        "test": "jest"
      }
    

    次のようになります.
  • moduleFileExtensions:ロードをサポートするファイル名を表し、Webpackのresolve.extensionsに類似する
  • moduleNameMapper:Mockが必要なリソース名を表します.Mockの静的リソース(less、scssなど)が必要な場合は、Mockのパス/__mocks__/yourMock.js
  • を構成する必要がある.
  • transform ES 6/ES 7構文をコンパイルするには、babel-jestに合わせて
  • を使用する必要があります.
    上の3つは一般的な構成で、より多くのJest構成は公式ドキュメントを参照してください:Jest Configuration

    スクリプト作成のテスト


    UIコンポーネントテスト


    環境が構築されたら、テストスクリプトを書くことができます.始める前に、まずTodoアプリケーションの構成部分を分析します.
    応用主体構造は以下のsrc/component/App.jsである.
    class App extends Component {
      render() {
        const { params } = this.props;
        return (
          <section className="todoapp">
            <div className="main">
              <AddTodo />
              <VisibleTodoList filter={params.filter || 'all'} />
            div>
             <Footer />
          section>
        )
      }
    }
    

    アプリケーション全体を3つのコンポーネントに分けることができます.
  • 最外層の
  • の中間のInput入力ボックス
  • の下のTODOリスト
  • ここで、はUIコンポーネントであり、およびはスマートコンポーネントであり、スマートコンポーネントに対応するUIコンポーネントおよびを見つける必要がある.Input入力ボックスであり、文字入力を受け、リターンキーをノックしてTodoを作成します.コードは次のsrc/component/AddTodoView.jsです.
    import React, { Component, PropTypes } from 'react'
    class AddTodoView extends Component {
      render() {
        return (
          <header className="header">
            <h1>todosh1>
            <input
              className="new-todo"
              type="text"
              onKeyUp={e => this.handleClick(e)}
              placeholder="input todo item"
              ref='input' />
          header>
        )
      }
    
      handleClick(e) {
        if (e.keyCode === 13) {
          const node = this.refs.input;
          const text = node.value.trim();
          text && this.props.onAddClick(text);
          node.value = '';
        }
      }
    }
    

    このコンポーネントの機能を理解したら、まず、どのコンポーネントをテストする必要があるかを明確にする必要があります.
  • コンポーネントが正常にレンダーされているかどうか
  • ユーザが入力内容がリターンキーを叩くと、propsによって伝達されるonAddClick(text)メソッド
  • が正常に呼び出すことができるかどうか.
  • 作成完了後にInputをクリアする値
  • ユーザが値を入力していない場合、バックトラックをノックするとき、propsによって伝達されるonAddClick(text)メソッド
  • は呼び出すべきではない.
    上記の分析を経て、ユニットテストスクリプトの作成を開始することができます.

    ステップ1:関連libの導入

    import React from 'react'
    import App from '../../src/component/App'
    import { shallow } from 'enzyme'
    

    ここでは、shallowが提供するAPIの1つであり、浅いレンダリングを実現することができるEnzyme方法を導入した.仮想ノードにレンダリングするだけで、実際のノードに戻ることなく、テストのパフォーマンスを大幅に向上させることができます.ただし、サブコンポーネントを含む宣言サイクルをテストする必要があるコンポーネントをテストするのには適していません.Enzymeには、他の2つのAPIも提供されています.
  • mount:Full Renderingは、DOM APIに存在するインタラクションコンポーネント、またはコンポーネントの完全な宣言サイクルをテストする必要がある
  • に非常に適している.
  • render:Static Renderingは、Reactコンポーネントを静的HTMLにレンダリングし、生成されたHTML構造を解析するために使用されます.renderが返すwrapperは、他の2つのAPIと同様である.異なる点は、renderがサードパーティ製HTML解析器およびCheerioを使用していることである.

  • 一般的にはshallowで十分ですが、たまにmountを使うことがあります.

    ステップ2:Propsをシミュレートし、コンポーネントをレンダリングしてWrapperを作成する


    このステップでは、setup関数を作成して実装することができます.
    const setup = () => {
      //   props
      const props = {
        // Jest  mock  
        onAddClick: jest.fn()
      }
    
      //   enzyme   shallow( )  
      const wrapper = shallow(<AddTodoView {...props} />)
      return {
        props,
        wrapper
      }
    }
    
    Propsに関数が含まれている場合は、Jestが提供するmockFunctionを使用する必要があります.

    ステップ4:Test Caseの作成


    ここのCaseは私たちの前の分析に基づいてテストする必要がある点を書きます.
    Case 1:コンポーネントが正常にレンダリングされているかどうかをテストします
    describe('AddTodoView', () => {
      const { wrapper, props } = setup();
    
      // case1
      //   Input, 
      it('AddTodoView Component should be render', () => {
        //.find(selector)   Enzyme shallow Rendering  ,  
        //   Enzyme   http://airbnb.io/enzyme/docs/api/shallow.html
        expect(wrapper.find('input').exists());
      })
    })
    

    最初のテスト例を書き終わったら、テストの効果を見てみましょう.Terminalにnpm run testと入力します.効果は次のとおりです.
    Case 2:内容を入力してリターンキーを押し、コンポーネントがpropsを呼び出す方法をテストする
      it('When the Enter key was pressed, onAddClick() shoule be called', () => {
        // mock input   Enter 
        const mockEvent = {
          keyCode: 13, // enter  
          target: {
            value: 'Test'
          }
        }
        //   Enzyme   simulate api   DOM  
        wrapper.find('input').simulate('keyup',mockEvent)
        //   props.onAddClick  
        expect(props.onAddClick).toBeCalled()
      })
    

    上のコードは最初のcaseと2点増えました.
  • は、DOMイベント
  • をシミュレートするためにmockEventを追加する.
  • は、Enzymeによって提供される.simulate(’keyup‘, mockEvent)を使用してクリックイベントをシミュレートし、ここでのkeyupは、ReactコンポーネントのonKeyUpに自動的に変換され、呼び出される.
  • npm run testを実行してテストの効果を確認します.
    上の2つのTest Caseの分析を経て、次のCase 3とCase 4の考え方も同じで、具体的な書き方はコードを参照してください:test/component/AddTodoView.spec.js、ここでは一つ一つ説明しません.

    Reducerテスト


    Reducerは純粋な関数であるため、Reducerのテストは非常に簡単であり、Reduxの公式ドキュメントにもテストの例が提供されています.コードは以下の通りです.
    import reducer from '../../reducers/todos'
    import * as types from '../../constants/ActionTypes'
    
    describe('todos reducer', () => {
      it('should return the initial state', () => {
        expect(
          reducer(undefined, {})
        ).toEqual([
          {
            text: 'Use Redux',
            completed: false,
            id: 0
          }
        ])
      })
    
      it('should handle ADD_TODO', () => {
        expect(
          reducer([], {
            type: types.ADD_TODO,
            text: 'Run the tests'
          })
        ).toEqual(
          [
            {
              text: 'Run the tests',
              completed: false,
              id: 0
            }
          ]
        )
    
        expect(
          reducer(
            [
              {
                text: 'Use Redux',
                completed: false,
                id: 0
              }
            ],
            {
              type: types.ADD_TODO,
              text: 'Run the tests'
            }
          )
        ).toEqual(
          [
            {
              text: 'Run the tests',
              completed: false,
              id: 1
            },
            {
              text: 'Use Redux',
              completed: false,
              id: 0
            }
          ]
        )
      })
    })
    
    

    Reduxのテストについては、公式サイトで提供されている例を参照してください.テスト-Reduxドキュメントの作成

    デバッグおよびテストオーバーライド率レポート


    テストスクリプトプロセスを実行すると、Jestのエラープロンプト情報は友好的で、エラー情報によって一般的に問題の所在を見つけることができます.同時にJestは、--coverageというパラメータを追加するだけで生成できるテストオーバーライド率レポートを生成するコマンドも提供しています.端末に表示されるだけでなく、
    また、プロジェクトにcoverageフォルダを生成することもでき、非常に便利です.

    資料

  • jest+enzymeを使用してreactプロジェクトテスト
  • を行う
  • フロントエンド自動化テスト
  • について
  • Enzyme API
  • Jest

  • 掘金技術征文第3期:あなたのベストプラクティスについて話します:https://juejin.im/post/58d8e99261ff4b006cd6874d