Українська

Вичерпний посібник з інтеграційного тестування з акцентом на тестування API за допомогою Supertest, що охоплює налаштування, найкращі практики та передові методи для надійного тестування додатків.

Інтеграційне тестування: опановуємо тестування API за допомогою Supertest

У світі розробки програмного забезпечення надзвичайно важливо переконатися, що окремі компоненти працюють коректно ізольовано (модульне тестування). Однак не менш важливо перевірити, що ці компоненти бездоганно працюють разом. Саме тут у гру вступає інтеграційне тестування. Інтеграційне тестування зосереджується на перевірці взаємодії між різними модулями або сервісами в додатку. Ця стаття глибоко занурюється в інтеграційне тестування, зокрема, зосереджуючись на тестуванні API за допомогою Supertest, потужної та зручної бібліотеки для тестування HTTP-тверджень у Node.js.

Що таке інтеграційне тестування?

Інтеграційне тестування — це тип тестування програмного забезпечення, який об'єднує окремі програмні модулі та тестує їх як групу. Його мета — виявити дефекти у взаємодіях між інтегрованими блоками. На відміну від модульного тестування, яке зосереджується на окремих компонентах, інтеграційне тестування перевіряє потік даних і потік управління між модулями. Поширені підходи до інтеграційного тестування включають:

У контексті API інтеграційне тестування передбачає перевірку того, що різні API працюють коректно разом, що дані, які передаються між ними, є послідовними, і що система в цілому функціонує, як очікувалося. Наприклад, уявіть собі додаток для електронної комерції з окремими API для управління продуктами, автентифікації користувачів та обробки платежів. Інтеграційне тестування гарантувало б, що ці API коректно взаємодіють, дозволяючи користувачам переглядати продукти, безпечно входити в систему та завершувати покупки.

Чому інтеграційне тестування API важливе?

Інтеграційне тестування API є критично важливим з кількох причин:

Розглянемо глобальну платформу для бронювання подорожей. Інтеграційне тестування API є першочерговим для забезпечення безперебійної взаємодії між API, що обробляють бронювання авіаквитків, готелів та платіжних шлюзів з різних країн. Неспроможність належним чином інтегрувати ці API може призвести до неправильних бронювань, збоїв платежів та поганого користувацького досвіду, що негативно вплине на репутацію та доходи платформи.

Представляємо Supertest: потужний інструмент для тестування API

Supertest — це високорівнева абстракція для тестування HTTP-запитів. Він надає зручний та виразний API для надсилання запитів до вашого додатку та перевірки відповідей. Створений на базі Node.js, Supertest спеціально розроблений для тестування HTTP-серверів Node.js. Він чудово працює з популярними фреймворками для тестування, такими як Jest та Mocha.

Ключові особливості Supertest:

Налаштування тестового середовища

Перш ніж ми почнемо, давайте налаштуємо базове тестове середовище. Будемо вважати, що у вас встановлено Node.js та npm (або yarn). Ми будемо використовувати Jest як наш фреймворк для тестування та Supertest для тестування API.

  1. Створіть проєкт Node.js:
mkdir api-testing-example
cd api-testing-example
npm init -y
  1. Встановіть залежності:
npm install --save-dev jest supertest
npm install express  # Or your preferred framework for creating the API
  1. Налаштуйте Jest: Додайте наступне до вашого файлу package.json:
{
  "scripts": {
    "test": "jest"
  }
}
  1. Створіть простий ендпоінт API: Створіть файл з назвою app.js (або подібною) з наступним кодом:
const express = require('express');
const app = express();
const port = 3000;

