SlideShare a Scribd company logo
Mocha 
Покрой свой фронт-енд по полной
О себе 
Владислав Безверхий, web-developer, A2 Design 
Интересуюсь IT с 2005 года 
Пишу всякие штуки для себя с 2009 года 
Работаю в IT с 2012 года 
Увлекаюсь музыкой, играювожу D&D. Люблю маму, папу, фракталы, 
парадоксы и функциональное программирование.
Жизнь без тестов 
● Нельзя с уверенностью сказать что код работает. 
● Каждая новая фича - беда для разработчика 
● Боишься регрессий как огня 
● При удачном стечении обстоятельств может сломаться production и 
разбиться сердце заказчика  product owner’а
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
Решение? 
● соблюдение принципов разработки (например 
KISS/DRY) 
● Модульное тестирование (Unit tests) 
● Функциональное тестирование 
● соблюдение code-styles 
● применение методологии разработки
А что с фронт-ендом? 
● Зависимость от сервера 
● Зависимость от браузера 
● DOM дерево - не всегда твой друг 
● Иногда бывает callback hell 
● Можно ловкой глобальной переменной 
сломать всё
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
Что из этого можно решить с 
помощью Unit-тестов? 
● Зависимость от сервера - mock объекты 
● Зависимость от браузера - можно прогонять тесты в 
разных браузерах. 
● Операции над DOM деревом можно тестировать 
● Сallback hell - с помощью spy функций 
● Глобальная переменная быстро проявит себя в 
хорошо написанных тестах
Средства тестирования 
Jasmine JS 
● полная поддержка BDD 
● methods chaining 
● написана в первую очередь для браузера 
● имеются пакеты для python и ruby 
● дружит с Sinon
Средства тестирования 
Mocha js 
● Поддерживает BDD и TDD 
● Написана с поддержкой браузера и Node JS 
● Возможность подключать разные библиотеки для asserts 
● Дружит с Sinon и Chai
Toolkit 
● Mocha 
● Chai 
● Sinon
Toolkit 
● Mocha - запускает тесты 
● Chai - предоставляет API 
● Sinon - mock объекты
Подключение 
> npm install mocha 
> npm install chai 
> npm install sinon
Подключаем в браузер (Mocha + Chai) 
<head> 
<title>Express Tests</title> 
<link rel="stylesheet" href="/stylesheets/tests/mocha. 
css"> 
<script src="/javascripts/mocha.js"></script> 
<script src="/javascripts/chai.js"></script> 
<script src=”/javascripts/chai.js”></script> 
</head>
Пишем первый тест 
var should = chai.expect; 
describe('Array', function() { 
describe('#indexOf()', function(){ 
it('should return -1 when the value is not present', function(){ 
should([1, 3, 4].indexOf(5)).equal(-1); 
should([1, 3, 4].indexOf(0)).equal(-1); 
}); 
}); 
});
Тестируем свой код 
var MapHandler = function() { 
var self = this; 
self.squareSide = 0.11; 
self.init(); 
}; 
MapHandler.prototype.coordsPolynome = function(x) { 
x = Math.abs(x); 
return 1.75477 * Math.pow(10, -6) * Math.pow(x, 3) -0.000365418 
* Math.pow(x, 2) + 0.00845663 * x + 0.954619;// 
};
Тестируем свой код 
describe('coordsPolynome', function() { 
it('should be clear', function() { 
assert.equal(MapHandler.coordsPolynome(50),MapHandler.coordsPolynome(50)); 
assert.equal(MapHandler.coordsPolynome(-10),MapHandler.coordsPolynome(10)); 
}); 
});
Запускаем тесты 
<script> 
mocha.setup('bdd'); 
mocha.bail(false); 
mocha.run(); 
</script> 
</body>
2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной
А что еще дает нам chai?
Chai plugins 
● Для фреймворков 
● Для jQuery 
● Для всевозможных изменений (DOM, 
promises etc.) 
● Можно писать свои - есть API
Немного о Sinon 
● Function Spies 
● Stubs 
● Fake Ajax 
● Fake XMLHttpRequest 
● Fake Server 
● Faking Time
Sinon - simplify your testing 
● Framework- agnostic (поддерживает 
Jasmine, Mocha) 
● Нет зависимостей 
● Можно использовать как на сервере так и 
в браузере
Sinon Spies 
Проблемы: 
● Отслеживание вызовов callback’ов 
● Отслеживание контекста внутри callback’ов 
● Отслеживание переменных переданных в callback 
● Отслеживание влияния callback’а на внешний scope
function once(fn) { 
var returnValue, called = false; 
return function () { 
if (!called) { 
called = true; 
returnValue = fn.apply(this, arguments); 
} 
return returnValue; 
}; 
}
it("calls the original function", function () { 
var callback = sinon.spy(); 
var proxy = once(callback); 
proxy(); 
assert(callback.called); 
});
it("calls the original function only once", function () { 
var callback = sinon.spy(); 
var proxy = once(callback); 
proxy(); 
proxy(); 
assert(callback.calledOnce); 
// ...or: 
// assert.equals(callback.callCount, 1); 
});
it("calls original function with right this and args", function() 
{ 
var callback = sinon.spy(); 
var proxy = once(callback); 
var obj = {}; 
proxy.call(obj, 1, 2, 3); 
assert(callback.calledOn(obj)); 
assert(callback.calledWith(1, 2, 3)); 
});
Sinon - Mocks 
● Тестируемая функция зависит от какого 
либо внешнего API (например 
фреймворка) 
● Тестируема функция зависит от внешнего 
объекта
it("returns the return value from the original function", 
function () { 
var myAPI = { method: function () {} }; 
var mock = sinon.mock(myAPI); 
mock.expects("method").once().returns(42); 
var proxy = once(myAPI.method); 
assert.equals(proxy(), 42); 
mock.verify(); 
});
Sinon - Stubs 
Проблемы: 
● Вызов функций за пределами теста 
● Дублирование тестов 
● Результат вызываемой функции зависит 
от временивнешних условий 
● Функция является замыканием
it("returns the return value from the original function", 
function () { 
var stub = sinon.stub().returns(42); 
var proxy = once(stub); 
assert.equals(proxy(), 42); 
});
Sinon - Fake XHR 
Проблемы: 
● Время отклика замедляет тестирование 
● Сервер может быть не всегда доступен 
● Запрос формируется динамически 
● Выполнение запроса повлечет изменение 
данных на сервере
var xhr, requests; 
before(function() { 
xhr = sinon.useFakeXMLHttpRequest(); 
requests = []; 
xhr.onCreate = function (req) { requests.push(req); }; 
}); 
after(function() { 
// Like before we must clean up when tampering with globals. 
xhr.restore(); 
});
it("makes a GET request for todo items", function () { 
getSomething(42, sinon.spy()); 
assert.equal(requests.length, 1); 
assert.equal(requests[0].url, "/something/42"); 
});
Sinon (Fake Server) - testing 
Проблемы: 
● Недоступностьотсутствие сервера 
● Время отклика 
● Несоответствие API сервера текущей 
спецификации 
● Запросы влияют на данные сервера
var server; 
beforeEach(function () { server = sinon.fakeServer.create(); }); 
afterEach(function () { server.restore(); });
it("returns ok", function() { 
var callback = sinon.spy(); 
getSomething(42, callback); 
// This is part of the FakeXMLHttpRequest API 
server.requests[0].respond( 
200, 
{ "Content-Type": "application/json" }, 
JSON.stringify([{ id: 1, text: "Provide examples", done: 
true }]) 
); 
assert.equal(200, server.requests[0].status); 
})
it("calls callback with deserialized data", function () { 
var callback = sinon.spy(); 
getTodos(42, callback); 
// This is part of the FakeXMLHttpRequest API 
server.requests[0].respond( 
200, 
{ "Content-Type": "application/json" }, 
JSON.stringify([{ id: 1, text: "Provide examples", done: 
true }]) 
); 
assert(callback.calledOnce); 
});
Sinon (Timers) - prepare 
Проблемы: 
● Может сильно замедлить прохождение 
тестов 
● Изменение состояния объектов в рамках 
setInterval 
● Очень не удобно отлаживать
function throttle(callback) { 
var timer; 
return function () { 
clearTimeout(timer); 
var args = [].slice.call(arguments); 
timer = setTimeout(function () { 
callback.apply(this, args); 
}, 100); 
}; 
}
var clock; 
before(function () { clock = sinon.useFakeTimers(); }); 
after(function () { clock.restore(); });
it("calls callback after 100ms", function () { 
var callback = sinon.spy(); 
var throttled = throttle(callback); 
throttled(); 
clock.tick(99); 
assert(callback.notCalled); 
clock.tick(1); 
assert(callback.calledOnce); 
assert.equal(new Date().getTime(), 100); 
}
Смотреть тесты фронтенда в 
консоли? 
> npm install mocha-phantomjs
Смотреть тесты фронтенда в 
консоли? 
<script> 
if (window.mochaPhantomJS) { mochaPhantomJS.run(); } 
else { mocha.run(); } 
</script>
Смотреть тесты фронтенда в 
консоли? 
<script> 
if (window.mochaPhantomJS) { mochaPhantomJS.run(); } 
else { mocha.run(); } 
</script> 
$ mocha-phantomjs -R dot /test/file.html 
$ mocha-phantomjs http://testserver.com/file.html 
> npm install mocha-phantomjs 
$ mocha-phantomjs -s localToRemoteUrlAccessEnabled=true -s webSecurityEnabled=false 
http://testserver.com/file.html 
$ mocha-phantomjs -p ~/bin/phantomjs /test/file.html
Спасибо за внимание 
@rabbiabram

More Related Content

PDF
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
PDF
Инструментируй это
PDF
Component Inspector
PDF
Автоматизация функционального тестирования REST API
PDF
Контроль качества верстки или как начать делать Makeup
PDF
Цена ошибки
PDF
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
PDF
Parallel STL
Как сделать ваш JavaScript быстрее / Роман Дворнов (Авито)
Инструментируй это
Component Inspector
Автоматизация функционального тестирования REST API
Контроль качества верстки или как начать делать Makeup
Цена ошибки
Ангелы и демоны многопоточного программирования / Алексей Федоров (Одноклассн...
Parallel STL

What's hot (20)

PPT
Alexander manuhin selenium_php_v2.0
PDF
Борис Сазонов, RAII потоки и CancellationToken в C++
PDF
Использование юнит-тестов для повышения качества разработки
PPT
бегун
PPTX
Улучшение качества открытого программного обеспечения с помощью инструментов ...
PPTX
Selenium: начало работы
PDF
2013 09 19 кеширование на клиенте и сервере
PPTX
Tdd webpack + testem + mocha + chai
PDF
Для чего мы делали свой акторный фреймворк и что из этого вышло?
PDF
Павел Довгалюк, Обратная отладка
PDF
JPoint 2016 - Etudes of DIY Java profiler
PPTX
Асинхронность и сопрограммы
PPTX
Система обработки бизнес-логики server-side приложения на Groovy
PDF
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
PPTX
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
PPTX
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
PDF
Григорий Демченко — Асинхронное программирование и сопрограммы
PDF
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья Стусь
PDF
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
PPTX
Основы и применение статического анализа кода при разработке лекция 1
Alexander manuhin selenium_php_v2.0
Борис Сазонов, RAII потоки и CancellationToken в C++
Использование юнит-тестов для повышения качества разработки
бегун
Улучшение качества открытого программного обеспечения с помощью инструментов ...
Selenium: начало работы
2013 09 19 кеширование на клиенте и сервере
Tdd webpack + testem + mocha + chai
Для чего мы делали свой акторный фреймворк и что из этого вышло?
Павел Довгалюк, Обратная отладка
JPoint 2016 - Etudes of DIY Java profiler
Асинхронность и сопрограммы
Система обработки бизнес-логики server-side приложения на Groovy
Юлия Ковалёва. Fscheck — альтернативный путь для unit тестов
Примеры быстрой разработки API на масштабируемом сервере приложений Impress д...
Сергей Шамбир, Адаптация Promise/A+ для взаимодействия между C++ и Javascript
Григорий Демченко — Асинхронное программирование и сопрограммы
Полный цикл тестирования React-приложений, Алексей Андросов и Наталья Стусь
Полухин Антон, Как делать не надо: C++ велосипедостроение для профессионалов
Основы и применение статического анализа кода при разработке лекция 1
Ad

Viewers also liked (16)

PDF
Арсений Заречнев и Федор Шумов - Одностраничные приложения
ODP
Security zap and selenium
PDF
обзор средств для тестирования Java script
PDF
автоматизированное тестирование. С чего начать Part2
PDF
Фвтоматизированное тестирование с чего начать Part1
PDF
грабли автоматизации тестирования мобильного веба с помощью Selenium 2
PDF
Доклад Виталия Котова на конференции LoveQA. "Selenium тесты. От RC и одного ...
PDF
Yandex experience-in-screenshot-based-testing-seleniumcamp-2014
PPTX
XPath локаторы в Selenium WebDriver
PPTX
Tao and Test Automation
PPTX
автоматизация тестирования с помощью Selenium
PPTX
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
PDF
Winium — это как Selenium, только под Windows
PPTX
The Dangers of Cucumber
PPTX
Webium: Page Objects in Python
PPTX
Багфиксинг процесса разработки в iOS: взгляд с двух сторон
Арсений Заречнев и Федор Шумов - Одностраничные приложения
Security zap and selenium
обзор средств для тестирования Java script
автоматизированное тестирование. С чего начать Part2
Фвтоматизированное тестирование с чего начать Part1
грабли автоматизации тестирования мобильного веба с помощью Selenium 2
Доклад Виталия Котова на конференции LoveQA. "Selenium тесты. От RC и одного ...
Yandex experience-in-screenshot-based-testing-seleniumcamp-2014
XPath локаторы в Selenium WebDriver
Tao and Test Automation
автоматизация тестирования с помощью Selenium
Автоматизация для ленивых тестировщиков. Selenium + Python + Behave (BDD)
Winium — это как Selenium, только под Windows
The Dangers of Cucumber
Webium: Page Objects in Python
Багфиксинг процесса разработки в iOS: взгляд с двух сторон
Ad

Similar to 2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной (20)

PPTX
Node.js введение в технологию, КПИ #ITmeetingKPI
PDF
М. Боднарчук Современное функциональное тестирование с Codeception
PPTX
Михаил Боднарчук Современное функциональное тестирование с Codeception
PPT
бегун
PPTX
PowerShell
PDF
Lift, play, akka, rails part1
PDF
Performance optimisation in javascript
PDF
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
PDF
Как выглядит современный фронтенд
PPTX
Типичные ошибки начинающих писать тесты на WebDriver
PDF
Стабы для фронтенда - Никита Мостовой (HeadHunter)
PDF
Erlang tasty & useful stuff
PPTX
разработка бизнес приложений (8)
PPT
Easy authcache 2 кэширование для pro. Родионов Игорь
PPT
Easy authcache 2 кеширование для pro родионов игорь
PDF
Семь тысяч Rps, один go
PPT
PHP Tricks
PPTX
Codeception Introduction
PDF
Веб-разработка без наркотиков с помощью PostgreSQL, Nginx и c2h5oh / Миша Кир...
PDF
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...
Node.js введение в технологию, КПИ #ITmeetingKPI
М. Боднарчук Современное функциональное тестирование с Codeception
Михаил Боднарчук Современное функциональное тестирование с Codeception
бегун
PowerShell
Lift, play, akka, rails part1
Performance optimisation in javascript
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Как выглядит современный фронтенд
Типичные ошибки начинающих писать тесты на WebDriver
Стабы для фронтенда - Никита Мостовой (HeadHunter)
Erlang tasty & useful stuff
разработка бизнес приложений (8)
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2 кеширование для pro родионов игорь
Семь тысяч Rps, один go
PHP Tricks
Codeception Introduction
Веб-разработка без наркотиков с помощью PostgreSQL, Nginx и c2h5oh / Миша Кир...
Подходы и технологии, используемые в разработке iOS-клиента Viber, Кирилл Лаш...

More from Омские ИТ-субботники (20)

PDF
2017-08-12 01 Алексей Коровянский. Привет, ARKit!
PDF
2017-08-12 02 Антон Ковалев. Texture a.k.a AsyncDisplayKit
PDF
2017-05-06 02 Илья Сиганов. Зачем учить машины?
PDF
2017 04-08 03 Максим Верзаков. Docker — жизнь, вселенная и все остальное
PDF
2017-04-08 01 Евгений Оськин. Video streaming: от идеи до нагруженной системы
PDF
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
PDF
2017-03-11 01 Игорь Родионов. Docker swarm vs Kubernetes
PDF
2017-02-04 03 Алексей Букуров, Игорь Циглер. DSL для правил валидации
PDF
2017-02-04 02 Яков Лило. Решение задач
PDF
2017-02-04 01 Евгений Тюменцев. Выразительные возможности языков программиро...
PDF
2016-12-03 01 Вадим Литвинов. От 2D к 3D обзор методов реконструкции поверхно...
PDF
2016-12-03 02 Алексей Городецкий. Как пишут компиляторы
PDF
2016-12-03 03 Евгений Тюменцев. DSL на коленке
PDF
2016-11-12 02 Николай Линкер. Чему Java может поучиться у Haskell и наоборот
PDF
2016-11-12 03 Максим Дроздов. Навести порядок быстро, или как спасти оценки н...
PDF
2016-11-12 01 Егор Непомнящих. Агрегация и осведомленность
PDF
2016-10-01 03 Андрей Аржанников. Что такое Bluetooth Low Energy?
PDF
2016-10-01 02 Евгений Комаров. Как я сделал IoT-кикер
PDF
2016-10-01 01 Звиад Кардава. Welcome to Internet of Things
PDF
2016-09-17 03 Василий Полозов. WebRTC
2017-08-12 01 Алексей Коровянский. Привет, ARKit!
2017-08-12 02 Антон Ковалев. Texture a.k.a AsyncDisplayKit
2017-05-06 02 Илья Сиганов. Зачем учить машины?
2017 04-08 03 Максим Верзаков. Docker — жизнь, вселенная и все остальное
2017-04-08 01 Евгений Оськин. Video streaming: от идеи до нагруженной системы
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 01 Игорь Родионов. Docker swarm vs Kubernetes
2017-02-04 03 Алексей Букуров, Игорь Циглер. DSL для правил валидации
2017-02-04 02 Яков Лило. Решение задач
2017-02-04 01 Евгений Тюменцев. Выразительные возможности языков программиро...
2016-12-03 01 Вадим Литвинов. От 2D к 3D обзор методов реконструкции поверхно...
2016-12-03 02 Алексей Городецкий. Как пишут компиляторы
2016-12-03 03 Евгений Тюменцев. DSL на коленке
2016-11-12 02 Николай Линкер. Чему Java может поучиться у Haskell и наоборот
2016-11-12 03 Максим Дроздов. Навести порядок быстро, или как спасти оценки н...
2016-11-12 01 Егор Непомнящих. Агрегация и осведомленность
2016-10-01 03 Андрей Аржанников. Что такое Bluetooth Low Energy?
2016-10-01 02 Евгений Комаров. Как я сделал IoT-кикер
2016-10-01 01 Звиад Кардава. Welcome to Internet of Things
2016-09-17 03 Василий Полозов. WebRTC

2014-10-04 02 Владислав Безверхий. Mocha - покрой frontend по полной

  • 1. Mocha Покрой свой фронт-енд по полной
  • 2. О себе Владислав Безверхий, web-developer, A2 Design Интересуюсь IT с 2005 года Пишу всякие штуки для себя с 2009 года Работаю в IT с 2012 года Увлекаюсь музыкой, играювожу D&D. Люблю маму, папу, фракталы, парадоксы и функциональное программирование.
  • 3. Жизнь без тестов ● Нельзя с уверенностью сказать что код работает. ● Каждая новая фича - беда для разработчика ● Боишься регрессий как огня ● При удачном стечении обстоятельств может сломаться production и разбиться сердце заказчика product owner’а
  • 5. Решение? ● соблюдение принципов разработки (например KISS/DRY) ● Модульное тестирование (Unit tests) ● Функциональное тестирование ● соблюдение code-styles ● применение методологии разработки
  • 6. А что с фронт-ендом? ● Зависимость от сервера ● Зависимость от браузера ● DOM дерево - не всегда твой друг ● Иногда бывает callback hell ● Можно ловкой глобальной переменной сломать всё
  • 8. Что из этого можно решить с помощью Unit-тестов? ● Зависимость от сервера - mock объекты ● Зависимость от браузера - можно прогонять тесты в разных браузерах. ● Операции над DOM деревом можно тестировать ● Сallback hell - с помощью spy функций ● Глобальная переменная быстро проявит себя в хорошо написанных тестах
  • 9. Средства тестирования Jasmine JS ● полная поддержка BDD ● methods chaining ● написана в первую очередь для браузера ● имеются пакеты для python и ruby ● дружит с Sinon
  • 10. Средства тестирования Mocha js ● Поддерживает BDD и TDD ● Написана с поддержкой браузера и Node JS ● Возможность подключать разные библиотеки для asserts ● Дружит с Sinon и Chai
  • 11. Toolkit ● Mocha ● Chai ● Sinon
  • 12. Toolkit ● Mocha - запускает тесты ● Chai - предоставляет API ● Sinon - mock объекты
  • 13. Подключение > npm install mocha > npm install chai > npm install sinon
  • 14. Подключаем в браузер (Mocha + Chai) <head> <title>Express Tests</title> <link rel="stylesheet" href="/stylesheets/tests/mocha. css"> <script src="/javascripts/mocha.js"></script> <script src="/javascripts/chai.js"></script> <script src=”/javascripts/chai.js”></script> </head>
  • 15. Пишем первый тест var should = chai.expect; describe('Array', function() { describe('#indexOf()', function(){ it('should return -1 when the value is not present', function(){ should([1, 3, 4].indexOf(5)).equal(-1); should([1, 3, 4].indexOf(0)).equal(-1); }); }); });
  • 16. Тестируем свой код var MapHandler = function() { var self = this; self.squareSide = 0.11; self.init(); }; MapHandler.prototype.coordsPolynome = function(x) { x = Math.abs(x); return 1.75477 * Math.pow(10, -6) * Math.pow(x, 3) -0.000365418 * Math.pow(x, 2) + 0.00845663 * x + 0.954619;// };
  • 17. Тестируем свой код describe('coordsPolynome', function() { it('should be clear', function() { assert.equal(MapHandler.coordsPolynome(50),MapHandler.coordsPolynome(50)); assert.equal(MapHandler.coordsPolynome(-10),MapHandler.coordsPolynome(10)); }); });
  • 18. Запускаем тесты <script> mocha.setup('bdd'); mocha.bail(false); mocha.run(); </script> </body>
  • 20. А что еще дает нам chai?
  • 21. Chai plugins ● Для фреймворков ● Для jQuery ● Для всевозможных изменений (DOM, promises etc.) ● Можно писать свои - есть API
  • 22. Немного о Sinon ● Function Spies ● Stubs ● Fake Ajax ● Fake XMLHttpRequest ● Fake Server ● Faking Time
  • 23. Sinon - simplify your testing ● Framework- agnostic (поддерживает Jasmine, Mocha) ● Нет зависимостей ● Можно использовать как на сервере так и в браузере
  • 24. Sinon Spies Проблемы: ● Отслеживание вызовов callback’ов ● Отслеживание контекста внутри callback’ов ● Отслеживание переменных переданных в callback ● Отслеживание влияния callback’а на внешний scope
  • 25. function once(fn) { var returnValue, called = false; return function () { if (!called) { called = true; returnValue = fn.apply(this, arguments); } return returnValue; }; }
  • 26. it("calls the original function", function () { var callback = sinon.spy(); var proxy = once(callback); proxy(); assert(callback.called); });
  • 27. it("calls the original function only once", function () { var callback = sinon.spy(); var proxy = once(callback); proxy(); proxy(); assert(callback.calledOnce); // ...or: // assert.equals(callback.callCount, 1); });
  • 28. it("calls original function with right this and args", function() { var callback = sinon.spy(); var proxy = once(callback); var obj = {}; proxy.call(obj, 1, 2, 3); assert(callback.calledOn(obj)); assert(callback.calledWith(1, 2, 3)); });
  • 29. Sinon - Mocks ● Тестируемая функция зависит от какого либо внешнего API (например фреймворка) ● Тестируема функция зависит от внешнего объекта
  • 30. it("returns the return value from the original function", function () { var myAPI = { method: function () {} }; var mock = sinon.mock(myAPI); mock.expects("method").once().returns(42); var proxy = once(myAPI.method); assert.equals(proxy(), 42); mock.verify(); });
  • 31. Sinon - Stubs Проблемы: ● Вызов функций за пределами теста ● Дублирование тестов ● Результат вызываемой функции зависит от временивнешних условий ● Функция является замыканием
  • 32. it("returns the return value from the original function", function () { var stub = sinon.stub().returns(42); var proxy = once(stub); assert.equals(proxy(), 42); });
  • 33. Sinon - Fake XHR Проблемы: ● Время отклика замедляет тестирование ● Сервер может быть не всегда доступен ● Запрос формируется динамически ● Выполнение запроса повлечет изменение данных на сервере
  • 34. var xhr, requests; before(function() { xhr = sinon.useFakeXMLHttpRequest(); requests = []; xhr.onCreate = function (req) { requests.push(req); }; }); after(function() { // Like before we must clean up when tampering with globals. xhr.restore(); });
  • 35. it("makes a GET request for todo items", function () { getSomething(42, sinon.spy()); assert.equal(requests.length, 1); assert.equal(requests[0].url, "/something/42"); });
  • 36. Sinon (Fake Server) - testing Проблемы: ● Недоступностьотсутствие сервера ● Время отклика ● Несоответствие API сервера текущей спецификации ● Запросы влияют на данные сервера
  • 37. var server; beforeEach(function () { server = sinon.fakeServer.create(); }); afterEach(function () { server.restore(); });
  • 38. it("returns ok", function() { var callback = sinon.spy(); getSomething(42, callback); // This is part of the FakeXMLHttpRequest API server.requests[0].respond( 200, { "Content-Type": "application/json" }, JSON.stringify([{ id: 1, text: "Provide examples", done: true }]) ); assert.equal(200, server.requests[0].status); })
  • 39. it("calls callback with deserialized data", function () { var callback = sinon.spy(); getTodos(42, callback); // This is part of the FakeXMLHttpRequest API server.requests[0].respond( 200, { "Content-Type": "application/json" }, JSON.stringify([{ id: 1, text: "Provide examples", done: true }]) ); assert(callback.calledOnce); });
  • 40. Sinon (Timers) - prepare Проблемы: ● Может сильно замедлить прохождение тестов ● Изменение состояния объектов в рамках setInterval ● Очень не удобно отлаживать
  • 41. function throttle(callback) { var timer; return function () { clearTimeout(timer); var args = [].slice.call(arguments); timer = setTimeout(function () { callback.apply(this, args); }, 100); }; }
  • 42. var clock; before(function () { clock = sinon.useFakeTimers(); }); after(function () { clock.restore(); });
  • 43. it("calls callback after 100ms", function () { var callback = sinon.spy(); var throttled = throttle(callback); throttled(); clock.tick(99); assert(callback.notCalled); clock.tick(1); assert(callback.calledOnce); assert.equal(new Date().getTime(), 100); }
  • 44. Смотреть тесты фронтенда в консоли? > npm install mocha-phantomjs
  • 45. Смотреть тесты фронтенда в консоли? <script> if (window.mochaPhantomJS) { mochaPhantomJS.run(); } else { mocha.run(); } </script>
  • 46. Смотреть тесты фронтенда в консоли? <script> if (window.mochaPhantomJS) { mochaPhantomJS.run(); } else { mocha.run(); } </script> $ mocha-phantomjs -R dot /test/file.html $ mocha-phantomjs http://testserver.com/file.html > npm install mocha-phantomjs $ mocha-phantomjs -s localToRemoteUrlAccessEnabled=true -s webSecurityEnabled=false http://testserver.com/file.html $ mocha-phantomjs -p ~/bin/phantomjs /test/file.html