ไทย

คู่มือฉบับสมบูรณ์สำหรับการทดสอบแบบบูรณาการที่เน้นการทดสอบ API ด้วย Supertest ครอบคลุมการตั้งค่า แนวทางปฏิบัติที่ดีที่สุด และเทคนิคขั้นสูงเพื่อการทดสอบแอปพลิเคชันที่แข็งแกร่ง

การทดสอบแบบบูรณาการ (Integration Testing): การทดสอบ API อย่างเชี่ยวชาญด้วย Supertest

ในโลกของการพัฒนาซอฟต์แวร์ การทำให้แน่ใจว่าส่วนประกอบแต่ละชิ้นทำงานได้อย่างถูกต้องโดยลำพัง (unit testing) ถือเป็นสิ่งสำคัญ แต่การตรวจสอบว่าส่วนประกอบเหล่านี้ทำงานร่วมกันได้อย่างราบรื่นก็มีความสำคัญไม่แพ้กัน นี่คือจุดที่ การทดสอบแบบบูรณาการ (integration testing) เข้ามามีบทบาท การทดสอบแบบบูรณาการมุ่งเน้นไปที่การตรวจสอบการทำงานร่วมกันระหว่างโมดูลหรือบริการต่างๆ ภายในแอปพลิเคชัน บทความนี้จะเจาะลึกเกี่ยวกับการทดสอบแบบบูรณาการ โดยเฉพาะอย่างยิ่งการเน้นที่ การทดสอบ API ด้วย Supertest ซึ่งเป็นไลบรารีที่มีประสิทธิภาพและใช้งานง่ายสำหรับการทดสอบการยืนยันค่า HTTP ใน Node.js

การทดสอบแบบบูรณาการ (Integration Testing) คืออะไร?

การทดสอบแบบบูรณาการคือการทดสอบซอฟต์แวร์ประเภทหนึ่งที่รวมโมดูลซอฟต์แวร์แต่ละตัวเข้าด้วยกันและทดสอบเป็นกลุ่ม โดยมีเป้าหมายเพื่อค้นหาข้อบกพร่องในการโต้ตอบระหว่างหน่วยที่รวมเข้าด้วยกัน ซึ่งแตกต่างจากการทดสอบหน่วย (unit testing) ที่มุ่งเน้นไปที่ส่วนประกอบแต่ละชิ้น การทดสอบแบบบูรณาการจะตรวจสอบการไหลของข้อมูลและการควบคุมระหว่างโมดูลต่างๆ แนวทางการทดสอบแบบบูรณาการที่พบบ่อย ได้แก่:

ในบริบทของ API การทดสอบแบบบูรณาการเกี่ยวข้องกับการตรวจสอบว่า API ต่างๆ ทำงานร่วมกันได้อย่างถูกต้อง ข้อมูลที่ส่งผ่านระหว่างกันมีความสอดคล้อง และระบบโดยรวมทำงานตามที่คาดไว้ ตัวอย่างเช่น ลองนึกภาพแอปพลิเคชันอีคอมเมิร์ซที่มี API แยกกันสำหรับการจัดการผลิตภัณฑ์ การยืนยันตัวตนผู้ใช้ และการประมวลผลการชำระเงิน การทดสอบแบบบูรณาการจะช่วยให้มั่นใจได้ว่า API เหล่านี้สื่อสารกันอย่างถูกต้อง ทำให้ผู้ใช้สามารถเรียกดูผลิตภัณฑ์ เข้าสู่ระบบอย่างปลอดภัย และทำการสั่งซื้อให้เสร็จสมบูรณ์ได้

เหตุใดการทดสอบการบูรณาการ API จึงมีความสำคัญ?

การทดสอบการบูรณาการ API มีความสำคัญอย่างยิ่งด้วยเหตุผลหลายประการ:

ลองพิจารณาแพลตฟอร์มการจองการเดินทางทั่วโลก การทดสอบการบูรณาการ API เป็นสิ่งสำคัญอย่างยิ่งเพื่อให้แน่ใจว่าการสื่อสารระหว่าง API ที่จัดการการจองเที่ยวบิน การจองโรงแรม และเกตเวย์การชำระเงินจากประเทศต่างๆ เป็นไปอย่างราบรื่น ความล้มเหลวในการบูรณาการ API เหล่านี้อย่างเหมาะสมอาจนำไปสู่การจองที่ไม่ถูกต้อง ความล้มเหลวในการชำระเงิน และประสบการณ์ผู้ใช้ที่แย่ ซึ่งส่งผลเสียต่อชื่อเสียงและรายได้ของแพลตฟอร์ม

แนะนำ Supertest: เครื่องมืออันทรงพลังสำหรับการทดสอบ API

Supertest เป็น high-level abstraction สำหรับการทดสอบ HTTP request โดยมี API ที่สะดวกและลื่นไหลสำหรับการส่งคำขอไปยังแอปพลิเคชันของคุณและการยืนยันค่าในการตอบกลับ Supertest สร้างขึ้นบน Node.js และออกแบบมาโดยเฉพาะสำหรับการทดสอบเซิร์ฟเวอร์ 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. ติดตั้ง dependencies:
npm install --save-dev jest supertest
npm install express  # หรือเฟรมเวิร์กที่คุณต้องการสำหรับสร้าง API
  1. ตั้งค่า Jest: เพิ่มโค้ดต่อไปนี้ลงในไฟล์ package.json ของคุณ:
{
  "scripts": {
    "test": "jest"
  }
}
  1. สร้าง API endpoint แบบง่ายๆ: สร้างไฟล์ชื่อ 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 endpoint ของเรากัน สร้างไฟล์ชื่อ 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. การส่ง Request Bodies

