Если у вас еще нет привычки, написание тестов для вашего кода - отличный способ оставаться дисциплинированным инженером-программистом в любом проекте. Если вы не думаете, что это того стоит, но хотите, чтобы у вас был способ тщательно проверять свой код в процессе работы, это краткое руководство подойдет вам идеально. Я расскажу об основах модульного тестирования, интеграционного тестирования и сквозного тестирования с использованием самого простого технологического стека, который поможет вам начать тестирование всего за несколько минут.

Настройка:

Перед тем как начать, установите тестовую среду Mocha в качестве зависимости разработки для вашего проекта. Mocha - это широко используемая среда тестирования JavaScript, работающая на Node.js, которая делает тестирование действительно простым. Нажмите здесь, чтобы ознакомиться с их (отличной) документацией.

$ npm install mocha --save-dev

Затем вам понадобится библиотека утверждений Chai, которая заставит ваше кодирование чувствовать себя как писать на обычном английском. Выполните команду ниже, чтобы установить через npm.

$ npm install chai --save-dev

Наконец, установите среду тестирования Sinon, которая позволит использовать шпионов, заглушек и имитаций. Подробнее об этом позже.

$ npm install sinon --save-dev

Модульное тестирование

Теперь мы готовы открыть новый файл и начать писать тесты. Мы начнем с простых модульных тестов. Это небольшие тесты, которые позволяют вам проверить функциональность одного небольшого аспекта вашей программы, который не взаимодействует или сильно зависит от других элементов. В качестве примера я напишу несколько тестов для метода объекта в моем коде.

