董寧 王波
摘要 運行和調試JavaScript代碼的主要工具是Web瀏覽器,現(xiàn)代Web瀏覽器一般包含調試JavaScript代碼的控制臺。JavaScript代碼運行中的錯誤信息、Ajax調用、性能分析結果、命令行執(zhí)行結果都會顯示在控制臺界面上。Firefox瀏覽器的Firebug提供了很多手段,可以將JavaScript代碼運行中的信息輸出到Firebug控制臺。通過靈活使用控制臺語句,可以方便地實現(xiàn)對JavaScript代碼的單元測試。
關鍵詞 JavaScript ;控制臺;單元測試
DOI DOI: 10.11907/rjdk.162418
中圖分類號: TP306
文獻標識碼: A 文章編號 文章編號: 16727800(2017)002001303
0 引言
在計算機編程中,單元測試[1]是針對程序模塊(軟件設計的最小單位)進行正確性檢驗的測試工作。程序單元是最小的測試部件。在過程化編程中,一個單元就是單個程序、函數(shù)、過程等;對于面向對象編程,最小單元就是方法,包括基類(超類)、抽象類或者派生類(子類)中的方法。每個理想的測試案例獨立于其它案例。為測試時隔離模塊,經常使用stubs、mock或fake等測試馬甲程序。單元測試通常由軟件開發(fā)人員編寫,用于確保所寫代碼符合軟件需求和遵循開發(fā)目標。
運行和調試JavaScript代碼[2]的主要工具是Web瀏覽器,現(xiàn)代的Web瀏覽器一般包含調試JavaScript代碼的控制臺。對于JavaScript代碼,Mozilla Firefox是最適合運行與調試的瀏覽器之一。Mozilla Firefox瀏覽器的插件Firebug是調試JavaScript代碼必不可少的,尤其是涉及到Ajax技術的Web應用。在Mozilla Firefox瀏覽器中安裝好Firebug插件后,JavaScript代碼運行中的錯誤信息、Ajax調用、性能分析結果、命令行執(zhí)行結果都會顯示在控制臺界面上。Firebug提供了很多手段可以將JavaScript代碼運行中的信息輸出到Firebug控制臺,通過靈活使用控制臺語句可以方便實現(xiàn)對JavaScript代碼的單元測試。
1 JavaScript代碼中控制臺語句使用
在JavaScript代碼中可以使用console.log()方法向控制臺輸出信息。實際上,console.log()方法包含在conosle對象中,而console對象則是由瀏覽器提供的(IE6及以前瀏覽器不支持console對象)。
除了最基本的console.log()方法外,conosle對象還提供了多種方法以便向控制臺輸出不同類型的信息和調試JavaScript代碼。
(1)不同類型輸出方法。
根據(jù)信息的不同性質,console對象除了console.log()方法外還有4種輸出信息方法:一般信息console.info()、調試信息console.debug()、警告提示console.warn()和錯誤提示console.error()。
(2)自定義輸出格式。
console對象所有的輸出方法都可以使用printf風格的占位符對輸出內容進行格式化。支持的占位符有字符(%s)、整數(shù)(%d或%i)、浮點數(shù)(%f)和對象(%o)。
(3)分組輸出。
如果在JavaScript代碼運行過程中需要輸出數(shù)據(jù)太多,則可以使用分組的方式輸出到控制臺以便查看和分析。conosle對象中的console.group()和console.groupEnd()方法提供了數(shù)據(jù)分組輸出功能。
(4)輸出指定對象所有屬性和方法。
console.dir()方法可以輸出傳入對象的所有屬性和方法。
(5)顯示頁面對象的HTML代碼。
console.dirxml()方法可以顯示輸入的頁面對象HTML代碼,以便查看和調試。
(6)斷言。
console.assert()方法提供了基本的代碼測試功能。該方法用來判斷一個表達式或變量是否為真,如果不為真,則在控制臺輸出一條相應信息,并且拋出一個異常。
(7)跟蹤方法調用軌跡。
console.trace()方法可以用來追蹤方法的調用軌跡,用來對遞歸方法或調用過程較復雜的方法進行分析。
(8)計時方法。
console.time()和console.timeEnd()方法可以用來記錄并輸出代碼的運行時間。
(9)性能分析方法。
性能分析指分析程序各個部分的運行時間,console.profile()可以用來對JavaScript代碼進行性能分析,找出代碼瓶頸。
2 JavaScript代碼單元測試實現(xiàn)
如果需要測試某些不涉及DOM和CSS操作的JavaScript代碼,用Qunit之類的第三方JavaScript單元測試框架[3]略顯繁瑣,效率不高,這類JavaScript代碼最適合用控制臺語句做單元測試。
例如某項目需要用JavaScript代碼實現(xiàn)快速排序[4],具體實現(xiàn)代碼如下:
//swap函數(shù)實現(xiàn)元素交換
function swap(list,firstIndex,secondIndex){
var temp = list[firstIndex];
list[firstIndex]= list[secondIndex];
list[secondIndex]=temp;
}
//getMiddle函數(shù)獲取中軸點
function getMiddle(list,left,right) {
var pivot = list[Math.floor((right + left)/2)];
var i = left;
var j = right;
while (i <= j) {
while (list[i]< pivot) {
i++;
}
while (list[j]> pivot) {
j--;
}
if (i <= j) {
swap(list,i,j);
i++;
j--;
}
}
return i;
}
//quickSort函數(shù)以遞歸方式完成快速排序
function quickSort(list,left,right) {
var index;
if (list.length > 1) {
index = getMiddle(list,left,right);
if (left < index - 1) {
quickSort(list,left,index - 1);
}
if (index < right) {
quickSort(list,index,right);
}
}
return list;
}
上述快速排序的實現(xiàn)代碼可以使用控制臺語句中的斷言部分完成測試,具體如下:
//待排序list
var array=[6,2,9,8,1,7];
//預期的結果
var result=[1,2,6,7,8,9];
//測試swap函數(shù)
swap(array,1,5);
console.assert(array[1]==7&&array[5]==2,"swap函數(shù)錯誤!");
//測試getMiddle函數(shù)
var m = getMiddle(array,0,array.length-1);
console.assert(m==5,"getMiddle函數(shù)錯誤!");
//測試quickSort函數(shù)
quickSort(array,0,array.length-1);
console.assert(array.toString()==result.toString(),"quickSort函數(shù)錯誤!");
//單元測試結束
console.info("測試完成!");
通過控制臺語句中的console.assert()方法可以分別測試代碼中的swap函數(shù)、getMiddle函數(shù)和quickSort函數(shù)。如果測試通過,則會看到在控制臺中輸出帶有信息提示圖標的“測試完成!”字樣。
如果其中某一個函數(shù)出錯則會有相應提示,如圖1所示。
上述針對快速排序模塊的測試很簡單,測試結果也沒有問題。但是對單元測試來說,這個測試用例太單一和普通了。為了提高測試用例[5]覆蓋率,最好寫一個輔助函數(shù)tester來調用被測試代碼和使用控制臺語句輸出結果,具體做法如下:
function tester(name,result,expect){
//使用分組語句輸出測試用例名
console.group(name);
if(result==expect){
//測試通過,信息提示
console.info("通過!");
}else{
//測試失敗,警告提示
console.warn("失敗");
}
//分組結束
console.groupEnd();
}
如果用上述tester函數(shù)測試完成快速排序的quickSort函數(shù),可以這樣實現(xiàn):
//待排序list
var array1=[6,2,9,8,1,7];
//預期的結果
var result1=[1,2,6,7,8,9];
//待排序list2
var array2= [6,2,9,8,1,7,85,12,48,56,78,987,45,
12,-78,45,0,58,96,12.56,12.3,7.36];
//預期的結果2
var result2 = [-78,0,1,2,6,7,7.36,8,9,12,12,12.3,
12.56,45,45,48,56,58,78,85,96,987];
//錯誤結果測試
tester("測試錯誤輸入",1,0);
//測試快速排序
quickSort(array1,0,array1.length-1);
tester("常規(guī)測試",array1.toString(),result1.toString());
quickSort(array2,0,array2.length-1);
tester("包含負數(shù)與小數(shù)測試",array2.toString(),result2.toString());
代碼運行結果如圖2所示。
可使用tester函數(shù)添加許多測試用例,并且還能為用例命名,在控制臺中直接顯示每個用例是否通過,同時用不同顏色標記,使結果一目了然。至此一個基本的單元測試就完成了。
3 結語
快速排序算法的JavaScript代碼,靈活使用控制臺語句可快速完成代碼模塊的單元測試,比起專業(yè)的第三方JavaScript單元測試框架更高效,學習曲線也不那么陡峭。但是,利用控制臺語句實現(xiàn)JavaScript代碼單元測試主要適用于邏輯代碼,而前端開發(fā)很多時候要和UI關聯(lián),雖然UI相關的代碼也可以進行單元測試,但很麻煩,比起邏輯代碼難度大得多。隨著單元測試的普及,尤其是敏捷開發(fā)的推動,涌現(xiàn)了許多優(yōu)秀的JavaScript單元測試框架,如Qunit和Jasmine等,每個都有各自擅長的領域。對于基于JavaScript語言的前端項目單元測試,結合控制臺語句,精心選擇框架,綜合考慮項目實際情況,一定可以寫出合適的測試代碼。
參考文獻:
[1] 張軍,李攀,邢光輝,等.軟件測試的認知誤區(qū)和單元測試實戰(zhàn)流程[J].科技創(chuàng)新與應用,2016 (25):120120.
[2] 張令芬.JavaScript API自動化測試方案的管理設計與實現(xiàn)[J].電子設計工程,2016,24(2):3537,41.
[3] 王婷婷,申啟杰.JavaScript調試器軟件架構[J].湖南師范大學學報,2014(6):8892.
[4] 王善坤,陶禎蓉.一種三路劃分快速排序的改進算法[J].計算機應用研究,2012,29(7):25132516.
[5] 張智軼,陳振宇,徐寶文,等.測試用例演化研究進展[J].軟件學報,2013,24(4):663674.
(責任編輯:杜能鋼)