天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

JavaScript 組件之旅(四):測試 JavaScript 組件

smart-queue-test
本期,我們要討論的話題是 JavaScript 的測試,以檢查組件的狀態和工作方式是否符合預期,還會介紹一個可以方便編寫測試用例的測試方法。這里說的測試當然是使用自動化的測試手段,這是軟件質量保證(QA)的重要環節。就本系列文章介紹的 Smart Queue 來說,我們的測試目標包括:

  • Task 對象的創建:第二期的代碼提供了多種創建方式,需要測試對象創建后的狀態。
  • Queue 內的任務運行次序:我們提供了兩種改變運行次序的方式:優先級和依賴配置,同樣也要測試各種配置對次序的影響。

對于第一個目標,只需檢查對象創建后的屬性是否符合預期即可。我們已經多次提到“符合預期”,斷言(Assert)正是為此而設計的。簡單的說,斷言就是確保所測試的表達式結果為“真”,否則,以某種方式通知測試人員,并幫助其定位斷言失敗的測試用例。
第二個目標稍稍有點復雜。由于我們在組件編碼實現的時候,將排序后的隊列(_sorted)隱藏在了閉包中,所以外部是無法訪問的。有兩種方法可以考慮:(1)重構代碼,增加代碼的可測試性,又有兩種重構方法:(a)設置 debug 開關,打開時將 _sorted 暴露給外部;(b)增加獨立文件,以構建的方式拼接代碼最終生成一個測試版本。(2)測試行為的結果而不是過程,前一種方法實質上是深入到組件的運行時狀態,而這個方法只是檢查組件的運行結果。本期選用后一種種測試方式,第一種測試方式留給有興趣的讀者練習:)

需要說明的是,我個人不贊成第一種的方法a. 為什么呢?我先說一下這個任務隊列的設計理念:

  • 它只是一個隊列,只負責“按需”調整任務的運行次序,不關注任務的個體細節。換句話說,它操作整體的任務,而不關心任務具體的行為和表現。
  • 它是個安全的隊列,使用者(第一期提到的“客戶”)可以放心把任務添加進去,不用擔心這個任務信息會被其他客戶看到。需要說明的是,第二期實現代碼中有 SmartQueue.Queue = [[], [], []], 結果是外部可以訪問到隊列項。代碼僅供介紹之用,你可以安全地刪除 SmartQueue.Queue = 來達成安全控制。

回到剛才討論的話題,設置 debug 開關后,任務信息就潛在的泄漏可能性。進一步地,繼續改造代碼也可以達成在使用 debug 開關時的安全性,做法是將開關的控制放在 SmartQueue 的構造函數中,這樣要求 SmartQueue 實現 Singleton 模式(見上一篇文章);一旦創建對象后,不允許修改閉包內的 debug 標記。

在編寫具體測試代碼前,我們設計了一個測試方法,以簡化測試代碼(主要是用例)的編寫。簡單地說,就是將測試用例與測試本身的代碼分離――前者以語義良好的方式編寫,后者是一次性編寫,用于處理前者設定的測試用例。用例編寫者需要寫格式形如這樣的代碼:

  <ul id="J_test_cases">    <li>      <pre>task = new sq.Task({fn: function() { log('unamed') }})</pre>      <ul>        <li>typeof task.fn === 'function'</li>        <li>task.name === 't0'</li>        <li>task.level === 1</li>        <li>task.dependencies.length === 0</li>        <li>task.context == window</li>      </ul>    </li>    <li>      <pre>task = new sq.Task({fn: function() { log('unamed') }, name: 'hello'})</pre>      <ul>        <li>task.name === 'hello'</li>        <li>task.level === 1</li>      </ul>    </li>  </ul>

ul li pre (CSS 選擇器路徑,下同)中寫要測試的代碼,相當于前置操作;ul ul li 中對這個代碼進行斷言測試,可以編寫多條斷言。這里建議對基本數據類型使用 ===!=== 運算符以加強對數據類型的預期判斷。

接下來,我們編寫兩個 helper 方法用來輸出和測試:

function log(str) {  node.value += str + '/n';}function assert(expression) {  var flag;  eval('flag = ' + expression);  return typeof(flag) === 'boolean' && flag;}

log 用來向文本框追加信息,assert 用來測試傳入表達式的值。測試方法如下(這里使用了 jQuery):

var sq = SmartQueue, task, total = 0, passed = 0, failed = 0;$('#J_test_cases').children().each(function(index) {  eval($('pre', this).text());  task.register();  $('li', this).each(function() {    var item = $(this);    var flag = assert(item.text());    if(flag) passed ++; else failed ++;    item.prepend((flag ? '<font color="green">[PASS]</font>' : '<font color="red">[FAIL]</font>') + ' ');    total++;  }).wrap('<pre></pre>');}).end().before('<p>Total: ' + total + ', passed: '+ passed +', failed: ' + failed + '</p>');sq.fire();

這個結構還可改進一下,比如輸出測試說明而不是具體的代碼,也可以增加后置操作,這里就不再演示了。你還可以查看完整的測試頁面,含有 23 個測試用例和完整的測試實現。

~~~~~~~~~~~~~ 八卦分割線 ~~~~~~~~~~~~~

好吧,我們已經體會到了思考和行動的樂趣,走到了系列文章的尾聲,但這只是開始。我們經歷了一個很小的實用組件的實現全過程,領略到了 JavaScript 世界的精彩,讓我們繼續前行~

JavaScript技術JavaScript 組件之旅(四):測試 JavaScript 組件,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 精品国产乱码久久久久久免费流畅 | 久久久精品国产免费A片胖妇女 | 99国内精品 | 国产手机精品一区二区 | 国产视频a在线观看v | 久久www成人看片 | 久久婷五月综合色啪网 | 在线亚洲中文精品第1页 | 国产超嫩一线天在线播放 | 消息称老熟妇乱视频一区二区 | 国产成人综合高清在线观看 | 国产人人为我我为人人澡 | 四虎永久在线精品国产 | 抽插嫩B乳无码漫 | 国产中文字幕一区 | 女仆乖H调教跪趴 | 久久免费精彩视频 | 啊灬啊灬啊灬快灬深高潮啦 | 翁公咬着小娇乳H边走边欢A | 国产在线视频在线观看 | 久久亚洲精品成人综合 | 国产成人精品永久免费视频 | 4480yy午夜私人影院 | 精品国产国产综合精品 | 色一情一乱一伦一区二区三区 | 无人区在线日本高清免费 | 日日操夜夜摸 | 狼人大香伊蕉国产WWW亚洲 | 大陆极品少妇内射AAAAAA | 色婷婷激婷婷深爱五月小蛇 | 无码乱人伦一区二区亚洲 | 亚洲人成人77777在线播放 | 国内精品人妻无码久久久影院蜜桃 | 免费人成网站永久 | 亚洲最大成人 | 校花被扒衣吸乳羞羞漫画 | 男人J桶女人P视频无遮挡网站 | 午夜伦理网 | 精品视频免费在线观看 | 佐山爱巨大肥臀在线 | 猪蜜蜜网站在线观看电视剧 |