ジェネレーターのテスト

下にスクロールして、ジェネレーターの単体テストの負担を軽減する Yeoman の追加のテストヘルパーについて詳しく確認してください。

次の例では、BDD モードで Mocha を使用しているものと想定しています。この全体的なコンセプトは、選択する単体テストフレームワークに簡単に適用できます。

テストの編成

テストを単純かつ簡単に編集できるようにすることが重要です。

通常、テストを編成するための最適な方法は、各ジェネレーターとサブジェネレーターをそれぞれの describe ブロックに分割することです。次に、各ジェネレーターが受け入れる各オプションについて describe ブロックを追加します。そして、it ブロックを各アサーション(または関連アサーション)に使用します。

コードでは、以下のような構造になります

describe('backbone:app', function () {
  it('generates a project with require.js', function () {
      // assert the file exist
      // assert the file uses AMD definition
  });

  it('generates a project with webpack');
});

テストヘルパー

Yeoman はテストヘルパーメソッドを提供します。これらは yeoman-test パッケージに含まれています。

var helpers = require('yeoman-test');

こちらのヘルパー API を全て確認できます

ジェネレーターの単体テストで最も使用できるメソッドは helpers.run() です。このメソッドは、ディレクトリのセットアップ、モックプロンプト、モック引数などのメソッドを呼び出すことができる RunContext インスタンスを返します。

var path = require('path');

it('generate a project', function () {
  // The object returned acts like a promise, so return it to wait until the process is done
  return helpers.run(path.join(__dirname, '../app'))
    .withOptions({ foo: 'bar' })      // Mock options passed in
    .withArguments(['name-x'])        // Mock the arguments
    .withPrompts({ coffee: false })   // Mock the prompt answers
    .withLocalConfig({ lang: 'en' }) // Mock the local config
    .then(function() {
      // assert something about the generator
    });
})

ターゲットディレクトリに既存の内容があるジェネレーターのテストシナリオを作成したい場合があります。その場合は、次のようにコールバック関数を指定して inTmpDir() を呼び出します

var path = require('path');
var fs = require('fs-extra');

helpers.run(path.join(__dirname, '../app'))
  .inTmpDir(function (dir) {
    // `dir` is the path to the new temporary directory
    fs.copySync(path.join(__dirname, '../templates/common'), dir)
  })
  .withPrompts({ coffee: false })
  .then(function () {
    assert.file('common/file.txt');
  });

コールバックで非同期タスクを実行することもできます

var path = require('path');
var fs = require('fs-extra');

helpers.run(path.join(__dirname, '../app'))
  .inTmpDir(function (dir) {
    var done = this.async(); // `this` is the RunContext object.
    fs.copy(path.join(__dirname, '../templates/common'), dir, done);
  })
  .withPrompts({ coffee: false });

実行の Promise は、ジェネレーターが実行されたディレクトリを解決します。ジェネレーターが実行された一時ディレクトリを使用する場合に役立ちます

helpers.run(path.join(__dirname, '../app'))
  .inTmpDir(function (dir) {
    var done = this.async(); // `this` is the RunContext object.
    fs.copy(path.join(__dirname, '../templates/common'), dir, done);
  })
  .withPrompts({ coffee: false })
  .then(function (dir) {
    // assert something about the stuff in `dir`
  });

ジェネレーターが composeWith() を呼び出す場合は、それらの依存ジェネレーターをモックしたい場合があります。 #withGenerators() を使用して、#createDummyGenerator() を最初の項目として、モックジェネレーターのネームスペースを 2 番目の項目として使用する配列の配列を渡します

var deps = [
  [helpers.createDummyGenerator(), 'karma:app']
];
return helpers.run(path.join(__dirname, '../app')).withGenerators(deps);

Promis が嫌いな場合は、発信される 'ready''error'、および 'end' イベントを使用できます

helpers.run(path.join(__dirname, '../app'))
  .on('error', function (error) {
    console.log('Oh Noes!', error);
  })
  .on('ready', function (generator) {
    // This is called right before `generator.run()` is called
  })
  .on('end', done);

モジュールとしてインポートしてジェネレーターを実行することもできます。ジェネレーターのソースコードが変換された場合に役立ちます。

run に次の設定を提供する必要があります

  • resolved: ジェネレーターへのパス(例:../src/app/index.js
  • namespace: ジェネレーターのネームスペース(例:mygenerator:app
var MyGenerator = require('../src/app');

helpers.run(MyGenerator, { 
  resolved: require.resolve(__dirname, '../src/app/index.js'),
  namespace: 'mygenerator:app'
});

アサーションヘルパー

Yeoman は、ジェネレーター関連のアサーションヘルパーで ネイティブ assert モジュール を拡張します。アサーションヘルパーの全リストは yeoman-assert リポジトリ にあります。

アサーションヘルパーの必要条件

var assert = require('yeoman-assert');

ファイルの存在をアサート

assert.file(['Gruntfile.js', 'app/router.js', 'app/views/main.js']);

assert.noFile() は反対をアサートします。

ファイルの内容をアサート

assert.fileContent('controllers/user.js', /App\.UserController = Ember\.ObjectController\.extend/);

assert.noFileContent() は反対をアサートします。