Jasmine и аналогичные среды тестирования, такие как Mocha или Jest, чаще всего используются для модульного тестирования, хотя их также можно использовать для функциональных тестов, и в этой статье показано, как тесты могут охватывать несколько компонентов продукта.
При работе над проектом Topee одной из самых важных и сложных частей был обмен сообщениями, когда внутристраничные скрипты обменивались сообщениями с фоновым скриптом и ретранслировали эти сообщения для фреймов, которые не могут общаться напрямую.
Тестирование всех частей по отдельности не обязательно означает, что сообщения и ответы будут передаваться между компонентами. В идеале тесты должны убедиться, что сообщение из iframe проходит через родительскую страницу и в конце достигает фона.
Первая попытка содержала несколько автоматических ответов и удаленный вызов функций, но ее было сложно использовать, она не масштабировалась по количеству тестов и не допускала сложной логики во всех компонентах.
Выяснилось, что хороший двухкомпонентный тест должен выглядеть так:
(компонент страницы)
describe('message from page', function () { it('reaches background', async function () { let response = performOnBackground(); sendMessage('test message'); expect(await response).toBe('message arrived'); }); });
(фоновый компонент)
describe('message from page', function () { body('reaches background', async function () { const msg = await messageListener.once('test message'); return msg === 'test message' ? 'message arrived' : 'error'; }); });
Одна из проблем заключалась в том, как сообщить performOnBackground, какой тест выполняется в данный момент, чтобы он мог найти соответствующее тело без дополнительных идентификаторов. Это можно решить, добавив дополнительный пользовательский репортер (репортеры обычно форматируют и выводят результаты теста):
jasmine.getEnv().addReporter({ specStarted: function (desc) { markCurrentItName(desc); }, suiteStarted: function (desc) { markCurrentDescribeName(desc); }, ... });
Затем performOnBackground может просто опубликовать набор и имена тестов и дождаться результата выполнения. Фреймворк выполнения в фоновом режиме или другие компоненты — это вопрос нескольких строк, которые регистрируют тестовые тела:
function describe(suiteName, suiteBody) { tests[suiteName] = {}; currentSuite = tests[suiteName]; suiteBody(); } function body(testName, testBody) { currentSuite[testName] = testBody; } function onRunTestCallback(descriptor, sendResponse) { var result = tests[descriptor.suiteName][descriptor.testName](); if (result && typeof result.then === 'function') { result.then(sendResponse); } else { sendResponse(result); } }
И в этом почти весь трюк. Тесты, написанные в таком стиле, позволяли за считанные минуты находить и исправлять некогда загадочные ошибки и предотвращали регрессии. Полный код доступен на github.
Первоначально опубликовано на сайте pavelstudeny.wordpress.com 6 декабря 2018 г.