Модульный тест и тест интеграции для AWS Lambda / NodeJS в TypeScript
Серия AWS Lambda / NodeJS (TypeScript)
- Как использовать TypeScript для AWS Lambda за 3 шага s
- Модульный тест и тест интеграции для AWS Lambda / NodeJS в TypeScript
Подготовка
Мы собираемся использовать jest
для управления всеми тестами. Чтобы использовать jest
с TypeScript, нам нужно будет установить некоторые babel
зависимости. Пожалуйста, проверьте команды установки ниже:
// install jest and types $ npm i -D jest @types/jest // install babel support to use jest with typescript $ npm i -D babel-jest @babel/core @babel/preset-env @babel/preset-typescript
Мы устанавливаем их в dev-dependencies
, потому что они используются только во время тестирования, а не в окончательном собранном пакете. После установки нам нужно создать babel.config.js
в, чтобы Babel работал. Содержание файла:
module.exports = { presets: [ ['@babel/preset-env', {targets: {node: 'current'}}], '@babel/preset-typescript', ], };
Теперь файловая структура выглядит так:
. ├── README.md ├── hello-world │ ├── babel.config.js │ ├── package-lock.json │ ├── package.json │ ├── src-ts │ └── tsconfig.json ├── samconfig.toml └── template.yaml
Модульный тест
Чтобы использовать jest
, лучше всего иметь файл конфигурации, мы можем сгенерировать файл с jest cli
:
// pwd: $ROOT/hello-world $ ./node_modules/.bin/jest init // generate jest.config.js $ mv jest.config.js jest.config.test.js // rename
В сгенерированном jest.config.test.js
нам потребуются следующие параметры:
module.exports = { clearMocks: false, collectCoverage: true, coverageDirectory: "coverage", coverageProvider: "v8", testEnvironment: "node", testMatch: [ "**/unit/**/*.test.ts" ], };
Затем давайте создадим наш первый файл модульного теста hello-world/tests/unit/test-handler.test.ts
. Далее мы могли заполнить файл модульным тестом для обработчика приложения, созданного в прошлой статье.
import { APIGatewayProxyEvent } from "aws-lambda"; import { lambdaHandler } from "../../src-ts/app"; describe('Unit test for app handler', function () { it('verifies successful response', async () => { const event: APIGatewayProxyEvent = { queryStringParameters: { a: "1" } } as any const result = await lambdaHandler(event) expect(result.statusCode).toEqual(200); expect(result.body).toEqual(`Queries: ${JSON.stringify(event.queryStringParameters)}`); }); });
Добавьте новую команду в package.json
, чтобы мы могли легко запустить модульный тест:
"scripts": { "test": "jest --config=jest.config.test.js", "compile": "tsc" }
Теперь у нас должна быть возможность запустить модульный тест и увидеть отчет о покрытии:
Выглядит отлично! Теперь файловая структура выглядит так:
. ├── README.md ├── hello-world │ ├── babel.config.js │ ├── jest.config.test.js │ ├── package-lock.json │ ├── package.json │ ├── src-ts │ ├── tests │ │ └── unit │ │ └── test-handler.test.ts ├── samconfig.toml └── template.yaml
Интеграционный тест
Чтобы отличить интеграционный тест от модульного, нам понадобится другой файл конфигурации jest, а именно jest.confg.integ.test.js
с содержимым:
// no need for coverage here module.exports = { testEnvironment: "node", testMatch: [ "**/integ/**/*.integ.test.ts" ], };
Для запуска интеграционного теста нам потребуются еще две вещи:
- Локальный сервер, на котором работает наша лямбда
- Пакет HTTP SDK для отправки запроса на локальный сервер
Запустите лямбду на локальном сервере
К счастью, AWS SAM CLI предоставляет возможность запускать стек локально с помощью этой команды:
// pwd: $ROOT/hello-world $ sam local start-api -t ../template.yaml
Эта команда требует установки Docker
, вы можете обратиться к этому документу для получения дополнительной информации. После выполнения он вызовет сервер, прослушивающий 127.0.0.1:3000
.
Лучше добавить эту команду и в скрипты NPM:
"scripts": { "test": "jest --config=jest.config.test.js", "start-local": "sam local start-api -t ../template.yaml", "compile": "tsc" },
Добавить HTTP SDK в проект
Мы бы выбрали Axios
для отправки запроса на сервер, запущенный выше:
$ npm i -D axios @types/axios
Создайте файл интеграционного теста hello-world/tests/integ/handler.integ.test.ts
с содержанием:
import axios from "axios"; describe("Integration Test", () => { it("hello world integration test", async () => { const query = { a: "hi" }; const response = await axios.get("http://localhost:3000/hello", { params: query }); expect(response.status).toEqual(200); expect(response.data).toEqual(`Queries: ${JSON.stringify(query)}`); }); });
В этом интеграционном тесте мы используем axios
для отправки GET
сообщения серверу, запущенному выше. Более того, мы используем async
и await
, чтобы код теста оставался простым и читаемым.
Снова добавьте команду выполнения для интеграционного теста в package.json
:
"scripts": { "test": "jest --config=jest.config.test.js", "integ-test": "jest --config=jest.config.integ.test.js", "start-local": "sam local start-api -t ../template.yaml", "compile": "tsc" }
Запустите интеграционный тест
Нам нужны две консоли для интеграционного теста, одна для сервера, другая для запуска интеграционного теста. Взгляните на результат бега:
Окончательная файловая структура:
. ├── README.md ├── hello-world │ ├── babel.config.js │ ├── jest.config.integ.test.js │ ├── jest.config.test.js │ ├── package-lock.json │ ├── package.json │ ├── src-ts │ │ └── app.ts │ ├── tests │ │ ├── integ │ │ │ └── handler.integ.test.ts │ │ └── unit │ │ └── test-handler.test.ts │ └── tsconfig.json ├── samconfig.toml └── template.yaml
Заключение
Потрясающие! Теперь мы можем не только писать обработчики лямбда-выражений в TypeScript, но и составлять модульные / интеграционные тесты с помощью TypeScript. Полный код можно найти по адресу: https://github.com/zijing07/aws-lambda-nodejs-ts.
В следующей статье я расскажу, как создавать модульные / интеграционные тесты с помощью DDB в AWS Lambda.