/var/log/messages

May 23, 2018 - 9 minute read - Comments - Angular

Jasmine and Karma

以下なドキュメント機械翻訳控えを投入。

Jasmine and Karma

純粋なjavascript関数を記述して実行することで、Angularアプリケーションを最初からテストすることができます。 関連するクラスのインスタンスを作成し、関数を呼び出し、実際の結果と期待される結果を確認します。

しかし、テストはjavascriptのような共通のアクティビティなので、テストを書くのにかかる時間を短縮するために使用できる多数のテストライブラリとフレームワークがあります。

Angularのテストに使用されるツールとフレームワークの2つがJasmineとKarmaであり、それらの議論がこの講義のトピックです。

Learning Objectives

  • Jasmine test framework とは何ですか?
  • Jasmine でテストを書くには?
  • Karma test runner とは何ですか?
  • Angular CLIを使用してテストを作成して実行するにはどうすればよいですか?
  • Plunkerでテストを作成して実行するには?

    Jasmine

Jasmineは、Behavior Driven Development(BDD)と呼ばれるソフトウェア開発の実践をサポートするjavascriptのテストフレームワークです。 それはテスト駆動開発(TDD)の特定の風味です。

Jasmine、BDDは一般に、人間が読める形式でテストを記述しようとするため、技術者以外の人が何がテストされているのかを理解することができます。 しかし、BDD形式の技術的な読み上げテストであっても、何が起こっているのかを理解するのがずっと簡単です。

たとえば、この関数をテストする場合は次のようになります。

function helloWorld() {
  return 'Hello world!';
}

次のようなジャスミンテスト仕様を書いてみましょう:

describe('Hello world', () => {  // 1.
  it('says hello', () => {  // 2.
    expect(helloWorld())  // 3.
        .toEqual('Hello world!');  // 4.
  });
});
  1. describe(string、function)関数は、個々のテスト仕様の集合であるテストスイートと呼ばれるものを定義します。
  2. it(string、function)関数は個々のTest Specを定義します。これは1つ以上のTest Expectationsを含みます。
  3. expect(実際の)式は、Expectationと呼ばれるものです。 Matcherと組み合わせることで、アプリケーションで予想される動作が記述されます。
  4. matcher(expected)式はMatcherと呼ばれるものです。 これは、渡された期待値と期待値関数とに渡された実際の値との論理比較を行い、偽の場合にはその仕様が失敗します。

    Built-in matchers

ジャスミンには、いくつかの事前に作られたマッチャーが付属しています。

expect(array).toContain(member);
expect(fn).toThrow(string);
expect(fn).toThrowError(string);
expect(instance).toBe(instance);
expect(mixed).toBeDefined();
expect(mixed).toBeFalsy();
expect(mixed).toBeNull();
expect(mixed).toBeTruthy();
expect(mixed).toBeUndefined();
expect(mixed).toEqual(mixed);
expect(mixed).toMatch(pattern);
expect(number).toBeCloseTo(number, decimalPlaces);
expect(number).toBeGreaterThan(number);
expect(number).toBeLessThan(number);
expect(number).toBeNaN();
expect(spy).toHaveBeenCalled();
expect(spy).toHaveBeenCalledTimes(number);
expect(spy).toHaveBeenCalledWith(...arguments);

ここでジャスミンのドキュメントを見ると、これらのマッチャーがどのように使用されているかの具体的な例を見ることができます: http://jasmine.github.io/edge/introduction.html#section-Included_Matchers

Setup and teardown

場合によっては、設定を行う必要があるフィーチャをテストするために、テストオブジェクトを作成することがあります。 また、テストが終了した後で、いくつかのファイルを削除する必要があるかもしれません。

これらのアクティビティはセットアップとティアダウン(クリーンアップ)と呼ばれ、ジャスミンにはこれを簡単にするために使用できるいくつかの機能があります。

beforeAll この関数は、記述されたテストスイート内のすべての仕様が実行される前に、一度呼び出されます。

