Jestを使用したJavaScriptのテスト

Jestは、JavaScriptコードをテストするためのライブラリです。これはFacebookによって管理されているオープンソースプロジェクトであり、Reactコードのテストに特に適していますが、それに限定されません。任意のJavaScriptコードをテストできます。ジェストは非常に高速で使いやすいです

ジェスト入門

Jestは、JavaScriptコードをテストするためのライブラリです。

これはFacebookによって管理されているオープンソースプロジェクトであり、Reactコードのテストに特に適していますが、それに限定されません。任意のJavaScriptコードをテストできます。その強みは次のとおりです。

  • これは速い
  • 実行できますスナップショットテスト
  • それは意見があり、あなたが選択をすることを必要とせずに箱から出してすべてを提供します

JestはMochaと非常によく似たツールですが、違いがあります。

  • モカはあまり意見がありませんが、ジェストには特定の規則があります
  • モカはより多くの構成を必要としますが、ジェストは意見が分かれているため、通常は箱から出して動作します
  • モカはより古く、より確立されており、より多くのツールが統合されています

私の意見では、Jestの最大の機能は、他のテストライブラリと対話してその作業を実行しなくても機能する、すぐに使用できるソリューションです。

インストール

Jestは自動的にインストールされますcreate-react-app、したがって、それを使用する場合は、Jestをインストールする必要はありません。

Jestは、を使用して他のプロジェクトにインストールできます。

yarn add --dev jest

またはnpm

npm install --save-dev jest

Jestをに入れるように両方に指示する方法に注意してくださいdevDependenciesの一部package.jsonファイル。これにより、開発環境にのみインストールされ、本番環境にはインストールされません。

この行をスクリプト部分に追加しますpackage.jsonファイル:

{
  "scripts": {
    "test": "jest"
  }
}

を使用してテストを実行できるようにしますyarn testまたはnpm run test

または、Jestをグローバルにインストールすることもできます。

yarn global add jest

を使用してすべてのテストを実行しますjestコマンドラインツール。

最初のJestテストを作成する

で作成されたプロジェクトcreate-react-appJestをすぐにインストールして事前構成しますが、プロジェクトにJestを追加するのは、入力するのと同じくらい簡単です。

yarn add --dev jest

あなたに追加package.jsonこの行:

{
  "scripts": {
    "test": "jest"
  }
}

実行してテストを実行しますyarn testあなたの殻の中で。

ここにはテストがないため、何も実行されません。

Testing with Yarn

最初のテストを作成しましょう。開くmath.jsファイルを作成し、後でテストするいくつかの関数を入力します。

const sum = (a, b) => a + b
const mul = (a, b) => a * b
const sub = (a, b) => a - b
const div = (a, b) => a / b

module.exports = { sum, mul, sub, div }

次に、math.test.js同じフォルダー内のファイルで、Jestを使用してで定義された関数をテストします。math.js

const { sum, mul, sub, div } = require('./math')

test(‘Adding 1 + 1 equals 2’, () => { expect(sum(1, 1)).toBe(2) }) test(‘Multiplying 1 * 1 equals 1’, () => { expect(mul(1, 1)).toBe(1) }) test(‘Subtracting 1 - 1 equals 0’, () => { expect(sub(1, 1)).toBe(0) }) test(‘Dividing 1 / 1 equals 1’, () => { expect(div(1, 1)).toBe(1) })

ランニングyarn testその結果、Jestは検出されたすべてのテストファイルで実行され、最終結果が返されます。

Passing tests

VSCodeでJestを実行する

Visual Studio Codeは、JavaScript開発用の優れたエディターです。ザ・ジェストエクステンション私たちのテストに一流の統合を提供します。

インストールすると、devDependenciesにJestがインストールされているかどうかが自動的に検出され、テストが実行されます。を選択して、手動でテストを呼び出すこともできます。ジェスト:スタートランナーコマンド。テストを実行し、監視モードのままにして、テストを含むファイルの1つ(またはテストファイル)を変更するたびにテストを再実行します。

A simple Jest test running in VS Code

マッチャー

前回の記事で使用しましたtoBe()唯一としてマッチャー

test('Adding 1 + 1 equals 2', () => {
  expect(sum(1, 1)).toBe(2)
})

マッチャーは、値をテストできるようにする方法です。

