XUnit是一套標準化的獨立於語言的概念和結構集合,用於編寫和運行單元測試(Unit tests).javascript
每個語言都有一個用於單元測試的XUnit框架,好比Java有JUnit, C++有CppUnit, PHP有PHPUnit, Oracle SQL有UTPL/SQL.html
JsUnit的官網: http://jsunit.net/java
JsUnit遵循XUnit的一些慣例:web
單元測試在JsUnit中叫作Test Functions.服務器
Test Functions所在的HTML頁面叫作Test Page.app
一個Test Page是一個包含jsUnitCore.js的HTML頁面. jsUnitCore.js提供了一些斷言函數, 好比assertEquals(comment, arg1, arg2).框架
JsUnit支持setUp()和tearDown().函數
Test Suite Page聲明瞭一個suite()函數,返回一個JsUnitTestSuite, 用來運行含多個測試的套件.單元測試
JsUnit的testRunner.html頁運行Test Pages.測試
TestRunner頁面能夠運行在一個文件服務器或者web服務器上.
因爲JavaScript沒有訪問修飾符,因此一般在JavaScript中,不但願外界訪問的成員和方法名如下劃線開始.
這是一種編碼規範,不是語言的規定,雖然外界仍然能夠訪問可是不推薦.
JsUnit測試函數要遵循的規則與JUnit3.8相似,好比說測試函數名以test開頭等.
待測試的源代碼:test1.js
function add(num1, num2) { return num1 + num2; } function subtract(num1, num2) { return num1 - num2; } function multiply(num1, num2) { return num1 * num2; } function addNumbers() { var v1 = document.getElementById("value1").value; var v2 = document.getElementById("value2").value; v1 = parseInt(v1); v2 = parseInt(v2); var v3 = v1 + v2; document.getElementById("value3").value = v3; }
測試頁面:test1.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title> New Document </title> <meta name="Generator" content="EditPlus"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <script type="text/javascript" src="..\jsunit2_2\jsunit\app\jsUnitCore.js"></script> <script type="text/javascript" src="test1.js"></script> <script type="text/javascript"> var count = 0; // 此函數只執行一次(在頁面加載後),相似於JUnit 4.x中的@BeforeClass // 注意:並無與@AfterClass對應的函數存在 function setUpPage() { alert('setUpPage Invoked'); // 這行代碼必須放在setUpPage函數的最後一行 // 告訴JsUnit,setUpPage函數已經執行完畢 setUpPageStatus = "complete"; } // setUp run before every test function function setUp() { //alert(count++); //JUnit若這樣執行,count全是0,由於每個測試方法都會生成新的測試對象; //JsUnit會遞增count, 由於都是在同一個頁面裏去執行,因此會基於原有的值 //設定初始條件 document.getElementById("value1").value = 2; document.getElementById("value2").value = 3; } // tearDown run after every test function function tearDown() { //alert("tearDown"); //清理狀態 document.getElementById("value1").value = ""; document.getElementById("value2").value = ""; document.getElementById("value3").value = ""; } // 如下爲測試函數(Test Function) function testAdd() { var result = add(1, 2); assertEquals(3, result); } function testSubtract() { var result = subtract(1, 2); assertEquals(-1, result); } function testMultiply() { var result = multiply(1, 2); assertEquals(2,result); } function testAddNumbers() { addNumbers(); assertEquals("5", document.getElementById("value3").value); } </script> </head> <body> <input type="text" id="value1"><br> <input type="text" id="value2"><br> <input type="text" id="value3"><br> <input type="button" value="Add" onclick="addNumbers();"> </body> </html>
使用JsUnit提供的測試運行器: testRunner.html, 加載測試頁面,便可運行相關測試,並報告結果.
setUp()在每個測試方法運行以前運行;
tearDown()在每個測試方法運行以後運行.
對於JsUnit來講, 其setUp()和tearDown()方法與JUnit的運行原理是不一樣的.
JUnit中的setUp()和tearDown()之間是沒有關係的,也就是說不一樣的測試方法運行在不一樣的測試對象之中;
而JsUnit的各個測試函數是運行在同一個測試頁面中,所以同一個頁面中setUp()和tearDown()運行屢次(每一個測試函數以前和以後),會針對同一個變量進行操做.
setUpPage()在測試頁面加載時執行,每次運行只執行一次.
這個方法的末尾必須加上:
setUpPageStatus = "complete";
表示setUpPage()執行完成,不然會提示setUpPage not completed, 從而沒法執行測試用例.
JsUnitTestSuite定義在jsUnitCore.js中, JsUnitTestSuite表明多個JsUnit測試頁面的套件,測試頁面和測試套件均可以被加在套件中,即套件是可嵌套的.(組合模式).
JsUnitTestSuite的定義(見jsUnitCore.js):
/** * @class * A JsUnitTestSuite represents a suite of JsUnit Test Pages. Test Pages and Test Suites can be added to a * JsUnitTestSuite * @constructor */ function JsUnitTestSuite() { /** * Declares that this object is a JsUnitTestSuite */ this.isJsUnitTestSuite = true; /** * @private */ this._testPages = Array(); /** * @private */ this._pageIndex = 0; for (var i = 0; i < arguments.length; i++) { if (arguments[i]._testPages) { this.addTestSuite(arguments[i]); } else { this.addTestPage(arguments[i]); } } }
測試套件的使用例子1: test2.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title> New Document </title> <meta name="Generator" content="EditPlus"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <script type="text/javascript" src="..\jsunit2_2\jsunit\app\jsUnitCore.js"></script> <script type="text/javascript"> //測試套件名必定爲suite function suite() { var testSuite = new top.jsUnitTestSuite(); // 增長的測試頁面的路徑是相對於測試運行器(testRunner.html)的路徑 // 而不是當前頁面 testSuite.addTestPage("../../jsUnit_code/test1.html"); testSuite.addTestPage("../../jsUnit_code/test1.html"); testSuite.addTestPage("../../jsUnit_code/test1.html"); return testSuite; // 最後須要返回套件 } </script> </head> <body> </body> </html>
測試套件的使用例子2: test3.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title> New Document </title> <meta name="Generator" content="EditPlus"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <script type="text/javascript" src="..\jsunit2_2\jsunit\app\jsUnitCore.js"></script> <script type="text/javascript"> // 自定義的測試套件 function mySuite() { var testSuite = new top.jsUnitTestSuite(); testSuite.addTestPage("../../jsUnit_code/test1.html"); testSuite.addTestPage("../../jsUnit_code/test1.html"); testSuite.addTestPage("../../jsUnit_code/test1.html"); return testSuite; } function suite() { var testSuite = new top.jsUnitTestSuite(); testSuite.addTestPage("../../jsUnit_code/test1.html"); // 在測試套件中加入頁面 testSuite.addTestSuite(mySuite()); // 在測試套件中加入測試套件 return testSuite; // 記得返回套件 } </script> </head> <body> </body> </html>
聖思園張龍老師Java Web培訓視頻教程: 60-62.
JsUnit官網: http://jsunit.net/