2012-06-18 13 views
5

背景:ユニットテストの方法DOM要素とやり取りするJavascriptコード

私はJavaのバックグラウンドから来ているので、Javascriptにも慣れていません。

私たちは、既存の(旧式の)コードと今後の作業の両方にJavaScript単位テストを導入する予定です。我々は、主にJavaのショップ(春、Weblogicなど)です。

私たちは、IDE(IntelliJアイデア)とソナーとの良好な統合と、継続的な統合の一環としてそれらを実行できるオプションを検討しています。

JsTestDriverはすべてのボックスにチェックを入れているようです。

質問:

当社の既存のJavaScriptコードの多くは、a)はJSPの中に埋め込まおよびb)直接ページ要素と対話するのjQueryを利用しています。

DOMに大きく依存する関数をテストするにはどうすればよいですか。ここで私が話している機能のいくつかのコード例です:

function enableOccupationDetailsText(){ 
    $("#fldOccupation").val("Unknown"); 
    $("#fldOccupation_Details").attr("disabled", ""); 
    $("#fldOccupation_Details").val(""); 
    $("#fldOccupation_Details").focus(); 
} 

または後者の場合

jQuery(document).ready(function(){ 

    var oTable = $('#policies').dataTable({ 
      "sDom" : 'frplitip', 
       "bProcessing": true, 
       "bServerSide": true, 
       "sAjaxSource": "xxxx.do", 
       "sPaginationType": "full_numbers", 
       "aaSorting": [[ 1, "asc" ]], 
       "oLanguage": { 
        "sProcessing": "Processing...", 
        "sLengthMenu": "Show _MENU_ policies", 
        "sZeroRecords": "No matching policies found", 
        "sInfo":   "Showing _START_ to _END_ of _TOTAL_ policies", 
        "sInfoEmpty": "Showing 0 to 0 of 0 policies", 
        "sInfoFiltered": "(filtered from _MAX_ total policies)", 
        "sInfoPostFix": "", 
        "sSearch":  "Search:", 
        "sUrl":   "", 
        "oPaginate": { 
         "sFirst": "First", 
         "sPrevious": "Previous", 
         "sNext":  "Next", 
         "sLast":  "Last" 
       } 
      }, 
       "fnRowCallback": function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { 
         $('td:eq(0)', nRow).html("<a href='/ole/policy/general_details.do?policy_id="+aData[0]+"'>"+aData[0]+"</a>"); 
         return nRow; 

       }, 

       "fnServerData" : function (url, data, callback, settings) { 

       settings.jqXHR = $.ajax({ 
        "url": url, 
        "data": data, 
        "success": function (json) { 
         if (json.errorMessage != null) { 
          var an = settings.aanFeatures.r; 
          an[0].style.fontSize="18px"; 
          an[0].style.backgroundColor="red"; 
          an[0].style.height="70px"; 
          an[0].innerHTML=json.errorMessage; 
          setTimeout('window.location="/xxxx"',1000); 
          //window.location="/xxxxx"; 
         } else { 
          $(settings.oInstance).trigger('xhr', settings); 
          callback(json); 
         } 
        }, 
        "dataType": "json", 
        "cache": false, 
        "error": function (xhr, error, thrown) { 
         if (error == "parsererror") { 
          alert("Unexpected error, please contact system administrator. Press OK to be redirected to home page."); 
          window.location="/xxxx"; 
         } 
        } 
       }); 
       } 

      }); 
     $("#policies_filter :text").attr('id', 'fldKeywordSearch'); 
     $("#policies_length :input").attr('id', 'fldNumberOfRows'); 
     $("body").find("span > span").css("border","3px solid red"); 
     oTable.fnSetFilteringDelay(500); 
     oTable.fnSearchHighlighting(); 
     $("#fldKeywordSearch").focus(); 

} 
); 

を、私のアプローチは、問題の関数があまりにも大きく、分割する必要がありますということでしょうテストすることができるようにより小さい(単位)にする。しかし、DOM、jQuery、datatables、ajaxなどとのやりとりのポイントはすべて、Javaの世界でやっているようにリファクタリングするのは本当に複雑です。

このように、上記のサンプルケースに対するご意見をお待ちしております。

+2

は、[テストDOMは、ジャスミンのテストで操作する]も参照してください(http://stackoverflow.com/questions/7672389/testing-dom-manipulating-in-jasmine-test) –

+0

もチェックアウトは何の解体についてのヘッドレスのWebKit – obimod

答えて

6

:今日、私は特にjQueryの背景にユニットテストのためのさまざまな方法を記述し、このサイトにつまずきましたコード:

// First, create the elements 
$('<input>', { id: 'fldOccupation' }).appendTo(document.body); 
$('<input>', { disabled: true, id: 'fldOccupation_Details' }) 
    .appendTo(document.body); 

// Then, run the function to test 
enableOccupationDetailsText(); 

// And test 
assert($('#fldOccupation').val(), 'Unknown'); 
assert($('#fldOccupation_Details').prop('disabled'), false); 

ご覧のとおり、それは古典的なsetup > run > assertですパターン。

+0

をphantomjsこれらのDOMオブジェクトを使用して、1つのテストで他のテストと干渉することはありませんか?それは良い練習でしょうか?もしそうなら、どうですか? –

+2

@ GregWoodsまあ、 '$( '#fldOccupation')のようなものでそれらを削除することができます。 $( '#fldOccupation_Details')。remove();または単に$(document.body.children).remove(); ' –

4

多分セレン/ SeleniumGridはあなたのために便利です:http://seleniumhq.org/

それは定義ごと「UnitTestを」ではありませんが、あなたはユニットテストとして(...と、より多くの)セレンのJavaやPythonでのテストを書くことができます。 Seleniumテストは、実際のブラウザでWebテストを開始し、フロントエンド(およびdom操作)のテストには静かです。

編集:あなたは以下のように使用することができ

function enableOccupationDetailsText(){ 
    $("#fldOccupation").val("Unknown"); 
    $("#fldOccupation_Details").attr("disabled", ""); 
    $("#fldOccupation_Details").val(""); 
    $("#fldOccupation_Details").focus(); 
} 

:次のコードをテストするにはhttp://addyosmani.com/blog/jquery-testing-tools/

関連する問題