2012-06-18 10 views
5

Nền:Cách kiểm tra đơn vị mã Javascript tương tác với các phần tử DOM

Tôi đến từ nền Java nên không quá quen thuộc với Javascript.

Chúng tôi đang có kế hoạch giới thiệu thử nghiệm đơn vị JavaScript cho cả mã hiện có (cũ) của chúng tôi và công việc trong tương lai. Chúng tôi là một cửa hàng java (Spring, Weblogic, vv) chủ yếu.

Chúng tôi đang xem xét các tùy chọn cung cấp cho chúng tôi tích hợp tốt với IDE (ý tưởng IntelliJ) và sonar, cũng như có thể chạy chúng như một phần của tích hợp liên tục.

JsTestDriver dường như đánh dấu tất cả các hộp.

Câu hỏi:

Rất nhiều của chúng tôi hiện có mã javascript là a) embeded trong JSP và b) sử dụng jQuery để tương tác với các yếu tố trang trực tiếp.

Chúng ta nên thử nghiệm như thế nào về chức năng phụ thuộc nhiều vào DOM. Dưới đây là một số ví dụ mã các chức năng mà tôi đang nói về:

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

hoặc

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(); 

} 
); 

Trong trường hợp sau, cách tiếp cận của tôi sẽ là các chức năng trong câu hỏi là cách quá lớn và cần được phá vỡ để nhỏ hơn (đơn vị) để nó có thể được kiểm tra. Nhưng tất cả các điểm tương tác với DOM, jQuery, datatables, ajax vv làm cho nó thực sự phức tạp để tái cấu trúc mọi thứ theo cách chúng ta làm trong thế giới Java để làm cho nó dễ kiểm tra hơn.

Vì vậy, bất kỳ đề xuất nào ở trên đối với các trường hợp mẫu sẽ được đánh giá rất nhiều!

+2

Xem thêm [Kiểm tra DOM thao tác trong thử nghiệm Jasmine] (http://stackoverflow.com/questions/7672389/testing-dom-manipulating-in-jasmine-test) –

+0

cũng kiểm tra các trang web không có đầu trang phantomjs – obimod

Trả lời

6

Để kiểm tra các đoạn mã sau:

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

Bạn có thể sử dụng như sau mã:

// 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); 

Như bạn thấy, nó chỉ là cổ điển setup > run > assert mẫu.

+0

những gì về rách xuống những đối tượng DOM đó để bạn không có một thử nghiệm can thiệp vào một đối tượng khác? Đó có phải là thực hành tốt không? Nếu vậy, làm thế nào? –

+2

@GregWoods tốt, bạn có thể loại bỏ chúng với một cái gì đó như '$ ('# fldOccupation'). Remove(); $ ('# fldOccupation_Details'). remove(); 'hoặc đơn giản là' $ (document.body.children) .remove(); ' –

4

lẽ Selenium/SeleniumGrid rất hữu ích cho bạn: http://seleniumhq.org/

Nó không phải là một "UnitTest" theo định nghĩa, nhưng bạn có thể viết các bài kiểm tra selen với java hoặc python (và nhiều hơn nữa ...) như kiểm tra đơn vị. Seleniumtests bắt đầu kiểm tra web trong các trình duyệt thực, và rất yên tĩnh để kiểm tra các giao diện (và các thao tác dom).

Sửa: hôm nay tôi stumbled khi trang web này mô tả cách khác nhau cho đơn vị thử nghiệm đặc biệt là trong một nền jQuery: http://addyosmani.com/blog/jquery-testing-tools/