Наступает 2019 год, и 2019 год станет годом бессерверных. Популярность Serverless стремительно растет. Однако из-за нехватки ресурсов сложно правильно настроить и протестировать функции. Конечно, есть много статей о том, как начать, но не много для тестирования. Я считаю, что многие из вас уже знают, сколько преимуществ дает TDD. Так что я не буду повторять это здесь. В этой статье я расскажу вам, как настроить облачные функции Firebase и написать для них модульный тест.
Перед тем, как мы начнем
Я предполагаю, что у вас уже есть хотя бы одна функция. В противном случае следуйте этому официальному руководству, чтобы создать новый проект (https://firebase.google.com/docs/functions/get-started).
Начиная
Позвольте мне вкратце объяснить функцию, которую мы собираемся создать.
Я создам триггер для метода user.onCreate. (Вы можете проверить, что это такое, на странице https://firebase.google.com/docs/functions/auth-events). Эта функция триггера сохранит только что аутентифицированного пользователя в нашей базе данных в реальном времени с несколькими необходимыми свойствами для моего простого игрового приложения. . Сначала посмотрите на приведенный ниже код.
Хорошо, ознакомьтесь с подробностями. Во-первых, метод onCreate принимает один параметр - user. Пользователь - это объект, возвращаемый после аутентификации по электронной почте / паролю, анонимной аутентификации, сторонним поставщикам аутентификации и т. Д. Мы можем использовать этот параметр для добавления новых свойств, как указано выше. Когда я делаю игровое приложение, я добавлял такие свойства, как очки и квесты. Затем я вызвал метод admin.database (). Ref (path) .set, чтобы сохранить нашего вновь созданного пользователя в базе данных. (Точно такой же процесс, как и при использовании базы данных с Firebase SDK)
Достаточно просто, правда?
Однако если вы попытаетесь протестировать эти триггерные функции, это станет огромной болью. Потому что сложно настроить клиентские приложения и вручную выполнить итерацию процесса аутентификации. (Нажмите кнопку аутентификации - введите адрес электронной почты / пароль - дождитесь завершения аутентификации - перейдите в консоль и проверьте, сохранен ли наш пользователь или нет)
Написать тест
Вот в чем преимущество автоматизированного тестирования. Вы можете повторять тестирование много раз без этих хлопот. Все, что вам нужно сделать, это просто ввести тестовые команды (тест пряжи) и повторить процесс красный / зеленый. Итак, давайте напишем тест для облачных функций Firebase. Для этого есть несколько примеров кода (https://github.com/firebase/functions-samples/blob/master/quickstarts/uppercase/functions/test/test.offline.js), но в этом примере кода используется Мокко и Чай. Как любитель Jest ( https://jestjs.io/), я хотел использовать Jest для своих тестов.
Хорошо, давайте добавим шутку в ваш проект. Я предпочитаю использовать Typescript для своих проектов, поэтому эта настройка может немного отличаться, если вы используете простой javascript, но большой разницы не будет.
- Добавьте jest.config.js в каталог функций.
2. Создайте каталог __tests__ в src и добавьте базовый тестовый файл.
it("should pass", () => { // meaningless test expect(1).toBe(1); });
3. Загрузите Сервисный ключ из консоли firebase.
Зайдите в настройки и щелкните вкладку учетной записи службы. Вы найдете кнопку создать новый ключ учетной записи ниже. Загрузите этот ключ и включите в свой проект. (Не забудьте включить этот файл в свой файл .gitignore - храните свои секреты в безопасности!)
4. Добавьте тестовую команду в файл package.json.
"scripts": { ...other commands // I prefer to set verbose=false, because it shows console.logs in terminal window. You can remove this flag. "test": "jest --watchAll --verbose=false" },
5. Установите зависимости.
yarn add jest @types/jest firebase-functions-test ts-jest -D
Теперь все готово.
Напишите наш тестовый код для проверки нашей функции триггера.
Поскольку мы собираемся использовать базу данных в реальном времени (сохранить пользователя), нам нужно выйти в Интернет. Нам потребуется указать projectConfig и service-key.json. Если вы следовали моим инструкциям выше, тогда у вас должен быть файл service-key.json в каталоге вашего проекта. Тогда как вы можете проверить projectId и databaseURL?
Для databaseURL перейдите на вкладку базы данных и создайте новую базу данных в реальном времени, тогда вы должны увидеть свой databaseURL в таком виде.
А для projectId перейдите в настройки / common.
Хорошо, давайте напишем еще код.
Ооооо, здесь много чего происходит!
Я объясню код шаг за шагом. Первое, что вы увидите, это блок beforeAll. Я использовал метод jest.spyOn, чтобы заглушить наш метод admin.initializeApp. Затем я загрузил наши функции. (Чтобы предоставить нашему администратору надлежащие учетные данные, вам нужно запретить метод администратора). И в блоке afterAll , мы очищаем настройки.
Чтобы выполнить нашу функцию в правильной среде, мы используем метод wrap testEnv. Сделав это, мы можем вызвать событие создания пользователя в нашем тесте, просто вызвав wrapped (testUser). После вызова мы считываем нашего пользователя из базы данных и проверяем, есть ли у этого пользователя свойство с именем points и его значение равно 0 или нет.
И это все! С этого момента вы можете добавлять другие тесты. Теперь мы закончили тестирование триггеров, не связанных с HTTP. Нам все еще нужно тестировать функции http, однако тестирование функции http не сильно отличается от тестирования триггеров. Все, что вам нужно изменить, это то, что вместо передачи настраиваемого параметра в обернутую функцию вы вместо этого передаете объект req и res.
// code from https://github.com/firebase/functions-samples/blob/master/quickstarts/uppercase/functions/test/test.offline.js const req = { query: {text: 'input'} }; const res = { redirect: (code, url) => { assert.equal(code, 303); assert.equal(url, 'new_ref'); done(); } }; myFunctions.addMessage(req, res);
Тест записи (в автономном режиме)
Есть еще один вариант, который вы можете выбрать при тестировании своих облачных функций. Это «автономный» режим. Этот быстрее (потому что вам не нужно иметь дело с транзакциями базы данных) и его легко написать.
При тестировании в автономном режиме мы должны отключить наш административный SDK, чтобы он не требовал учетных данных. Давайте погрузимся в код!
Как видите, я использовал метод jest.mock. Сначала я объявил наш макет «firebase-admin» (вы должны указать имя модуля в качестве параметра, а не сам объект модуля), а затем дал ему частичную реализацию. (initializeApp и метод базы данных) После этой фиктивной настройки все, что нам нужно проверить, это возвращаемое значение нашей триггерной функции, которое истинно, и параметр, который наш mockSet функция принимает, который будет нашим объектом newUser.
Итак, наш тестовый код должен выглядеть так.
Кажется, что эти издевательские испытания бесполезны. Я просто повторил свою реализацию функции еще раз. Однако это становится очень ценным, когда наша функция становится больше или включает в себя сложную логику if-else. Вы можете легко протестировать каждый случай с помощью этих тестовых тестов. (Это становится особенно ценным, когда вам приходится иметь дело с крайними случаями, которые нелегко проверить вручную)
Тестирование дает большую свободу. Вы можете быстро повторить столько раз, сколько сможете, с помощью автоматизированных тестов. Напишите свой собственный тест и уверенно разверните свои функции! Спасибо, что прочитали мою статью.