最も一般的に使用されるマッチャー、の結果の値を比較するexpect()引数として渡された値は次のとおりです。

  • toBeを使用して、厳密な等式を比較します===
  • toEqual2つの変数の値を比較します。オブジェクトまたは配列の場合は、すべてのプロパティまたは要素が等しいかどうかをチェックします
  • toBeNullnull値を渡す場合はtrue
  • toBeDefined定義された値を渡す場合はtrue(上記の反対)
  • toBeUndefined未定義の値を渡す場合はtrue
  • toBeCloseTo丸め誤差を回避して、浮動小数点値を比較するために使用されます
  • toBeTruthy値がtrueと見なされる場合はtrue(ifします)
  • toBeFalsy値がfalseと見なされる場合はtrue(ifします)
  • toBeGreaterThanexpect()の結果が引数よりも高い場合はtrue
  • toBeGreaterThanOrEqualexpect()の結果が引数と等しいか、引数よりも大きい場合はtrue
  • toBeLessThanexpect()の結果が引数よりも小さい場合はtrue
  • toBeLessThanOrEqualexpect()の結果が引数と等しいか、引数よりも小さい場合はtrue
  • toMatch文字列をと比較するために使用されます正規表現パターンマッチング
  • toContain配列で使用されます。予期される配列の要素セットに引数が含まれている場合はtrueです。
  • toHaveLength(number):配列の長さをチェックします
  • toHaveProperty(key, value):オブジェクトにプロパティがあるかどうかを確認し、オプションでその値を確認します
  • toThrow渡す関数が例外(一般的に)または特定の例外をスローするかどうかをチェックします
  • toBeInstanceOf():オブジェクトがクラスのインスタンスであるかどうかを確認します

これらのマッチャーはすべて、を使用して無効にすることができます.not.ステートメント内の例:

test('Adding 1 + 1 does not equal 3', () => {
  expect(sum(1, 1)).not.toBe(3)
})

約束で使用するために、あなたは使用することができます.resolvesそして.rejects

expect(Promise.resolve('lemon')).resolves.toBe('lemon')

expect(Promise.reject(new Error(‘octopus’))).rejects.toThrow(‘octopus’)

セットアップ

テストを実行する前に、初期化を実行する必要があります。

すべてのテストが実行される前に一度何かを行うには、beforeAll()関数:

beforeAll(() => {
  //do something
})

各テストを実行する前に何かを実行するには、beforeEach()

beforeEach(() => {
  //do something
})

取り壊す

セットアップで実行できるのと同じように、各テストの実行後に何かを実行することもできます。

afterEach(() => {
  //do something
})

そして、すべてのテストが終了した後:

afterAll(() => {
  //do something
})

describe()を使用したグループテスト

セットアップ機能とティアダウン機能を分離するテストのグループを1つのファイルに作成できます。

describe('first set', () => {
  beforeEach(() => {
    //do something
  })
  afterAll(() => {
    //do something
  })
  test(/*...*/)
  test(/*...*/)
})

