自動ビルドプロセスにJavaScriptユニットテストを組み込んでいます。現在、JSUnitはJUnitで適切に動作しますが、それは放棄されているようで、AJAX、デバッグ、およびタイムアウトのサポートが不足しています。
YUIテスト、JQueryのQUnit、jQUnit( http://code.google.com/p/jqunit/ )などの単体テストライブラリを(ANTで)自動化する運があった人はいますか?
注:カスタムビルドAJAXライブラリを使用しているため、DojoのDOHの問題は、独自のAJAX関数呼び出しとイベントハンドラーを使用する必要があることです。 AJAX単体テストで動作します。
多くのJavaScriptユニットテストフレームワーク(jsUnit、scriptaculousなど)がありますが、自動ビルドで使用できるのはjsUnitだけです。
「真の」ユニットテストを実行している場合、AJAXサポートは必要ありません。たとえば、DWRなどのRPC ajaxフレームワークを使用している場合は、簡単にモック関数を作成できます。
function mockFunction(someArg、callback){ var result = ...; //いくつかの処理 setTimeout(
function(){callback(result); }、 300 //偽のレイテンシ
); }
そして、はい、JsUnitはタイムアウトを処理します: jsUnitテストでのシミュレーション時間
私は今取り組んでいる新しいプロジェクトでJavascript TDDを始めようとしています。私の現在の計画は、ユニットテストを行うために qunit を使用することです。開発中は、ブラウザでテストページを更新するだけでテストを実行できます。
継続的インテグレーション(およびすべてのブラウザーでテストが実行されるようにする)の場合、 Selenium を使用して、各ブラウザーでテストハーネスを自動的に読み込み、結果を読み取ります。これらのテストは、ソース管理へのチェックインごとに実行されます。
また、テストのコードカバレッジ分析を取得するために JSCoverage を使用します。これもSeleniumで自動化されます。
私は現在これをセットアップしている最中です。セットアップが完了したら、この回答をより正確な詳細で更新します。
テストツール:
js-test-driver の大ファンです
CI環境で適切に動作し、クロスブラウザーテストのために実際のブラウザーをキャプチャできます。
私は最近、JsUnitを使用してその上にJsMockフレームワークを作成するBrunoによる記事を読みました...非常に興味深いです。彼の作品を使ってJavascriptコードのユニットテストを開始しようと考えています。
私は Hudson CIを実行してJasmineBDDを実行する (ヘッドレス)、少なくとも純粋なjavascriptユニットテスト用です。
(Hudson実行Javaシェル経由、Envjs実行、JasmineBDD実行)
プロトタイプのように、大きなライブラリでニースをプレイすることはまだできていません。
調べてください YUITest
私はjsunitが一種のVineで死にかけていることに同意しています。 YUIテストに置き換えました。
QUnitを使用した例と同様に、Seleniumを使用してテストを実行しています。このテストは、通常のUI回帰テストのような依存関係がないために(他のSeleniumテストとは独立して)実行しています(たとえば、サーバーへのアプリのデプロイ)。
最初に、すべてのテストhtmlファイルに含まれている基本のJavaScriptファイルがあります。これは、YUIインスタンス、テストランナー、YUI.Test.Suiteオブジェクト、およびTest.Caseの設定を処理します。これには、Seleniumを介してアクセスしてテストスイートを実行し、テストランナーがまだ実行されているかどうかを確認し(実行が完了するまで結果は利用できません)、テスト結果を取得する(JSON形式を選択した)メソッドがあります。
var yui_instance; //the YUI instance
var runner; //The YAHOO.Test.Runner
var Assert; //an instance of YAHOO.Test.Assert to save coding
var testSuite; //The YAHOO.Test.Suite that will get run.
/**
* Sets the required value for the name property on the given template, creates
* and returns a new YUI Test.Case object.
*
* @param template the template object containing all of the tests
*/
function setupTestCase(template) {
template.name = "jsTestCase";
var test_case = new yui_instance.Test.Case(template);
return test_case;
}
/**
* Sets up the test suite with a single test case using the given
* template.
*
* @param template the template object containing all of the tests
*/
function setupTestSuite(template) {
var test_case = setupTestCase(template);
testSuite = new yui_instance.Test.Suite("Bond JS Test Suite");
testSuite.add(test_case);
}
/**
* Runs the YAHOO.Test.Suite
*/
function runTestSuite() {
runner = yui_instance.Test.Runner;
Assert = yui_instance.Assert;
runner.clear();
runner.add(testSuite);
runner.run();
}
/**
* Used to see if the YAHOO.Test.Runner is still running. The
* test results are not available until it is done running.
*/
function isRunning() {
return runner.isRunning();
}
/**
* Gets the results from the YAHOO.Test.Runner
*/
function getTestResults() {
return runner.getResults(yui_instance.Test.Format.JSON);
}
Seleniumに関しては、パラメーター化されたテストを使用しました。テストをIEとデータメソッドのFireFoxの両方で実行し、テスト結果をブラウザ配列、テストファイル名、テスト名を含むオブジェクト配列のリストに解析します。結果(合格、失敗、または無視)とメッセージ。
実際のテストは、テスト結果を表明するだけです。 「合格」と等しくない場合、テストは失敗し、YUIテスト結果から返されるメッセージが表示されます。
@Parameters
public static List<Object[]> data() throws Exception {
yui_test_codebase = "file:///c://myapppath/yui/tests";
List<Object[]> testResults = new ArrayList<Object[]>();
pageNames = new ArrayList<String>();
pageNames.add("yuiTest1.html");
pageNames.add("yuiTest2.html");
testResults.addAll(runJSTestsInBrowser(IE_NOPROXY));
testResults.addAll(runJSTestsInBrowser(FIREFOX));
return testResults;
}
/**
* Creates a Selenium instance for the given browser, and runs each
* YUI Test page.
*
* @param aBrowser
* @return
*/
private static List<Object[]> runJSTestsInBrowser(Browser aBrowser) {
String yui_test_codebase = "file:///c://myapppath/yui/tests/";
String browser_bot = "this.browserbot.getCurrentWindow()"
List<Object[]> testResults = new ArrayList<Object[]>();
Selenium = new DefaultSelenium(APPLICATION_SERVER, REMOTE_CONTROL_PORT, aBrowser.getCommand(), yui_test_codebase);
try {
Selenium.start();
/*
* Run the test here
*/
for (String page_name : pageNames) {
Selenium.open(yui_test_codebase + page_name);
//Wait for the YAHOO instance to be available
Selenium.waitForCondition(browser_bot + ".yui_instance != undefined", "10000");
Selenium.getEval("dom=runYUITestSuite(" + browser_bot + ")");
//Output from the tests is not available until
//the YAHOO.Test.Runner is done running the suite
Selenium.waitForCondition("!" + browser_bot + ".isRunning()", "10000");
String output = Selenium.getEval("dom=getYUITestResults(" + browser_bot + ")");
JSONObject results = JSONObject.fromObject(output);
JSONObject test_case = results.getJSONObject("jsTestCase");
JSONArray testCasePropertyNames = test_case.names();
Iterator itr = testCasePropertyNames.iterator();
/*
* From the output, build an array with the following:
* Test file
* Test name
* status (result)
* message
*/
while(itr.hasNext()) {
String name = (String)itr.next();
if(name.startsWith("test")) {
JSONObject testResult = test_case.getJSONObject(name);
String test_name = testResult.getString("name");
String test_result = testResult.getString("result");
String test_message = testResult.getString("message");
Object[] testResultObject = {aBrowser.getCommand(), page_name, test_name, test_result, test_message};
testResults.add(testResultObject);
}
}
}
} finally {
//if an exception is thrown, this will guarantee that the Selenium instance
//is shut down properly
Selenium.stop();
Selenium = null;
}
return testResults;
}
/**
* Inspects each test result and fails if the testResult was not "pass"
*/
@Test
public void inspectTestResults() {
if(!this.testResult.equalsIgnoreCase("pass")) {
fail(String.format(MESSAGE_FORMAT, this.browser, this.pageName, this.testName, this.message));
}
}
これがお役に立てば幸いです。
私はあなたの質問日を見て、当時はいくつかの良いJSテストlib/frameworkがありました。今日では、TDD、BDD、Assetion、ランナーサポートの有無にかかわらず、さらに多くの異なる焦点を見つけることができます。
このゲームには、Mocha、Chai、QUnit、Jasmineなどの多くのプレイヤーがいます... JS /モバイル/ Webテストに関する詳細情報は this ブログにあります...
Java環境(antのような)環境で qunit テストを実行できる新しいプロジェクトがあるため、クライアント側のテストスイートを他のユニットテストと完全に統合できます。
http://qunit-test-runner.googlecode.com
私はそれをjQueryプラグインのユニットテストに使用しました objx コード、カスタムOO JavaScript、そしてそれは変更なしですべてに対して機能します。
ブラウザーを使用せずにブラウザー依存のJavaScriptテストを検証するための little library を公開しました。これは、zombie.jsを使用してテストページをロードし、結果を検査するnode.jsモジュールです。私はそれについて書きました 私のブログで 。自動化は次のようになります。
var browsertest = require('../browsertest.js').browsertest;
describe('browser tests', function () {
it('should properly report the result of a mocha test page', function (done) {
browsertest({
url: "file:///home/liam/work/browser-js-testing/tests.html",
callback: function() {
done();
}
});
});
});
私が取り組んでいるプロジェクトでは、 Js-Test-Driver hosting Jasmine on Chrome 10 with Jasmine-JSTD-Adapter JS-Test-Driverに含まれる Code Coverage テストの利用を含む。毎回いくつかの問題がありますが、 CI環境でブラウザを変更または更新する ジャスミンテストは非同期テストの軽微な問題でかなりスムーズに実行されていますが、私が知っている限り、これらはジャスミンクロックを使用して回避できます。まだパッチを当てる機会がありませんでした。
Antで実行できる別のJSテストフレームワークは CrossCheck です。プロジェクトのビルドファイルにAntを介してCrossCheckを実行する例があります。
CrossCheckは、限られた成功を収めて、XMLHttpRequestおよびタイムアウト/間隔のモックスタイル実装を含むブラウザをエミュレートしようとします。
ただし、現在、WebページからのJavaScriptのロードは処理していません。ロードしてテストするJavaScriptファイルを指定する必要があります。すべてのJSをHTMLから切り離しておくと、うまくいく場合があります。
私は、Antビルドプロセス内でQUnit htmlテストファイルを実行するために、ヘッドレスWebkitブラウザである Phantom JS を使用するAntタスクを作成しました。また、いずれかのテストが失敗すると、ビルドも失敗する可能性があります。