2012-06-18 2 views
5

Фон:Как модульный тест Код Javascript, который взаимодействует с элементами DOM

Я иду из фона Java, поэтому не слишком хорошо знаком с Javascript.

Мы планируем внедрить тестирование модуля JavaScript как на наш существующий (устаревший) код, так и на будущую работу. В основном мы являемся магазином java (Spring, Weblogic и т. Д.).

Мы рассматриваем варианты, которые дают нам хорошую интеграцию с IDE (идея IntelliJ) и сонара, а также возможность запускать их как часть непрерывной интеграции.

JsTestDriver, похоже, все флажки.

Вопрос:

Много наших существующих Javascript кода а) в JSPs поместить его и б) использует 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 манипуляции в тесте Jasmine] (http://stackoverflow.com/questions/7672389/testing-dom-manipulating-in-jasmine-test) –

+0

также проверить phantomjs обезглавленный WebKit – obimod

ответ

6

Чтобы проверить следующий код:

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

Вы можете использовать следующие код:

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

насчет срывая эти объекты DOM, чтобы у вас не было одного теста, мешающего другому? Будет ли это хорошей практикой? Если да, то как? –

+2

@GregWoods хорошо, вы можете удалить их с чем-то вроде '$ ('# fldOccupation'). Remove(); $ ('# fldOccupation_Details'). remove(); 'или просто' $ (document.body.children) .remove(); ' –

4

может быть Селен/SeleniumGrid является полезным для вас: http://seleniumhq.org/

Это не «UnitTest» по определению, но вы можете написать селен тесты с Java или Python (и многой другой ...) в качестве модульных тестов. Seleniumtests запускает веб-тесты в реальных браузерах и отлично подходит для тестирования интерфейсов (и манипуляций с домино).

Edit: сегодня я наткнулся на этот сайт, описывающий различные способы для модульного тестирования, особенно на фоне JQuery: http://addyosmani.com/blog/jquery-testing-tools/

Смежные вопросы