Подтвердить что ты не робот

Единичное тестирование Javascript, который включает DOM

Как вы относитесь к блочному тестированию javascript, который использует и изменяет DOM?

Я приведу простой пример. Валидатор формы, который проверяет пустое текстовое поле, написанное на javascript и использующее JQuery.

      function Validator() {

        this.isBlank = function(id) {
            if ($(id).val() == '') {
                return true;
            } else {
                return false;
          }
        };

        this.validate = function(inputs) {

           var errors = false;

           for (var field in inputs) {
               if (this.isBlank(inputs[field])) {
                   errors = true;
                   break;
               }
           }

           return errors;
       };
    }

Использование:

var validator = new Validator();
var fields = { field_1 : '#username', field_2 : '#email' };

if (!validator.validate(fields)) {
    console.log('validation failed');
} else {
    console.log('validation passed');
}

Какова наилучшая практика для попытки сделать unit test что-то вроде этого?

4b9b3361

Ответ 1

В идеале вы должны разделить код. Логика проверки действительности действительно не требует доступа DOM, поэтому вы бы поместили ее в свою собственную функцию и поместили логику, которая обрабатывает идентификатор в значение, которое затем проверяется на другое.

Таким образом, вы можете легко unit test проверить логику и, если необходимо, выполнить функциональный тест на всем протяжении, используя некоторые из инструментов, предложенных Джозефом Мечтателем.

Ответ 2

Вы можете использовать Qunit для модульных тестов с использованием DOM. Если вы хотите автоматизировать, вы можете использовать Grunt с помощью grunt-contrib-qunit задачи, которая запускает ваши страницы в безголовый WebKit называется PhantomJS.

Ответ 3

В маловероятном случае, когда большая часть вашего кода JavaScript содержит логику и полагается на небольшое количество jQuery-кода (или живых элементов DOM), вы можете использовать код рефакторинга, чтобы заменить доступ к DOM/использование jQuery легко и выполнить запись с макетными реализациями:

 function Validator(){
    this.getElementValue = function(id){return $(id).val();}

    this.check_blank = function(id){
    if(this.getElementValue(id) == '') // replace direct call to jQuery mock-able call
       return false;
    else
       return true;
    }....
}

И в тесте реализована макетная реализация:

 test("Basic valid field", function() {
   var validation = new Validator();

   // replace element accessor with mock implementation:
   validation.getElementValue = function(id){
     equals(id, "#my_field"); // assert that ID is expected one
     return "7";
   }
   var form_fields = {field_1 : '#my_field'};

   ok(validation.validate(form_fields), "non-empty field should be valid");
 }