Руководство по написанию тестов в полнофункциональном веб-приложении MERN

Руководство по написанию тестов в полнофункциональном веб-приложении MERN

11 ноября 2022 г.

Только написав тесты, вы сможете понять важность тестирования. Насколько я знаю, никакие учебные курсы или курсы по кодированию не учат писать тесты. Написание тестов может не понадобиться для демонстрационных проектов или курсовых работ, но это необходимо для реальных приложений. Итак, в этой Части 3 " Давайте создадим и развернем полнофункциональное веб-приложение MERN», в котором я покажу, как писать тесты для компонентов ReactJs и RESTAPI ExpressJs.

Начнем

Что такое тестирование?

На этапе тестирования разработки программного обеспечения фактические результаты приложения сравниваются с ожидаемыми. Этот этап используется перед развертыванием приложения, чтобы убедиться, что все работает должным образом. Начинающие разработчики часто считают, что написание тестов — это трудоемкий и неважный процесс. Но они игнорируют тот факт, что тестирование на самом деле дает вам много времени в долгосрочной перспективе. Вы можете думать о тестировании как о единовременной инвестиции.

При разработке программного обеспечения используются различные методы тестирования, включая модульное тестирование, интеграционное тестирование, бета-тестирование, регрессионное тестирование и другие. В этом уроке мы узнаем о модульном тестировании и о том, как создавать тесты для приложений, созданных с помощью ReactJ и NodeJ.

Что такое модульное тестирование?

Как следует из названия, модульное тестирование включает тестирование отдельных фрагментов кода или приложения. Например, в REST API мы можем создавать отдельные тесты для каждой конечной точки, а в приложении ReactJs мы можем тестировать каждый компонент отдельно.

Давайте начнем создавать тесты для нашего приложения "Productivity Tracker". (Если вы не знаете, что это такое, прочитайте предыдущую статью — Добавление аутентификации в полнофункциональное веб-приложение MERN)

Написание тестов в приложении NodeJs с помощью Jest и SuperTest

<цитата>

Примечание. Я рекомендую настроить отдельную базу данных для целей тестирования. Но для этого урока в этом нет необходимости.

Шаг 1. Разделите приложение и сервер

Во-первых, нам нужно отделить сервер от приложения, поскольку мы используем SuperTest для тестирования приложения, а не сервера.

Создайте файл app.js в корневом каталоге и вставьте этот код.

const express = require("express");
const cors = require("cors");

const ActivityRouter = require("./routes/activity.route");
const AuthRouter = require("./routes/auth.route");

const app = express();

/* Telling the application to use the express.json() middleware. This middleware will parse the body of
any request that has a Content-Type of application/json. */
app.use(express.json());

/* Allowing the frontend to access the backend. */
app.use(cors());

/* This is a route handler. It is listening for a GET request to the root route of the application.
When it receives a request, it will send back a response with the string "Hello World!". */
app.get("/", (req, res) => {
  res.send("Hello World!");
});

/* Telling the application to use the ActivityRouter for any requests that start with "/api". */
app.use("/api", ActivityRouter);

/* Telling the application to use the AuthRouter for any requests that start with "/api/auth". */
app.use("/api/auth", AuthRouter);

module.exports = app;

... и в server.js.

const express = require("express");
const mongoose = require("mongoose");

const app = express();

/* Loading the environment variables from the .env file. */
require("dotenv").config();

const PORT = process.env.PORT || 5000;
const MONGODB_URI = process.env.MONGODB_URI || "mongodb://localhost/todoapiDB";

/* Connecting to the database and then starting the server. */
mongoose
  .connect(MONGODB_URI, { useNewUrlParser: true })
  .then(() => {
    app.listen(PORT, console.log("Server stated on port 5000"));
  })
  .catch((err) => {
    console.log(err);
  });

Шаг 2. Установите пакеты

Чтобы начать писать тесты, вам понадобятся три пакета npm: jest, supertest и cross-env.

npm i --save-dev jest supertest cross-env

jest: Jest — это платформа для тестирования кода JavaScript. Модульное тестирование является его основным использованием. супертест: с помощью супертеста мы можем тестировать конечные точки и маршруты на HTTP-серверах. cross-env: вы можете установить переменные среды внутри команды, используя cross-env.

Шаг 3. Добавьте тестовый скрипт

Откройте файл package.json и добавьте тестовый скрипт к скриптам.

"scripts": {
    "test": "cross-env NODE_ENV=test jest --testTimeout=5000",
    "start": "node server.js",
    "dev": "nodemon server.js"
},

В этом случае для testTimeout установлено значение 5000, так как выполнение некоторых запросов может занять некоторое время, и cross-env используется для установки переменных среды и jest для запуска наборов тестов.

Шаг 4. Начните писать тесты

Сначала создайте папку с именем tests/ в корне приложения, а затем создайте там файл с именем activity.test.js. Jest ищет папку tests/ в корне проекта, когда вы выполняете npm run test. В результате вы должны поместить свои тестовые файлы в папку tests/.

Затем импортируйте пакеты supertest и mongoose в тестовый файл.

const mongoose = require("mongoose");
const request = require("supertest");

Импортируйте dotenv для загрузки переменных среды и импортируйте app.js, поскольку именно с него начинается наше приложение.

const mongoose = require("mongoose");
const request = require("supertest");

const app = require("../app");

require("dotenv").config();

Вам потребуется подключать и отключать базу данных до и после каждого теста (поскольку нам не требуется база данных после завершения тестирования).

/* Connecting to the database before each test. */
beforeEach(async () => {
  await mongoose.connect(process.env.MONGODB_URI);
});

