javascriptのテストのはなし:SugerTest
今回はマイナーであろうSugerTestを紹介します。
ユニットテスト用のライブラリで、JsUnitTestをベースとした拡張版?という感じですね。
実際に利用するにはSugarTestのライブラリと合わせてJsUnitTestのライブラリをロードする必要があります。テスト実行結果の画面はJsUnitTestの画面そのものです。
準備
ここからSugerTestのライブラリを落とします。
先に書いた通り、JsUnitTestとSugarTestのライブラリ両方を使う必要がありますが、ダウンロードしたSugerTestのライブラリの中にJsUnitTestも含まれているので、特に気にする必要はないです。
ダウンロードしたzipを解凍するとassetというディレクトリがあって、その中にJsUnitTestとSugerTestのjsが入っているのでそれをhtmlで指定します。
また、htmlのbodyの中に
<div id="testlog"></div>
を用意しておきます。JsUnitTestがこのタグに対してテスト結果を出力します。
アサーション
ドキュメントによると、使えるアサーションはJsUnitTestのアサーションで次のものが挙げられています。
assert、assertEqual、assertNotEqual、assertEnumEqual、assertEnumNotEqual、assertHashEqual、assertHashNotEqual、assertIdentical、assertNotIdentical、assertNull、assertNotNull、assertUndefined、assertNotUndefined
ちなみに、JsUnitTestには上記以外にも
assertNullOrUndefined、assertNotNullOrUndefined、assertMatch、assertNoMatch、assertHasClass、assertHidden、assertInstanceOf、assertNotInstanceOf、assertRespondsTo、assertRaise、assertNothingRaised、assertVisible、assertNotVisible、assertElementsMatch、assertElementMatches
があります。
使い方
基本
SugarTest().run();
でテストを実行します。
コンテキストを作る
describe()でコンテキストを作り、it()でテストケースを複数定義、end()でコンテキストを終えます。describe()は複数作れるし、ネストする事もできます。
SugarTest() .describe("context 1") .it("testcase 1-1", function(){...}) .it("testcase 1-2", function(){...}) .describe("context 1-2") .it("testcase 1-2-1", function(){...}) .it("testcase 1-2-2", function(){...}) .end() .end() .describe("context 2") .it("testcase 2-1", function(){...}) .it("testcase 2-2", function(){...}) .end() .run();
全てのメソッドがsugarTestのオブジェクトを返すので、コンテキスト分、ユニット分、チェーンする事ができます。
チェーンさせて記述するのがSugarTestの特徴ですね。
setUpとtearDwon
SugarTestの場合は、setUp、tearDownという名称ではなく、before()、after()で定義します。これらのメソッドもsugarTestのオブジェクトを返すのでチェーンさせて記述します。
SugarTest() .before(function(data){...}) .after(function(data){...}) .describe("context 1") .it("testcase 1-1", function(){...}) .it("testcase 1-2", function(){...}) .end() .run();
また、before()、after()はコンテキストの中でも行う事が出来ます。
before()の場合はネストの外側から内側に、after()の場合はネストの内側から外側に向けて実行されます。
SugarTest() .before(function(data){...}) .after(function(data){...}) .describe("context 1") .before(function(data){...}) .after(function(data){...}) .it("testcase 1-1", function(){...}) .it("testcase 1-2", function(){...}) .end() .run();
ルートコンテキスト
ルートコンテキストの直下にもユニットを作れます。
SugarTest() .before(function(data){...}) .after(function(data){...}) .it("root testcase", function(){...}) .describe("context 1") .before(function(data){...}) .it("testcase 1-1", function(){...}) .it("testcase 1-2", function(){...}) .end() .run();
root()を使うとルートコンテキストに戻れます。
SugarTest() .before(function(data){...}) .after(function(data){...}) .it("root testcase1", function(){...}) .describe("context 1-1") .before(function(data){...}) .it("testcase 1-1", function(){...}) .it("testcase 1-2", function(){...}) .root() .it("root testcase2", function(){...}) .end() .run();
補足
describe()/it()の代わりに、context()/should()を使う事も出来ます。テスト実行時の表示が変わるだけで基本的に同じです。
実行してみる
ライブラリに入っているサンプルのテストファイルsugar_test_sample.htmlがやれる事を網羅していて良い感じなのでこれを動かしてみます。実行結果は次の様な感じになります。
コンテキストをネストさせてテストが構造化できるわけですが、結果表示はフラットなのでいまいち分かりにくいですね。。テスト実行~結果表示まではJsUnitTestの機能なので仕方ないんでしょうけど。
ちなみにsugar_test_sample.htmlのソースはこんな感じになってます。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html lang="en"> <head> <title>SugerTest</title> <script src="http://code.jquery.com/jquery-latest.js"></script> <link rel="stylesheet" href="assets/unittest.css" type="text/css" /> <script src="assets/jsunittest.js" type="text/javascript"></script> <script src="assets/sugar_test.js" type="text/javascript"></script> <!-- Source and test files go here --> </head> <body> <div id="content"> <div id="header"> <h1>SugarTest sample test file</h1> <p>This file shows example usage of <a href="http://sugartest.scriptia.net/">SugarTest</a>.</p> </div> <div id="testlog"></div> </div> <script type="text/javascript"> // <![CDATA[ SugarTest("AAAA") .it("root", function(data){ this.assert(true); }) .before(function(data){ this.wadus = "wadus"; }) .after(function(){ this.wadus = ""; }) .describe('First context') .it('runs examples', function(data) { this.assert(false); }) .it('runs examples2', function(data) { this.assert(true); }) .end() .describe('Second context') .before(function(data){ this.wadus = this.wadus.toUpperCase(); }) .it('runs examples', function(data) { this.assertEqual(this.wadus, "WADUS"); }) .end() .describe('Third context') .should('runs examples', function(data) { this.assertEqual(this.wadus, data.wadus); }) .end() .run(); // ]]> </script> </body> </html>