2013-03-03 18 views
8

私はビジネスロジックのさまざまな部分を含む私のアプリケーションのためのいくつかの流星の方法を書いた。これらのメソッドの単体テストを作成したいと思います。ユニットテストでは、私は特にない高速なテストを意味:私の流星の方法を単体テストする方法は?

  • は、データベースにXHRsまたは
  • 書き込みを実行し

どのように私はこれをやって行くことができますか?私が現在考えているのは、テスト構成でMeteorサーバーを起動するときに、自分のコレクションをダミーコレクション(new Meteor.Collection(null)を渡して)に置き換え、私の単体テストをサーバー側で実行し、私のMeteor.callそこから順番に方法。どのようにテストを開始するのかは完全にはわかりませんが、おそらく私は自分のアプリケーションにカスタム/tests URLを作成したいと思っています。このアプローチは合理的だと思われますか?私のメソッドの単体テストテストを容易にするライブラリ/パッケージがありますか?

答えて

1

ここで私のユニットテストの方法について考えました。私はこれに改善の余地がたくさんあることを認めて最初になるでしょう!

まず、私は次のコードを持っている私のserver.coffeeファイルに:私は実行時にMeteor.settings [「テスト」]は私が行うことができ、定義されている場合

Meteor.startup -> 
    return unless Meteor.settings["test"] 
    require = __meteor_bootstrap__.require 
    require("coffee-script") 
    fs = require("fs") 
    path = require("path") 
    Mocha = require("mocha") 

    mocha = new Mocha() 
    files = fs.readdirSync("tests") 
    basePath = fs.realpathSync("tests") 
    for file in files 
    continue unless file.match(/\.coffee$/) or file.match(/\.js$/) 
    continue if file[0] == "." 
    filePath = path.join(basePath, file) 
    continue unless fs.statSync(filePath).isFile() 
    mocha.addFile(filePath) 
    mocha.run() 

すべてこのコードの最初にのみ実行されます私のテストは現地で行われていますが、実際には生産には当てはまりません。次に、 "tests"ディレクトリでjavascriptまたはcoffeescriptファイルを探します(私の実装ではサブディレクトリは検索されませんが、追加するのは簡単でしょう)。mochaインスタンスに追加します。ここでは、アサーションライブラリと組み合わせて、優れたmochaのjavascriptテストライブラリを使用しています。

このコードはすべてMeteor.startupコールの中にラップされているため、単体テストはサーバーの起動時に実行されます。 Meteorはコードを変更するたびに自動的にテストを再実行するので、これは特に便利です。データベースを分離してXHRを実行しないという決定のため、私のテストは数ミリ秒で実行されるため、これはあまり迷惑ではありません。テスト自分自身のために

、私はアサーションライブラリに引っ張るために

chai = require("chai") 
should = chai.should() 

を行う必要があります。しかし、解決すべきいくつかの難しい問題がまだあります。まず、Meteorのメソッド呼び出しは、ファイバーでラップされていないと失敗します。私は現在、この問題に非常に良い解決策を持っていないが、私はモカのit機能を置き換えるためにitShould機能を作成し、ファイバ内の試験体を包む:テストのために、

# A version of mocha's "it" function which wraps the test body in a Fiber. 
itShould = (desc, fn) -> 
    it(("should " + desc), (done) -> (Fiber -> 
    fn() 
    done()).run()) 

次のアップが問題です私のコレクションをモックコレクションに置き換えています。コレクションをグローバル変数に入れるという標準的な流行のプラクティスに従えば、これは非常に困難です。ただし、グローバルオブジェクト上にコレクションを作成すると、それを行うことができます。 myApp.Collection = new Meteor.Collection("name")でコレクションを作るだけです。次に、あなたのテストで、あなたがコレクションからbefore機能のモックを持つことができます。

realCollection = null 
before -> 
    realCollection = myApp.Collection 
    myApp.Collection = new Meteor.Collection(null) 
after -> 
    myApp.Collection = realCollection 

この方法は、あなたのコレクションは、テスト実行の継続のために嘲笑されていますが、あなたと対話することができますので、それを復元していますアプリは正常です同様の方法で模擬することも可能です。たとえば、グローバルMeteor.userId()関数は、クライアントが開始した要求に対してのみ機能します。私は実際に彼らがこの問題へのよりよい解決策を提供できるかどうかを確認するために流星に対してa bugを提出してきましたが、今の私はテストのために私自身のバージョンとの機能を交換しています:このアプローチは、いくつかのために働く

realUserIdFn = null 
before -> 
    realUserIdFn = Meteor.userId 
    Meteor.userId = -> "123456" 
after -> 
    Meteor.userId = realUserIdFn 

メテオの一部ですが、すべてではありません。たとえば、私はthis.setUserIdを呼び出すメソッドをテストする方法を見つけていません。なぜなら、その動作を模倣する良い方法はないと思うからです。しかし、全体的には、このアプローチは私のために働いています...私はコードを変更すると自動的にテストを再実行できることが大好きで、単体でテストを実行するのが一般的には良い考えです。また、サーバー上のテストをブロックすることができ、コールバックチェーンを使用しないで簡単にテストを行うことができます。テストは次のようになります:

describe "the newWidget method", -> 
    itShould "make a new widget in the Widgets collection", -> 
    widgetId = Meteor.call("newWidget", {awesome: true}) 
    widget = myApp.Widgets.findOne(widgetId) 
    widget.awesome.should.be.true 
0

私が取り組んでいるより大きなメテオのアプリケーションをテストするのにjasmineを使っています。単体テストよりもはるかに多くを行うことができ、かなりうまく機能しています。これについてのブログ記事は私のtodo lisです。今のところ私はあなたにこのCoffeeScriptを与えることができます:

if were_testing() 
    describe 'something', -> 
    it 'should be greater than 0', -> 
     expect(theThing).toBeGreaterThan 0 

were_testing = -> document.location.pathname.replace(/^\/([^\/]*).*$/, '$1') == 'tests' 

jasmine_test = -> 
    jasmineEnv = jasmine.getEnv() 
    jasmineEnv.updateInterval = 1000 

    htmlReporter = new jasmine.HtmlReporter() 
    jasmineEnv.addReporter htmlReporter 

    jasmineEnv.execute() 

このコードはブラウザで実行されます。スクリプトを作成したい場合は、casperjsインスタンスで実行することができます。クライアント上でMeteorの初期化を行うので、XHRとデータベースのクエリを実行しますが、余分なクエリを実行しないテストを簡単に記述できます。または訪問/ unittestsときに起動される機能のサブセットを書く

私たちのものはまだ生産されていませんが、deployscriptは単に上記のジャスミンコードとすべての*.spec.coffeeファイルを削除します。

これをJenkinsに接続して適切な継続的な統合設定にしたいが、Jenkinsを基本よりもセットアップする時間がない。私はヘッドレスブラウジングのためにcasperjを使って遊んでいましたが、これはかなりうまくいきました。

また、tests/(Meteorでは実行されていません)にテストコードを入れてrequireを使用して別のアプローチをとることもできます。私はすぐにこれを試して、それは非常に退屈だとわかりました。

+0

私はこれを理解していないかもしれませんが、このコードはブラウザで動作するようですね。その場合、メソッドを単独でテストするのはかなり難しいと思います。何か特別なことが起こっていない限り、あなたのメソッド呼び出しはXHRやデータベースの書き込みや作業をするでしょうか? –

関連する問題