afterAll この関数は、テストスイート内のすべての仕様が完了した後に一度呼び出されます。

beforeEach この関数は、実行された各テスト仕様が機能する前に呼び出されます。

afterEach この関数は、各テスト仕様が実行された後に呼び出されます。

これらの関数は次のように使用できます。

describe('Hello world', () => {

  let expected = "";

  beforeEach(() => {
    expected = "Hello World";
  });

  afterEach(() => {
    expected = "";
  });

  it('says hello', () => {
    expect(helloWorld())
        .toEqual(expected);
  });
});

Running Jasmine tests

ジャスミンテストを手動で実行するには、HTMLファイルを作成し、必要なjasmine javascriptファイルとcssファイルを次のように組み込みます。

<link rel="stylesheet" href="jasmine.css">
<script src="jasmine.js"></script>
<script src="jasmine-html.js"></script>
<script src="boot.js"></script>

hello world関数がmain.jsにある場合など、テストしたいアプリケーションコードの部分をロードします。

<link rel="stylesheet" href="jasmine.css">
<script src="jasmine.js"></script>
<script src="jasmine-html.js"></script>
<script src="boot.js"></script>

<script src="main.js"></script>

重要 スクリプトタグの順序は重要です。

次に、個々のテストスイートファイルをロードします。たとえば、上記のテストスイートコードをtest.jsというファイルに配置した場合、次のようにロードします。

<link rel="stylesheet" href="jasmine.css">
<script src="jasmine.js"></script>
<script src="jasmine-html.js"></script>
<script src="boot.js"></script>

<script src="main.js"></script>

<script src="test.js"></script>

テストを実行するには、単にブラウザでHTMLファイルを開きます。

スクリプトとリンクを介して要求されたすべてのファイルがブラウザによってロードされると、関数window.onloadが呼び出されます。これはJasmineが実際にテストを実行するときです。

結果はブラウザウィンドウに表示され、失敗した実行は次のようになります。

jasmine fail

パスした場合は次のようになります。

jasmine pass

異なるブラウザでコードをテストする場合は、テストするブラウザにHTMLファイルをロードするだけです。

コードをデバッグしたい場合は、そのブラウザで利用可能な開発ツールを使用します。

Karma

コードを編集するたびにブラウザのタブでブラウザのタブを繰り返しリフレッシュして手動でJasmineテストを実行すると、面倒な作業になる可能性があります。

カルマは、ブラウザを起動し、コマンドラインからジャスミンテストを実行するためのツールです。 テストの結果は、コマンドラインにも表示されます。

Karmaは開発ファイルを見て変更を確認し、テストを自動的に再実行することもできます。

Karmaでは、開発ツールチェーンの一環としてジャスミンテストを実行することができます。開発ツールチェーンでは、テストを実行可能にし、結果をコマンドラインで調べる必要があります。

カルマの仕組みの内部を知る必要はありません。 Angular CLIを使用している場合は、この設定を処理します。このセクションの残りの部分では、Jasmineのみを使用してテストを実行します。

Angular CLI

Angular CLIを使用してAngularプロジェクトを作成する場合は、デフォルトでJasmineとKarmaを使用してユニットテストを作成して実行します。

CLIを使用してファイルを作成し、メインコードファイルを作成するたびに、メインコードファイルと同じ名前の単純なジャスミン仕様ファイルが作成されますが、末尾は.spec.tsです。

次のようにCLIを使ってPipeを作成した場合:

ng generate pipe My

これにより、2つのファイルが作成されます。

  • my-pipe.ts - これはメインコードファイルで、パイプのコードを記述します。
  • my-pipe.spec.ts - パイプ用のジャスミンテストスイートです。

スペックファイルには、既に次のようないくつかのコードがブートストラップされています:

/* tslint:disable:no-unused-variable */

import { TestBed, async } from '@angular/core/testing';
import { MyPipe } from './my.pipe';