/* Closing database connection after each test. */
afterEach(async () => {
  await mongoose.connection.close();
});

Теперь напишите свой первый модульный тест.

describe("GET /api/activities", () => {
  it("should get all the activities", async () => {
    const token = await request(app).post("/api/auth/login").send({
      email: process.env.EMAIL,
      password: process.env.PASSWORD,
    });

    const response = await request(app)
      .get("/api/activities")
      .set({
        Authorization: "bearer " + token.body.token,
        "Content-Type": "application/json",
      });

    expect(response.statusCode).toBe(200);
    expect(response.body.length).toBeGreaterThan(0);
  });
});

В приведенном выше коде

  • Мы используем describe для описания модульного теста. Хотя это и не обязательно, будет полезно идентифицировать тесты в результатах тестов.
  • В it мы пишем реальный тестовый код. Запишите ожидаемый результат в первый аргумент, а затем во второй аргумент напишите функцию обратного вызова, содержащую тестовый код.
  • В функции обратного вызова запрос сначала отправляется в конечную точку, а затем сравниваются ожидаемый и фактический ответы. Тест считается пройденным, если оба ответа совпадают, в противном случае он не пройден.
<цитата>

Примечание. Поскольку в нашем приложении есть аутентифицированные маршруты, нам нужно получить токен, войдя в приложение и используя этот токен для доступа к маршруту.

Вы можете написать тесты для всех конечных точек одним и тем же способом.

describe("POST /api/activity", () => {
  it("should add an activity to the database", async () => {
    const token = await request(app).post("/api/auth/login").send({
      email: process.env.EMAIL,
      password: process.env.PASSWORD,
    });

    const response = await request(app)
      .post("/api/activity")
      .send({
        name: "Jogging",
        time: "3:00 PM",
      })
      .set({
        Authorization: "bearer " + token.body.token,
        "Content-Type": "application/json",
      });

    expect(response.statusCode).toBe(201);
  });
});

Затем запустите npm run test, чтобы запустить наборы тестов (набор — тестовый файл).

test results

Написание тестов в приложении ReactJs с библиотекой тестирования React

Точно так же напишем тесты для React-приложений. Для этого мы будем использовать библиотеку тестирования React.

<цитата>

Семейство пакетов @testing-library помогает тестировать компоненты пользовательского интерфейса с учетом интересов пользователя.

Шаг 1. Установите пакеты

Чтобы начать писать тесты в React, вам потребуется библиотека тестирования React. Но эти пакеты поставляются с предустановленным приложением create-react-app (CRA). Если вы не использовали CRA, вы можете установить их следующим образом.

npm install --save-dev @testing-library/react @testing-library/jest-dom @testing-library/user-event

Шаг 2. Создайте тестовые файлы

Рекомендуется создать тестовый файл для каждого компонента.

У нас есть 2 компонента, которые необходимо протестировать: <App /> и <Login />. Поэтому создайте App.test.js и Login.test.js в папке src/. Но пока создайте только файл App.test.js.

Шаг 3. Начните писать тесты

Напишите свой первый тест.

В файле App.jsx добавьте атрибут data-testid={"app-header-heading"} к основному элементу заголовка. Позже, при написании тестов, мы сможем обращаться к этому элементу с этим идентификатором.

<h1 data-testid="app-header-heading">Productivity Tracker</h1>

Теперь откройте файл App.test.js и вставьте приведенный ниже код.

import { render, screen } from "@testing-library/react";

import App from "./App";

/* This is a test that is testing the App component. 
 * It is testing that the heading is correct. */
describe("App", () => {
  it("should have exact heading", () => {
    /* Rendering the App component. */
    render(<App />);

    /* Getting the element with the test id of "app-header-heading". */
    const mainHeading = screen.getByTestId("app-header-heading");

    /* Checking that the innerHTML of the element with the test id of "app-header-heading" is equal to
    "Productivity Tracker". */
    expect(mainHeading.innerHTML).toBe("Productivity Tracker");
  });
});

В приведенном выше коде

  • Сначала мы импортировали необходимые пакеты — render и screen из @testing-library/react, а затем импортировали компонент, который необходимо проверено.
  • Для описания модульного теста используется тот же синтаксис, что и в экспресс-тесте. Большинство разработчиков React по соглашению помещают имя компонента в первый аргумент. Фактический тест записывается как функция обратного вызова во втором аргументе.
  • В it мы пишем реальный тестовый код. Запишите ожидаемый результат в первый аргумент, а затем во второй аргумент напишите функцию обратного вызова, содержащую тестовый код.
  • Остальная часть кода не требует пояснений, и вы также можете понять ее из комментариев. Мы ожидаем, что компонент "Приложение" должен содержать заголовок "Отслеживание продуктивности".

Это общий процесс написания теста для компонента React:

  • Визуализировать компонент -> Напишите элементы, с которыми вы хотите взаимодействовать -> Взаимодействуйте с этими элементами -> Подтвердите, что результаты соответствуют ожиданиям.

Теперь запустите команду npm test. Вы увидите результаты.

App component test results

Пожалуйста, обратитесь к официальной документации, чтобы узнать больше о библиотеке тестирования React и написать свои собственные тесты.


В качестве испытания попробуйте реализовать поток "Добавить активность". В следующей статье мы узнаем кое-что о DevOps.


Также читайте,

Не стесняйтесь задавать свои сомнения в комментариях.

:::информация Также опубликовано здесь.

:::


Оригинал
PREVIOUS ARTICLE
NEXT ARTICLE