Back to QA Automation

Module 4: API Testing & Automation

Master API testing from basics to advanced automation with modern tools and frameworks

๐Ÿ”Œ REST API Testing Fundamentals

APIs are like waiters in a restaurant - they take your order (request) and bring back food (response). Testing APIs ensures they deliver the right food every time!

HTTP Methods

GET - Retrieve data

Like asking "What's on the menu?"

POST - Create new data

Like placing a new order

PUT - Update existing data

Like changing your order

DELETE - Remove data

Like canceling your order

HTTP Status Codes

// Success codes

200 OK - Request successful

201 Created - Resource created

204 No Content - Success, no data returned

// Client error codes

400 Bad Request - Invalid data sent

401 Unauthorized - Authentication required

403 Forbidden - No permission

404 Not Found - Resource doesn't exist

// Server error codes

500 Internal Server Error - Server crashed

503 Service Unavailable - Server down

๐Ÿ“ฎ Postman for API Testing

Postman is like a playground for APIs - test requests, save collections, and automate tests visually.

Creating a Request

// GET request example

GET https://api.example.com/users

// POST request with body

POST https://api.example.com/users

Headers:

Content-Type: application/json

Body:

{

"name": "Test User",

"email": "test@email.com"

}

Postman Tests

// Test status code

pm.test("Status code is 200", function () {

pm.response.to.have.status(200);

});

// Test response time

pm.test("Response time is less than 500ms", function () {

pm.expect(pm.response.responseTime).to.be.below(500);

});

// Test response body

pm.test("User has correct email", function () {

const jsonData = pm.response.json();

pm.expect(jsonData.email).to.eql("test@email.com");

});

// Save data for next request

const userId = pm.response.json().id;

pm.environment.set("userId", userId);

๐Ÿงช Automated API Tests with SuperTest

SuperTest lets you write automated API tests in code - perfect for CI/CD pipelines.

// Install SuperTest

npm install --save-dev supertest jest

// tests/api/users.test.js

const request = require('supertest');

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

describe('User API', () => {

let userId;

test('GET /api/users - should return all users', async () => {

const response = await request(app)

.get('/api/users')

.expect(200)

.expect('Content-Type', /json/);

expect(response.body).toBeInstanceOf(Array);

expect(response.body.length).toBeGreaterThan(0);

});

test('POST /api/users - should create user', async () => {

const newUser = {

name: 'Test User',

email: 'test@email.com'

};

const response = await request(app)

.post('/api/users')

.send(newUser)

.expect(201);

expect(response.body).toHaveProperty('id');

expect(response.body.name).toBe(newUser.name);

userId = response.body.id;

});

test('PUT /api/users/:id - should update user', async () => {

const updates = { name: 'Updated Name' };

await request(app)

.put(`/api/users/${userId} `)

.send(updates)

.expect(200);

});

test('DELETE /api/users/:id - should delete user', async () => {

await request(app)

.delete(`/api/users/${userId} `)

.expect(204);

});

});

๐Ÿ”ท GraphQL API Testing

GraphQL is like ordering ร  la carte - you specify exactly what data you want.

// GraphQL Query Test

test('should fetch user with specific fields', async () => {

const query = `

query {

user(id: "1") {

id

name

email

}

}

`;

const response = await request(app)

.post('/graphql')

.send({ query })

.expect(200);

expect(response.body.data.user).toHaveProperty('id');

expect(response.body.data.user).toHaveProperty('name');

});

// GraphQL Mutation Test

test('should create user via mutation', async () => {

const mutation = `

mutation {

createUser(name: "Test", email: "test@email.com") {

id

name

}

}

`;

const response = await request(app)

.post('/graphql')

.send({ query: mutation })

.expect(200);

expect(response.body.data.createUser).toHaveProperty('id');

});

๐Ÿ” Authentication & Authorization Testing

// Test JWT authentication

describe('Authentication', () => {

let authToken;

test('should login and return token', async () => {

const response = await request(app)

.post('/api/auth/login')

.send({

email: 'test@email.com',

password: 'password123'

});

expect(response.status).toBe(200);

expect(response.body).toHaveProperty('token');

authToken = response.body.token;

});

test('should access protected route with token', async () => {

await request(app)

.get('/api/profile')

.set('Authorization', `Bearer ${authToken} `)

.expect(200);

});

test('should reject without token', async () => {

await request(app)

.get('/api/profile')

.expect(401);

});

test('should reject with invalid token', async () => {

await request(app)

.get('/api/profile')

.set('Authorization', 'Bearer invalid-token')

.expect(401);

});

});

โœ… Schema Validation

Validate API responses match expected structure - like checking if your pizza has all the toppings you ordered.

// Install Joi for validation

npm install joi

// Define schema

const Joi = require('joi');

const userSchema = Joi.object({

id: Joi.number().required(),

name: Joi.string().min(3).required(),

email: Joi.string().email().required(),

age: Joi.number().min(18).optional(),

createdAt: Joi.date().required()

});

// Validate response

test('should match user schema', async () => {

const response = await request(app).get('/api/users/1');

const { error } = userSchema.validate(response.body);

expect(error).toBeUndefined();

});

โšก Performance Testing Basics

// Test response time

test('should respond within 500ms', async () => {

const start = Date.now();

await request(app).get('/api/users');

const duration = Date.now() - start;

expect(duration).toBeLessThan(500);

});

// Load testing with k6 (preview)

import http from 'k6/http';

import { check } from 'k6';

export default function() {

const res = http.get('https://api.example.com/users');

check(res, {

'status is 200': (r) => r.status =>= 200,

'response time < 500ms': (r) => r.timings.duration < 500

});

}

๐Ÿš€ Complete API Test Framework Project

Build a complete API testing framework with helpers, fixtures, and organized tests.

// Project Structure

tests/

โ”œโ”€โ”€ api/

โ”‚ โ”œโ”€โ”€ users.test.js

โ”‚ โ”œโ”€โ”€ products.test.js

โ”‚ โ””โ”€โ”€ orders.test.js

โ”œโ”€โ”€ helpers/

โ”‚ โ”œโ”€โ”€ auth.js

โ”‚ โ””โ”€โ”€ testData.js

โ”œโ”€โ”€ fixtures/

โ”‚ โ””โ”€โ”€ users.json

โ””โ”€โ”€ setup.js

// helpers/auth.js

async function getAuthToken() {

const response = await request(app)

.post('/api/auth/login')

.send({ email: 'test@email.com', password: 'pass' });

return response.body.token;

}

// Run all tests

npm test

๐ŸŽฏ Module Summary

You've mastered API testing and automation:

  • โœ“ REST API testing fundamentals
  • โœ“ Postman for manual API testing
  • โœ“ Automated tests with SuperTest
  • โœ“ GraphQL API testing
  • โœ“ Authentication and authorization testing
  • โœ“ Schema validation
  • โœ“ Performance testing basics
  • โœ“ Complete API test framework

Next: Mobile Testing Automation in Module 5!