describe('Pipe: My', () => {
  it('create an instance', () => {
    let pipe = new MyPipe();
    expect(pipe).toBeTruthy();
  });
});

注意 ブートストラップされるコードは、作成するアイテムによって異なります。

アプリケーションですべてのテストを実行するには、プロジェクトルートにng testと入力するだけです。

これはカルマを経てJasmineでプロジェクトのすべてのテストを実行します。

開発ファイルの変更を監視し、すべての開発者ファイルをまとめてバンドルし、テストを自動的に再実行します。

Angular Plunker

実際のAngularアプリケーションを作成するときは、Angular CLIで定義されたファイルとフォルダ構造だけでなく、組み込みテストランナーを使用することをお勧めします。

しかし、このセクションでは、コードを表示して再生する簡単な方法を提供するために、Jasmineのみを使用し、ブラウザをリフレッシュしてテストを実行します。

これで、このコースの他のすべてのセクションで行ったように、Plunker経由でコードを簡単に共有できます。

Angular Jasmine Plunkerは、いくつかの主要な違いから通常のJasmine Plunker appartと非常によく似ています。

  1. また、必要なAngularライブラリとJasmine用のパッチも含まれていますので、Angularでよりうまく動作します。
  2. 次に、テストするspecファイルをspec_filesという特別な配列に追加します。 var spec_files = [ ‘app/auth.service.spec’];
  3. 次に、変換されたファイルをブラウザに転送して読み込んだら、テスト仕様の実行をトリガーするshim javascriptファイルをロードします。

Disabled and focused test

あなたは私たちにコメントすることなくテストを無効にすることができます。単にxを記述や関数に先行するだけです:

xdescribe('Hello world', () => {  // 1.
  xit('says hello', () => {  // 1.
    expect(helloWorld())
        .toEqual('Hello world!');
  });
});
  1. これらのテストは実行されません。

逆に、fで事前に保留することで特定のテストに集中することもできます:

fdescribe('Hello world', () => {  // 1.
  fit('says hello', () => {  // 1.
    expect(helloWorld())
        .toEqual('Hello world!');
  });
});
  1. すべてのテストスイートとテスト仕様のすべてのテストのうち、これらは実行される唯一のものです。

    Summary

JasmineはBehavior Driven Developmentをサポートするテストフレームワークです。 テストスイートには、1つまたは複数のテスト仕様で構成されたテストが書き込まれます。これらのテスト仕様自体は、1つまたは複数のテストの期待から構成されています。

HTMLファイルを設定して読み込むことで、ブラウザでJasmineテストを実行できますが、より一般的にはKarmaというコマンドラインツールを使用します。 Karmaは、HTMLファイルの作成、ブラウザの起動、テストの実行、およびそれらのテストの結果のコマンドラインへの返信処理を処理します。

Angular CLIを使用してプロジェクトを管理すると、コード生成時に自動的にスタブジャスミン仕様ファイルが作成されます。 また、カラマの設定、ファイルの転送とバンドルを処理するので、テストを実行するために必要な作業は、コマンドng testと入力します。

このセクションでは、簡単なブラウザベースのJasmineテストランナーを使用していますので、コードを簡単に共有することができます。

Listing

http://plnkr.co/edit/8ApdkvletoEc4Q0maXSN?p=preview

Listing 1. index.html

<!-- Run application specs in a browser -->
<!DOCTYPE html>
<html>
<head>
  <title>Jasmine Running</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.css">
</head>
<body>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine-html.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script>
  <script src="main.js"></script>
  <script src="test.js"></script>
</body>

</html>

Listing 2. main.js

function helloWorld() {
  return 'Hello world!';
}

Listing 3. test.js

describe('Hello world', () => {

  let expected = "";

  beforeEach(() => {
    expected = "Hello world!";
  });

  afterEach(() => {
    expected = "";
  });

  it('says hello', () => {
    expect(helloWorld())
        .toEqual(expected);
  });
});

Overview Testing Classes & Pipes

comments powered by Disqus