หากต้องการส่งข้อมูลใน request body คุณสามารถใช้เมธอด .send() ตัวอย่างเช่น ลองสร้าง endpoint ที่รับข้อมูล 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);
});

นี่คือวิธีที่คุณสามารถทดสอบ endpoint นี้โดยใช้ 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. การตั้งค่า Headers

หากต้องการตั้งค่า header ที่กำหนดเองใน request ของคุณ คุณสามารถใช้เมธอด .set() ซึ่งมีประโยชน์สำหรับการตั้งค่าโทเค็นการยืนยันตัวตน (authentication token), content type หรือ header ที่กำหนดเองอื่นๆ

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 ยังสามารถจัดการคุกกี้ได้อีกด้วย คุณสามารถตั้งค่าคุกกี้โดยใช้เมธอด .set('Cookie', ...) หรือคุณสามารถใช้ property .cookies เพื่อเข้าถึงและแก้ไขคุกกี้

4. การทดสอบการอัปโหลดไฟล์

Supertest สามารถใช้ทดสอบ API endpoint ที่จัดการการอัปโหลดไฟล์ได้ คุณสามารถใช้เมธอด .attach() เพื่อแนบไฟล์ไปกับ request

5. การใช้ไลบรารี Assertion (Chai)

แม้ว่าไลบรารี assertion ที่มีในตัวของ Jest จะเพียงพอสำหรับหลายกรณี แต่คุณยังสามารถใช้ไลบรารี assertion ที่มีประสิทธิภาพมากกว่าอย่าง Chai กับ Supertest ได้ Chai มี синтаксис assertion ที่สื่อความหมายและยืดหยุ่นกว่า หากต้องการใช้ Chai คุณจะต้องติดตั้งก่อน:

npm install --save-dev chai

จากนั้น คุณสามารถ import Chai เข้าไปในไฟล์เทสต์ของคุณและใช้ assertion ของมันได้:

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 อย่างถูกต้อง ซึ่งมักจะเกี่ยวข้องกับการเพิ่มไฟล์ setup ที่ import Chai และกำหนดค่าให้ทำงานร่วมกับ expect แบบ global ของ Jest

6. การใช้ Agent ซ้ำ

สำหรับเทสต์ที่ต้องการตั้งค่าสภาพแวดล้อมเฉพาะ (เช่น การยืนยันตัวตน) การใช้ Supertest agent ซ้ำมักจะเป็นประโยชน์ ซึ่งจะช่วยหลีกเลี่ยงโค้ดการตั้งค่าที่ซ้ำซ้อนในแต่ละกรณีทดสอบ

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 agent ใน hook beforeAll และทำการยืนยันตัวตนของ agent เทสต์ต่อๆ ไปภายในบล็อก describe สามารถใช้ agent ที่ยืนยันตัวตนแล้วนี้ซ้ำได้โดยไม่ต้องยืนยันตัวตนใหม่ในแต่ละเทสต์

แนวทางปฏิบัติที่ดีที่สุดสำหรับการทดสอบการบูรณาการ API ด้วย Supertest

เพื่อให้แน่ใจว่าการทดสอบการบูรณาการ API มีประสิทธิภาพ ให้พิจารณาแนวทางปฏิบัติที่ดีที่สุดต่อไปนี้:

ข้อผิดพลาดที่ควรหลีกเลี่ยง

สรุป

การทดสอบการบูรณาการ API เป็นส่วนสำคัญของกระบวนการพัฒนาซอฟต์แวร์ ด้วยการใช้ Supertest คุณสามารถเขียนเทสต์การบูรณาการ API ที่ครอบคลุมและเชื่อถือได้ ซึ่งช่วยให้มั่นใจในคุณภาพและเสถียรภาพของแอปพลิเคชันของคุณ อย่าลืมมุ่งเน้นไปที่การทดสอบเวิร์กโฟลว์แบบต้นจนจบ การใช้ข้อมูลที่สมจริง การแยกเทสต์ของคุณ และการทำให้กระบวนการทดสอบของคุณเป็นอัตโนมัติ การปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดเหล่านี้จะช่วยลดความเสี่ยงของปัญหาการบูรณาการได้อย่างมากและส่งมอบผลิตภัณฑ์ที่แข็งแกร่งและน่าเชื่อถือยิ่งขึ้น

ในขณะที่ API ยังคงขับเคลื่อนแอปพลิเคชันสมัยใหม่และสถาปัตยกรรมไมโครเซอร์วิส ความสำคัญของการทดสอบ API ที่แข็งแกร่ง โดยเฉพาะอย่างยิ่งการทดสอบแบบบูรณาการ จะยิ่งเพิ่มขึ้นเรื่อยๆ Supertest เป็นชุดเครื่องมือที่มีประสิทธิภาพและเข้าถึงได้สำหรับนักพัฒนาทั่วโลก เพื่อให้แน่ใจในความน่าเชื่อถือและคุณภาพของการทำงานร่วมกันของ API ของพวกเขา