var assert = chai.assert;
var should = chai.should();
describe('Tests for todo.app', function() {
  describe('the trimTodoName function', function() {
    it('should remove leading whitespace', function() {
      todo.util.trimTodoName('   name').should.equal('name');
    });
    it('should remove trailing whitespace', function() {
      todo.util.trimTodoName('name   ').should.have.length(4);
    });
    it('should remove leading and trailing whitespace', function() {
      assert(todo.util.trimTodoName('  name  '), 'name');
    });
  });
}

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

Затем я выписываю реальные тесты, используя конструкцию Mocha "it". Опять же, первый аргумент - это строка, в которой говорится, что вы тестируете, а второй аргумент - это функция, которая запускает тест. Здесь в игру вступает библиотека утверждений Chai. Посмотрите на приведенный ниже код, взятый из приведенного выше примера:

todo.util.trimTodoName('   name').should.equal('name');

В функции блока «it» эта строка в основном говорит, что «todo.util.trimToDoName (« name ») должно равняться« name ». Я же сказал, что это будет похоже на английский! Это благодаря способности Чай соединять утверждения в цепочку. Имейте в виду, что хотя они и выглядят как предложения на английском языке, это просто обычные старые функции. В приведенной выше строке используется стиль тестирования Chai «следует», но вы можете провести тот же тест, используя конструкции «assert» или «expect» в Chai. Фактически, я использую стиль «assert» в третьем тесте приведенного выше примера кода.

Теперь вы официально выполнили первые тесты своего кода! В зависимости от того, как вы настроили свою файловую структуру, или если вы используете систему сборки / средство запуска тестов, вы должны иметь возможность запустить тест npm и увидеть результат теста.

Интеграционное тестирование

Теперь мы перейдем к более обширным тестам. Интеграционные тесты используются, когда у вас есть код, который зависит от других модулей и поэтому не может быть изолирован. Допустим, у нас был сервер, который мы хотели убедиться, что отправляет определенный бит данных при вызове определенной функции. Я расскажу по шагам, как мы это добьемся, используя несколько удобных функций из библиотеки Sinon.

  1. Используйте функцию Mocha «description», чтобы подготовить почву для наших тестов, используя ее точно так же, как и в нашем предыдущем примере.
  2. Используйте функцию Mocha «до», чтобы настроить все «поддельные» аспекты теста. Внутри функции before мы можем написать любой код, который мы хотим запустить, до функции «it», что и является реальной логикой тестирования.
  3. В блоке «до» мы создадим объект JSON, который наш фальшивый сервер будет отправлять в качестве ответа при проверке связи.
  4. Здесь мы сделаем заглушку и поддельный сервер, используя две библиотечные функции Sinon. Заглушка - это функция («шпион»), которой мы можем дать заранее запрограммированное поведение. В этом случае мы «заглушим» функцию «setup», которая позволит нам увидеть, сколько раз она вызывалась во время теста. В строке ниже мы используем функцию sinon.fakeServer.create () и назначаем ее переменной. Теперь мы можем дать этому поддельному серверу заранее заданный ответ и убедиться, что наша тестовая заглушка отвечает правильно.
  5. Теперь, когда у нас есть поддельный сервер, мы можем дать ему заранее запрограммированный ответ для отправки после его вызова. Если наша функция «setup» работает правильно, она будет вызвана и отправит обратно объект JSON после того, как наш поддельный сервер отправит ему запрос GET.
  6. Наконец, теперь, когда вся наша настройка завершена, мы можем написать фактический тест. Мы можем сделать это точно так же, как и в наших модульных тестах. Сначала мы вызовем todo.init () и server.respond (). На этом этапе установочная заглушка должна была ответить заранее определенным объектом JSON, поэтому мы напишем две функции «assert», чтобы проверить это. Полный код ниже.
//step1
describe('API integration', function(){
//step2
  before(function(){
//step3
    var JSONresponse = JSON.stringify(
    {todos: [{name: 'test1',done: true}] }
    )
//step4
    var setupStub = sinon.stub(todo, 'setup')
    var server = sinon.fakeServer.create();
//step5
    server.respondWith
    (
      "GET", 
      "https://localhost:3000/todos", 
      [200, {"Content-Type":"application/json"}, JSONresponse]
    )
  })
//step6
  it('todo.setup receives an array of todos after todo.init()',
  function() {
    todo.init();
    server.respond();
    assert(setupStub.calledOnce);
    assert(setupStub.calledWith(JSON.parse(JSONresponse.todos))
  });
});

Сквозное тестирование

Еще более тщательными, чем интеграционные, тесты являются полные сквозные тесты. Как следует из названия, эти тесты могут гарантировать, что в конце дня пользователь увидит то, что он должен делать, когда в ваше веб-приложение поступит определенный ввод. Для этого они запускают собственную версию браузера, а затем выполняют заранее заданные команды, прежде чем проверять, получили ли они правильный ответ. Еще раз установите через npm:

npm install casperjs

Теперь мы можем использовать casper.test.begin (), чтобы начать писать тест. В этом примере я продемонстрирую, как я проверяю, правильно ли отображается список в моем приложении с делами после добавления элемента. Я снова разобью его по шагам:

  1. Вызовите casper.test.begin, передав строку (имя вашего теста) в качестве первого аргумента, количество утверждений, которые вы планируете использовать в качестве второго аргумента, и, наконец, функцию набора, в которую вы поместите логику для теста.
  2. Внутри функции вызовите casper.start с URL-адресом и анонимной функцией. Здесь вы разместите остальную логику.
  3. Шаг 3: Сообщите касперу, что он должен делать перед запуском теста. Думайте об этом как о «призрачном пользователе», который волшебным образом делает что-то определенное с вашим приложением перед запуском теста. В этом случае я хочу заполнить форму «to-do» в моем приложении элементом, который я позже проверю, чтобы убедиться, что он существует. Если это так, то я буду знать, что мое приложение позволяет пользователям успешно добавлять элементы в список дел. Casper позволяет вам делать с вашим приложением очень широкий спектр вещей, помимо заполнения полей поиска перед запуском теста.
  4. Теперь мы можем написать тест, чтобы убедиться, что этот элемент теперь присутствует в списке дел.
  5. Все, что вы хотите, чтобы casper сделал после запуска тестов. Почти всегда он просто вызывает test.done ().

Вот и все. Теперь вы можете запустить свой тест и увидеть красивую информацию обо всех выполненных http-запросах, количестве времени, которое потребовалось для этого, и, конечно, о том, прошел ли ваш тест!