app.get('/hello', (req, res) => {
  res.send('Hello, World!');
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

module.exports = app; // Export for testing

Написання вашого першого тесту з Supertest

Тепер, коли наше середовище налаштоване, давайте напишемо простий тест Supertest для перевірки нашого ендпоінту API. Створіть файл з назвою app.test.js (або подібною) в корені вашого проєкту:

const request = require('supertest');
const app = require('./app');

describe('GET /hello', () => {
  it('responds with 200 OK and returns "Hello, World!"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).toBe(200);
    expect(response.text).toBe('Hello, World!');
  });
});

Пояснення:

Щоб запустити тест, виконайте наступну команду у вашому терміналі:

npm test

Якщо все налаштовано правильно, ви повинні побачити, що тест пройшов успішно.

Просунуті техніки Supertest

Supertest пропонує широкий спектр функцій для просунутого тестування API. Давайте розглянемо деякі з них.

1. Надсилання тіла запиту

Щоб надіслати дані в тілі запиту, ви можете використовувати метод .send(). Наприклад, давайте створимо ендпоінт, який приймає дані у форматі JSON:

app.post('/users', express.json(), (req, res) => {
  const { name, email } = req.body;
  // Simulate creating a user in a database
  const user = { id: Date.now(), name, email };
  res.status(201).json(user);
});

Ось як ви можете протестувати цей ендпоінт за допомогою Supertest:

describe('POST /users', () => {
  it('creates a new user', async () => {
    const userData = {
      name: 'John Doe',
      email: 'john.doe@example.com',
    };

    const response = await request(app)
      .post('/users')
      .send(userData)
      .expect(201);

    expect(response.body).toHaveProperty('id');
    expect(response.body.name).toBe(userData.name);
    expect(response.body.email).toBe(userData.email);
  });
});

Пояснення:

2. Встановлення заголовків

Щоб встановити власні заголовки у ваших запитах, ви можете використовувати метод .set(). Це корисно для встановлення токенів автентифікації, типів контенту або інших власних заголовків.

describe('GET /protected', () => {
  it('requires authentication', async () => {
    const response = await request(app).get('/protected').expect(401);
  });

  it('returns 200 OK with a valid token', async () => {
    // Simulate getting a valid token
    const token = 'valid-token';

    const response = await request(app)
      .get('/protected')
      .set('Authorization', `Bearer ${token}`)
      .expect(200);

    expect(response.text).toBe('Protected Resource');
  });
});

Пояснення:

3. Робота з Cookies

Supertest також може працювати з cookies. Ви можете встановлювати cookies за допомогою методу .set('Cookie', ...), або ви можете використовувати властивість .cookies для доступу та зміни cookies.

4. Тестування завантаження файлів

Supertest можна використовувати для тестування ендпоінтів API, які обробляють завантаження файлів. Ви можете використовувати метод .attach() для прикріплення файлів до запиту.

5. Використання бібліотек тверджень (Chai)

Хоча вбудованої бібліотеки тверджень Jest достатньо для багатьох випадків, ви також можете використовувати більш потужні бібліотеки тверджень, такі як Chai, разом із Supertest. Chai надає більш виразний та гнучкий синтаксис тверджень. Щоб використовувати Chai, вам потрібно його встановити:

npm install --save-dev chai

Потім ви можете імпортувати Chai у ваш тестовий файл і використовувати його твердження:

const request = require('supertest');
const app = require('./app');
const chai = require('chai');
const expect = chai.expect;

describe('GET /hello', () => {
  it('responds with 200 OK and returns "Hello, World!"', async () => {
    const response = await request(app).get('/hello');
    expect(response.statusCode).to.equal(200);
    expect(response.text).to.equal('Hello, World!');
  });
});

Примітка: Можливо, вам доведеться налаштувати Jest для коректної роботи з Chai. Це часто включає додавання файлу налаштування, який імпортує Chai і конфігурує його для роботи з глобальним expect від Jest.

6. Повторне використання агентів

Для тестів, які вимагають налаштування специфічного середовища (наприклад, автентифікації), часто корисно повторно використовувати агента Supertest. Це дозволяє уникнути надлишкового коду налаштування в кожному тестовому випадку.

describe('Authenticated API Tests', () => {
  let agent;

  beforeAll(() => {
    agent = request.agent(app); // Create a persistent agent
    // Simulate authentication
    return agent
      .post('/login')
      .send({ username: 'testuser', password: 'password123' });
  });

  it('can access a protected resource', async () => {
    const response = await agent.get('/protected').expect(200);
    expect(response.text).toBe('Protected Resource');
  });

  it('can perform other actions that require authentication', async () => {
    // Perform other authenticated actions here
  });
});

У цьому прикладі ми створюємо агента Supertest у хуку beforeAll та автентифікуємо його. Наступні тести в межах блоку describe можуть потім повторно використовувати цього автентифікованого агента, не потребуючи повторної автентифікації для кожного тесту.

Найкращі практики для інтеграційного тестування API з Supertest

Щоб забезпечити ефективне інтеграційне тестування API, враховуйте наступні найкращі практики:

Поширені помилки, яких слід уникати

Висновок

Інтеграційне тестування API є невід'ємною частиною процесу розробки програмного забезпечення. Використовуючи Supertest, ви можете легко писати вичерпні та надійні інтеграційні тести API, які допомагають забезпечити якість та стабільність вашого додатку. Пам'ятайте про необхідність зосереджуватися на тестуванні повних робочих процесів, використанні реалістичних даних, ізоляції ваших тестів та автоматизації процесу тестування. Дотримуючись цих найкращих практик, ви можете значно зменшити ризик проблем інтеграції та надати більш надійний та стабільний продукт.

Оскільки API продовжують бути рушійною силою сучасних додатків та мікросервісних архітектур, важливість надійного тестування API, і особливо інтеграційного тестування, буде тільки зростати. Supertest надає потужний та доступний набір інструментів для розробників по всьому світу, щоб забезпечити надійність та якість їхніх взаємодій з API.