Если у вас еще нет привычки, написание тестов для вашего кода - отличный способ оставаться дисциплинированным инженером-программистом в любом проекте. Если вы не думаете, что это того стоит, но хотите, чтобы у вас был способ тщательно проверять свой код в процессе работы, это краткое руководство подойдет вам идеально. Я расскажу об основах модульного тестирования, интеграционного тестирования и сквозного тестирования с использованием самого простого технологического стека, который поможет вам начать тестирование всего за несколько минут.
Настройка:
Перед тем как начать, установите тестовую среду 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.
- Используйте функцию Mocha «description», чтобы подготовить почву для наших тестов, используя ее точно так же, как и в нашем предыдущем примере.
- Используйте функцию Mocha «до», чтобы настроить все «поддельные» аспекты теста. Внутри функции before мы можем написать любой код, который мы хотим запустить, до функции «it», что и является реальной логикой тестирования.
- В блоке «до» мы создадим объект JSON, который наш фальшивый сервер будет отправлять в качестве ответа при проверке связи.
- Здесь мы сделаем заглушку и поддельный сервер, используя две библиотечные функции Sinon. Заглушка - это функция («шпион»), которой мы можем дать заранее запрограммированное поведение. В этом случае мы «заглушим» функцию «setup», которая позволит нам увидеть, сколько раз она вызывалась во время теста. В строке ниже мы используем функцию sinon.fakeServer.create () и назначаем ее переменной. Теперь мы можем дать этому поддельному серверу заранее заданный ответ и убедиться, что наша тестовая заглушка отвечает правильно.
- Теперь, когда у нас есть поддельный сервер, мы можем дать ему заранее запрограммированный ответ для отправки после его вызова. Если наша функция «setup» работает правильно, она будет вызвана и отправит обратно объект JSON после того, как наш поддельный сервер отправит ему запрос GET.
- Наконец, теперь, когда вся наша настройка завершена, мы можем написать фактический тест. Мы можем сделать это точно так же, как и в наших модульных тестах. Сначала мы вызовем 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 (), чтобы начать писать тест. В этом примере я продемонстрирую, как я проверяю, правильно ли отображается список в моем приложении с делами после добавления элемента. Я снова разобью его по шагам:
- Вызовите casper.test.begin, передав строку (имя вашего теста) в качестве первого аргумента, количество утверждений, которые вы планируете использовать в качестве второго аргумента, и, наконец, функцию набора, в которую вы поместите логику для теста.
- Внутри функции вызовите casper.start с URL-адресом и анонимной функцией. Здесь вы разместите остальную логику.
- Шаг 3: Сообщите касперу, что он должен делать перед запуском теста. Думайте об этом как о «призрачном пользователе», который волшебным образом делает что-то определенное с вашим приложением перед запуском теста. В этом случае я хочу заполнить форму «to-do» в моем приложении элементом, который я позже проверю, чтобы убедиться, что он существует. Если это так, то я буду знать, что мое приложение позволяет пользователям успешно добавлять элементы в список дел. Casper позволяет вам делать с вашим приложением очень широкий спектр вещей, помимо заполнения полей поиска перед запуском теста.
- Теперь мы можем написать тест, чтобы убедиться, что этот элемент теперь присутствует в списке дел.
- Все, что вы хотите, чтобы casper сделал после запуска тестов. Почти всегда он просто вызывает test.done ().
Вот и все. Теперь вы можете запустить свой тест и увидеть красивую информацию обо всех выполненных http-запросах, количестве времени, которое потребовалось для этого, и, конечно, о том, прошел ли ваш тест!