【IT168專稿】當前,在軟體開發中單元測試越來越受到開發者的重視,它能提高軟體的開發效率,而且能保障開發的質量。以往,單元測試往往多見於服務端的開發中,但隨著Web編程領域的分工逐漸明細,在前端Javascript開發領域中,也可以進行相關的單元測試,以保障前端開發的質量。在本文中,將初步探討如何在Javascript中進行單元測試及其注意要點。
Javascript中的單元測試工具
在Javascript的單元測試中工具中,有很多開源的工具,本文選取其中兩個比較典型實用的工具進行介紹:jsTestDriver和Qunit。先來看下jsTestDriver(下載地址:http://code.google.com/p/js-test-driver/wiki/GettingStarted)。
jsTestDriver以客戶服務端的方式運行,在客戶端發送測試請求到服務端,整個運行是在可以捕捉的瀏覽器中進行的,其優點為它能很容易地與代碼編輯器整合,以及能成為自動構建的一部分。jsTestDriver包括一系列能與Eclipse,Maven和IntelliJ整合的插件,甚至與Visual Studio整合也是可行的(參考這篇文章),比如下圖是與EditPlus整合的一個示意圖:
jsTestDriver的安裝
安裝jsTestDriver的步驟如下:
1. 從jsTestDriver的下載頁中下載相關的JAR文件,下載地址為:http://code.google.com/p/js-test-driver/downloads/list,下載其中的JsTestDriver-1.3.3a.jar 這個文件
2. 創建兩個文件夾,其中一個為名稱為src的存放Javascript原始碼的文件,另外一個是用來存放測試用例的文件,文件夾命名為src-test。
3. 創建一個配置文件,配置文件名為jsTestDriver.conf,配置文件如下:
server: http://localhost:9876
load:
- src/*.js
- src-test/*.js
這裡指出了啟動位於9876的埠進行監聽,並且先加載src文件夾下的所有js文件夾,然後在加載src-test文件夾下的js文件進行測試。
4. 接下來,我們配置jsTestDriver的服務端,以讓其監控chrome瀏覽器,讓其運行Javascript測試用例。在命令行輸入如下代碼,具體路徑請根據實際情況修改。
"C:\Program Files (x86)\Java\jre6\bin\java" -jar JsTestDriver-1.3.2.jar --port 4224 --browser "C:\Documents and Settings\Tarwn\Local Settings\Application Data\Google\Chrome\Application\chrome.exe"
這樣的話,會在4224埠啟動jsTestDriver,並且會啟動一個chrmoe瀏覽器的實例,這個實例會捕捉所有的在Chrmoe中運行的Javascript單元測試。接下來,編寫一個.cmd文件,在命令方式下執行,以執行測試,測試所有放在src-test中的測試用例,代碼如下:
"C:\Program Files (x86)\Java\jre6\bin\java" -jar JsTestDriver-1.3.2.jar --tests all
Pause
開始編寫Javascript
我們開始編寫一個簡單的Javascript來進行測試,先在src和src-test目錄下,分別編
寫如下代碼:
Src目錄下的mystuff.js
myAwesomeApp = {};
myAwesomeApp.MyAwesomeClass = function(){};
myAwesomeApp.MyAwesomeClass.prototype.add = function(num0, num1){
return num0 + num1;
};
Src-test 目錄下的mystuff.js
TestCase("Sample Test Case",{
"test Number plus Zero Equals Number": function(){
var adder = new myAwesomeApp.MyAwesomeClass();
assertEquals(5, adder.add(5,0));
},
"test Number plus Number Equals Sum": function(){
var adder = new myAwesomeApp.MyAwesomeClass();
assertEquals(8, adder.add(5,3));
},
"test Zero plus Number Equals Number": function(){
var adder = new myAwesomeApp.MyAwesomeClass();
assertEquals(5, adder.add(0,5));
},
"test Number plus Negative of Number Equals Zero": function(){
var adder = new myAwesomeApp.MyAwesomeClass();
assertEquals(0, adder.add(5,-5));
},
"test Fails miserably": function(){
fail("miserably");
}
});
熟悉單元測試的開發者對它們應該不感到陌生。在上面的測試代碼組中,分別測試
了多種用例,用到的都是assertEquals斷言。更多的用法請參考其官方主頁的介紹。
接下來,我們開始運行測試用例,方法為在命令行模式下,
"C:\Program Files (x86)\Java\jre6\bin\java" -jar ../JsTestDriver-1.3.2.jar --port 4224 --browser "C:\Documents and Settings\Tarwn\Local Settings\Application Data\Google\Chrome\Application\chrome.exe"
這樣就可以啟動chrome瀏覽器監聽相關的Javascript單元測試用例。運行後可以看到打開了瀏覽器,如下圖:
▲
接下來開始進行單元測試,命令行輸入如下代碼:
"C:\Program Files (x86)\Java\jre6\bin\java" -jar ../JsTestDriver-1.3.2.jar --tests all
運行後,會在瀏覽器中看到相關的輸出結果,如下:
....F
Total 5 tests (Passed: 4; Fails: 1; Errors: 0) (0.00 ms)
Chrome 13.0.782.220 Windows: Run 5 tests (Passed: 4; Fails: 1; Errors 0) (0.00 ms)
Object Literal Test Case.test Fails miserably failed (0.00 ms): AssertError: miserably
AssertError: miserably
at Object.test Fails miserably (http://localhost:4224/test/src-test/mystuff.js:22:3)
Tests failed: Tests failed. See log for details.
從結果中可以看到,.S表示成功通過的單元測試,.F為失敗的單元測試用例,而.E為錯誤的測試用例,信息中還指出了有多少個單元測試,通過了多少,多少個沒有通過。
jsTestDriver還支持傳統的setup和teardown等單元測試方法。更多的相關介紹可以參考其在線幫助手冊。
開源的單元測試工具Qunit
接下來,介紹另外一款開源的單元測試工具Qunit(下載地址:http://code.jquery.com/qunit),它是完全基於瀏覽器運行的,因此不需要象jsTestDriver那麼安裝麻煩,而且值得一提的是,這個框架是jQuery的單元測試Javascript框架,功能十分強大。下面是安裝方法:
1) 只需要下載qunit.js(http://code.jquery.com/qunit/qunit-git.js)和qunit.css(http://code.jquery.com/qunit/qunit-git.css)
2) 我們需要編寫一個Qunit的界面,命名為testrunner.html,代碼如下:
<DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="qunit.js" type="text/javascript"></script>
<link rel="stylesheet" media="all" href="qunit.css" />
<script src="src/mystuff.js" type="text/javascript"></script>
<script src="src-test/mystuff_qunit.js" type="text/javascript"></script>
</head>
<body>
<h1 id="qunit-header">MyStuff</h1>
<h2 id="qunit-banner"></h2>
<h2 id="qunit-userAgent"></h2>
<ol id="qunit-tests"></ol>
</body>
</html>
這個頁面中分別引入了jquery類庫,qunit的類庫,還有就是我們之前編寫的,位於Src目錄下的原先的javascript腳本mystuff.js,以及位於src-test目錄下的測試用例Mystuff_qunit.js。
接下來,來看下測試用例文件Mystuff_qunit.js,代碼如下:
module("Sample Test Case");
test("Number plus Zero Equals Number", function(){
var adder = new myAwesomeApp.MyAwesomeClass();
equals( adder.add(5,0),5);
});
test("Number plus Number Equals Sum", function(){
var adder = new myAwesomeApp.MyAwesomeClass();
equals(adder.add(5,3),8);
});
test("Zero plus Number Equals Number", function(){
var adder = new myAwesomeApp.MyAwesomeClass();
equals(adder.add(0,5),5);
});
test("Number plus Negative of Number Equals Zero", function(){
var adder = new myAwesomeApp.MyAwesomeClass();
equals(adder.add(5,-5),0);
});
test("Fails miserably", function(){
ok(false,"miserably");
});
這個看上去跟jsTestDriver有點象,但注意的是在斷言方法中,參數的順序不同,即在qunit中,斷言的參數順序為:Qunit.equals(actual, expected),即實際的數值。在前面,而期望的數值在後面,這點請注意。最後,直接在瀏覽器中運行test.html,可以看到效果如下:
▲
其中,紅色部分即時表示沒能通過的單元測試。
整合jsTestDriver和Qunit
由於jsTestDriver和Qunit各有優勢,因此我們可以考慮對其進行整合。比如,我們可以將jsTestDriver編寫的腳本移植到Qunit中去,由於它們的斷言參數順序有不同,因此可以修改一下,編寫名為jsTestDriverInQunit.js的腳本如下:
function TestCase(name, tests){
if(tests != null)
module(name);
for(var key in tests){
if(tests[key] instanceof Function && key.indexOf("test") == 0){
test(key,tests[key]);
}
}
return function(){};
}
function assertEquals(arg0,arg1){
equals(arg1,arg0);
}
function fail(msg){
ok(false,msg);
}
並且將testrunner.html修改如下:
<DOCTYPE html>
2. <html>
3. <head>
4. <script src="http://code.jquery.com/jquery-1.6.4.min.js" type="text/javascript"></script>
5. <script src="qunit.js" type="text/javascript"></script>
6. <script src="jsTestDriverInQunit.js" type="text/javascript"></script>
7. <link rel="stylesheet" media="all" href="qunit.css" />
8.
9. <script src="src/mystuff.js" type="text/javascript"></script>
10. <script src="src-test/mystuff.js" type="text/javascript"></script>
11. </head>
12. <body>
13. <h1 id="qunit-header">MyStuff</h1>
14. <h2 id="qunit-banner"></h2>
15. <h2 id="qunit-userAgent"></h2>
16. <ol id="qunit-tests"></ol>
17. </body>
18. </html>
這樣一來,我們無論是使用jsTestDriver還是使用Qunit,都可以都使用同一套測試用例了。
此外,還有一個開源項目提供了將Qunit轉化為jsTestDriver的功能,項目地址為:
http://code.google.com/p/js-test-driver/wiki/QUnitAdapter。
小結
本文簡單介紹了如何使用兩款Javascript單元測試工具進行前端的開發單元測試,前端的單元測試在複雜的前端Javascript開發中,能夠保證前端開發的質量,值得前端開發者仔細研究學習。