describe(‘second set’, () => { beforeEach(() => { //do something }) beforeAll(() => { //do something }) test(//) test(//) })

非同期コードのテスト

最新のJavaScriptの非同期コードには、基本的に2つの形式があります。コールバックとpromiseです。約束に加えて、async / awaitを使用できます。

コールバック

Jestはテストを実行しないため、コールバックにテストを含めることはできません。テストファイルの実行は、コールバックが呼び出される前に終了します。これを修正するには、パラメータをテスト関数に渡します。これを簡単に呼び出すことができます。done。ジェストはあなたが電話するまで待ちますdone()そのテストを終了する前に:

//uppercase.js
function uppercase(str, callback) {
  callback(str.toUpperCase())
}
module.exports = uppercase

//uppercase.test.js const uppercase = require(’./src/uppercase’)

test(uppercase 'test' to equal 'TEST', (done) => { uppercase(‘test’, (str) => { expect(str).toBe(‘TEST’) done() } })

Jest async test callback

約束

promiseを返す関数を使用して、約束を返すテストから:

//uppercase.js
const uppercase = str => {
  return new Promise((resolve, reject) => {
    if (!str) {
      reject('Empty string')
      return
    }
    resolve(str.toUpperCase())
  })
}
module.exports = uppercase

//uppercase.test.js const uppercase = require(’./uppercase’) test(uppercase 'test' to equal 'TEST', () => { return uppercase(‘test’).then(str => { expect(str).toBe(‘TEST’) }) })

Jest async test promises

拒否されたプロミスは、を使用してテストできます.catch()

//uppercase.js
const uppercase = str => {
  return new Promise((resolve, reject) => {
    if (!str) {
      reject('Empty string')
      return
    }
    resolve(str.toUpperCase())
  })
}

module.exports = uppercase

//uppercase.test.js const uppercase = require(’./uppercase’)

test(uppercase 'test' to equal 'TEST', () => { return uppercase(’’).catch(e => { expect(e).toMatch(‘Empty string’) }) })

Jest async test catch

非同期/待機

promiseを返す関数をテストするには、async / awaitを使用することもできます。これにより、構文が非常に単純で単純になります。

//uppercase.test.js
const uppercase = require('./uppercase')
test(`uppercase 'test' to equal 'TEST'`, async () => {
  const str = await uppercase('test')
  expect(str).toBe('TEST')
})

Jest async test await async

モック

テストでは、嘲笑以下に依存する機能をテストできます。

  • データベース
  • 通信網リクエスト
  • へのアクセスファイル
  • どれか外部システム

そのため:

  1. テストが実行されますもっと早く、開発中の迅速なターンアラウンドタイムを提供します
  2. あなたのテストは独立ネットワークの状態、またはデータベースの状態
  3. あなたのテストはしません汚染データベースにアクセスしないため、データストレージ
  4. テストで行われた変更は、後続のテストの状態を変更しません。テストスイートの再実行は、既知の再現可能な開始点から開始する必要があります。
  5. API呼び出しとネットワークリクエストのレート制限について心配する必要はありません

モックは、副作用(データベースへの書き込みなど)を回避したい場合、またはコードの遅い部分(ネットワークアクセスなど)をスキップしたい場合に役立ちます。また、テストを複数回実行することによる影響を回避します(たとえば、電子メールまたはレート制限APIを呼び出します)。

さらに重要なのは、単体テスト、関数が触れるもののすべての手荷物ではなく、関数の機能を分離してテストする必要があります。

モックを使用すると、モジュール関数が呼び出されたかどうか、およびどのパラメーターが使用されたかを次のように検査できます。

  • expect().toHaveBeenCalled():スパイされた関数が呼び出されたかどうかを確認します
  • expect().toHaveBeenCalledTimes():スパイされた関数が呼び出された回数を数える
  • expect().toHaveBeenCalledWith():関数が特定のパラメータセットで呼び出されたかどうかを確認します
  • expect().toHaveBeenLastCalledWith():関数が最後に呼び出されたときのパラメータを確認してください

関数コードに影響を与えずにパッケージをスパイする

パッケージをインポートするとき、次を使用して、特定の関数の実行時にJestに「スパイ」するように指示できます。spyOn()、そのメソッドの動作に影響を与えることなく。

例:

const mathjs = require('mathjs')

test(The mathjs log function, () => { const spy = jest.spyOn(mathjs, ‘log’) const result = mathjs.log(10000, 10)

expect(mathjs.log).toHaveBeenCalled() expect(mathjs.log).toHaveBeenCalledWith(10000, 10) })

パッケージ全体をモックする

Jestは、パッケージ全体をモックする便利な方法を提供します。作成する__mocks__プロジェクトルートのフォルダ、およびこのフォルダに、パッケージごとに1つのJavaScriptファイルを作成します。

インポートするとしますmathjs。作成する__mocks__/mathjs.jsプロジェクトルートにファイルを作成し、次のコンテンツを追加します。

module.exports = {
  log: jest.fn(() => 'test')
}

これにより、パッケージのlog()関数がモックされます。モックしたい数の関数を追加します。

const mathjs = require('mathjs')

test(The mathjs log function, () => { const result = mathjs.log(10000, 10) expect(result).toBe(‘test’) expect(mathjs.log).toHaveBeenCalled() expect(mathjs.log).toHaveBeenCalledWith(10000, 10) })

単一の関数をモックする

を使用して単一の関数をモックできますjest.fn()

const mathjs = require('mathjs')

mathjs.log = jest.fn(() => ‘test’) test(The mathjs log function, () => { const result = mathjs.log(10000, 10) expect(result).toBe(‘test’) expect(mathjs.log).toHaveBeenCalled() expect(mathjs.log).toHaveBeenCalledWith(10000, 10) })

使用することもできますjest.fn().mockReturnValue('test')値を返す以外に何もしない単純なモックを作成します。

構築済みのモック

人気のあるライブラリ用の既製のモックを見つけることができます。たとえば、このパッケージhttps://github.com/jefflau/jest-fetch-mockあなたがモックすることができますfetch()を呼び出し、テストで実際のサーバーと対話せずにサンプルの戻り値を提供します。

スナップショットテスト

スナップショットテストは、Jestが提供する非常に優れた機能です。 UIコンポーネントがどのようにレンダリングされるかを記憶し、それを現在のテストと比較して、不一致がある場合はエラーを発生させることができます。

これは、シンプルなアプリコンポーネントの簡単なテストです。create-react-appアプリケーション(必ずインストールしてくださいreact-test-renderer):

import React from 'react'
import App from './App'
import renderer from 'react-test-renderer'

it(‘renders correctly’, () => { const tree = renderer.create(<App />).toJSON() expect(tree).toMatchSnapshot() })

このテストを初めて実行すると、Jestはスナップショットをに保存します。__snapshots__フォルダ。 App.test.js.snapに含まれるものは次のとおりです。

// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`renders correctly 1`] = `
<div
  className="App"
>
  <header
    className="App-header"
  >
    <img
      alt="logo"
      className="App-logo"
      src="logo.svg"
    />
    <h1
      className="App-title"
    >
      Welcome to React
    </h1>
  </header>
  <p
    className="App-intro"
  >
    To get started, edit
    <code>
      src/App.js
    </code>
     and save to reload.
  </p>
</div>
`

ご覧のとおり、これはAppコンポーネントがレンダリングするコードであり、それ以上のものではありません。

次回テストでの出力を比較するとき<App />これに。アプリが変更されると、エラーが発生します。

Error with snapshot

使用する場合yarn testcreate-react-appあなたはウォッチモード、そしてそこからあなたは押すことができますwその他のオプションを表示します。

Watch Usage
 › Press u to update failing snapshots.
 › Press p to filter by a filename regex pattern.
 › Press t to filter by a test name regex pattern.
 › Press q to quit watch mode.
 › Press Enter to trigger a test run.

If your change is intended, pressing u will update the failing snapshots, and make the test pass.

You can also update the snapshot by running jest -u (or jest --updateSnapshot) outside of watch mode.


More devtools tutorials: