DB Fixturesを使用してUnit Testに基礎データを提供し、Sails+Mochaで実現します.

5673 ワード

DB Fixturesを使用してUnit Testに基礎データを提供し、Sails+Mochaで実現します.
質問:Test Fixtureは分散しすぎて管理が面倒です.
ユニットテストをするとき、データのロールバックは面倒な問題です.
比較的簡単な解決策は、ユニットテスト時に個別のDBを接続し、テストが完了したらDB内容をクリアすればよい.しかし、これはもう一つの問題をもたらしています.DBは最初は空でした.caseをテストするとき、私たちはこのcaseの基礎データを提供し、初期化操作をする必要があります.このような操作はTest Fixtureと呼ばれています.この概念は何ですか.この文章は少し説明があるhttp://magustest.com/blog/whiteboxtesting/three-different-test-fixture-setup-approach/.「被測定ソフトを実行するために必要なすべてのもの」です.
MochaでTest Fixtureを提供するのはbeforeメソッドです.公式サイトを参照してください.http://mochajs.org/
describe('hooks', function() {

  before(function(cb) {
    // runs before all tests in this block
    User.create(user,function(err,data){
      user_id = data.id;
      cb(err);
    });
  });

  after(function() {
    // runs after all tests in this block
  });

  // test cases
});

beforeでオブジェクトをcreateし、データの準備を完了し、test casesでこのオブジェクトを使用できます.これは比較的簡単なTest Fixture実装ですが、Test Caseが多い場合、いくつかの問題をもたらします.
  • データは重複しており、各case間でデータを共有することができず、case AでUserオブジェクトを初期化し、case Bでもう一度初期化する.
  • データメンテナンス管理が混乱し、これらのデータは各caseに分散し、集中管理ができない.また,Userのようなオブジェクト構造が変更され,各caseでUserを初期化するコードを更新する必要がある.beforeは、このcaseでUserオブジェクトをcreateしたり、別のcaseでUserオブジェクトをcreateしたりするなど、繰り返し作業をしていることがよくわかります.

  • 解決方案:集中管理Test Fixture
    Sailsは、上記の問題を解決するためのツールパッケージ実装を提供しており、Barrels https://www.npmjs.com/package/barrels Simple DB Fixtures for Sails.js with associations support.Githubでこのツールが提供されているDemo https://github.com/bredikhin/barrels/blob/master/test/index.test.jsあ、参考になります。
    Barrelsは、すべての基礎データをjsonファイルとして定義し、Unit Test環境の初期化時にBarrels loadを使用してこれらのjsonをテストDBに永続化することをサポートします.Sailsでは、これらのファイルはデフォルトでtest/fixturesディレクトリに保存されます.
    test
    	--fixtures
    		--user.json
    		--order.json
    		--bootstrap.test.js 

    user.jsonを例にとると、長いという配列です.
    [
      {
        "name": "Walter White",
        "email": "[email protected]"
      },
      {
        "name": "John Appleseed",
        "email": "[email protected]"
      }
    ]

    Sailsでは、testディレクトリbootstrap.test.jsファイルは、Unit Test初期化環境を定義するSails用のファイルです.このファイルに次のコードを追加してTest Fixturesの初期化を完了します.
    before(function (done) {
      Sails.lift({
        log: {
          level: 'error'
        },
        models: {
          connection: 'testMongodb',
          migrate: 'drop'
        }
      }, function(err, sails) {
        if (err)
          return done(err);
        // Load fixtures
        var barrels = new Barrels();
    
        //           
        TestContext.loadData(barrels);
    
        // Populate the DB
        barrels.populate(function(err) {
          done(err, sails);
        });
      });
    });

    new Barrels()にすべてのjsonファイルがロードされ、barrels.populateメソッドを使用してjsonがDBに永続化されます.OK、これでtest/fixturesディレクトリでテストデータを統一的に管理できます.
    では、本当の問題は、test caseでこれらのjsonオブジェクトをどのように取得するかです.
    Test CaseでTest Fixturesを取得する
    Barrelsは、すべてのjsonファイルを独自のdataプロパティに格納し、userリストを取得するには、次のようにします.
    var barrels = new Barrels();
    var userList = barrels.data.user

    では、どのようにして具体的なuserを取得しますか?user_を介してidはデータベースでクエリーできますか?このように:
    before(function (done) {
        User.findOne({id: user_id}, function (err, user) {
            cb(err, user)
        });
    });

    毎回調べるのは面倒ではありませんか?どうやって知った?idはどのuserに対応しますか?前に約束したデータ共有はどこへ行きましたか?
    テストコンテキストTestContextを使用してデータを共有します.
    上記の問題は2つあります.
  • 特定のuser
  • をどのように指定するか
  • データの共有方法
  • 最初の問題を解決するには、user.jsonファイルで各userオブジェクトにkeyを指定します.
    [
      {
        "key": "base",
        "name": "Walter White",
        "email": "[email protected]"
      },
      {
        "key": "john",
        "name": "John Appleseed",
        "email": "[email protected]"
      }
    ]

    2つ目の問題を解決し、自分でTestContextオブジェクトを定義し、bootstrap.test.jsに次のコードを追加してTestContextを初期化します.
    //           
    TestContext.loadData(barrels);

    TestContext.loadDataの実現:
    var _ = require('underscore');
    module.exports = {
    
      loadData: function (barrels) {
        self.barrels = barrels;
        var fixtures = barrels.data;
        self.fixtures = fixtures;
    
        //     model
        _.each(Object.keys(fixtures), function (key) {
          //       
          _.each(fixtures[key], function (object) {
            if (!self[key]) {
              self[key] = {};
            }
            if (object.key) {
              // barrels.model.key = object
              self[key][object.key] = object;
            }
          });
        });
      }
    };
    var self = module.exports;

    これらの初期化操作を行うと、Test CaseでUserオブジェクトを取得できます.
    var TestContext = require('../lib/TestContext');
    describe("Unit TEST !", function () {
      var user = TestContext.user.base;
    
      before(function (done) {
        done();
      });
    
      describe(" do test ", function () {
    
        it(" do test ", function (done) {
          //     
          done(err);
        });
    
      });
    }

    非常に便利で、TestContextオブジェクトを導入するとuserオブジェクトを取得できます.baseはuser.jsonのあるuser定義のkeyです.これで上記の2つの問題は完璧に解決された.
    何かできること
    Barrelsの機能はload jsonでデータを永続化し,ユニットテスト環境の初期化に加えて開発または正式環境の初期化にも利用できる.プロジェクトの導入には、基本的なデフォルトデータを導入する必要があります.Barrelsでこの作業を完了することができます.
    フォルダにjsonファイルを定義し、プロジェクトの初期化時に次のコードを追加します.
    // Load fixtures
    var barrels = new Barrels('josn     ');
    // Populate the DB
    barrels.populate(function(err) {
      done(err);
    });

    これで初期化が完了します.注意しなければならない問題は、Barrelsがデータを保存する前にテーブルを空にし、データの損失に注意することです.あるいはBarrelsのコードを修正して、テーブルの論理をクリアすることで、安全になります.