Testes de API
Aula 5 de 7
Importância dos Testes
Pirâmide de Testes:
╱╲
╱ E2E ╲ ✅ UI / Integração
╱───────╲
╱ Service ╲ ✅ Testes de API
╱───────────╲
╱ Unit ╲ ✅ Testes unitários
╱───────────────╲
Testes Unitários de HTTP
# Python + FastAPI + pytest
from fastapi.testclient import TestClient
from app import app
client = TestClient(app)
def test_create_user():
response = client.post("/users", json={
"name": "João",
"email": "[email protected]"
})
assert response.status_code == 201
data = response.json()
assert data["name"] == "João"
assert "id" in data
def test_get_user_not_found():
response = client.get("/users/99999")
assert response.status_code == 404
def test_invalid_email():
response = client.post("/users", json={
"name": "João",
"email": "invalido"
})
assert response.status_code == 422
assert "email" in response.json()["error"]["details"]
// Node.js + Jest + Supertest
const request = require('supertest');
const app = require('../app');
describe('Users API', () => {
it('cria usuário com sucesso', async () => {
const res = await request(app)
.post('/users')
.send({ name: 'Maria', email: '[email protected]' })
.expect(201);
expect(res.body).toHaveProperty('id');
});
it('retorna 400 sem nome', async () => {
await request(app)
.post('/users')
.send({ email: '[email protected]' })
.expect(422);
});
});
Testes de Contrato (Pact)
# Consumer-driven contract testing
import pact
pact = Pact(consumer='WebApp', provider='UsersAPI')
@pact.given('users exist')
@pact.upon_receiving('a request for user 1')
@pact.with_request(method='GET', path='/users/1')
@pact.will_respond_with(200, body={
'id': 1,
'name': 'João',
'email': '[email protected]'
})
def test_get_user():
result = client.get('/users/1')
assert result.status_code == 200
Testes de Performance (k6)
// k6 — teste de carga
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [
{ duration: '2m', target: 50 }, // ramp up
{ duration: '5m', target: 50 }, // steady
{ duration: '2m', target: 100 }, // ramp up
{ duration: '5m', target: 100 }, // steady
{ duration: '2m', target: 0 }, // ramp down
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% das requests < 500ms
http_req_failed: ['rate<0.01'], // < 1% de erro
},
};
export default function () {
const res = http.get('https://api.exemplo.com/users');
check(res, {
'status 200': (r) => r.status === 200,
'duration < 300ms': (r) => r.timings.duration < 300,
});
sleep(1);
}
k6 run script.js
Testes Automatizados via Postman/Newman
// Postman collection → Newman CLI
// pm.test() — assertions no Postman
pm.test("Status 200", () => {
pm.response.to.have.status(200);
});
pm.test("Response time < 500ms", () => {
pm.expect(pm.response.responseTime).to.be.below(500);
});
pm.test("Body tem campos obrigatórios", () => {
const json = pm.response.json();
pm.expect(json).to.have.all.keys('id', 'name', 'email');
});
# Newman — rodar collection no CI
newman run MinhaAPI.postman_collection.json \
--environment producao.postman_environment.json \
--reporters cli,junit \
--reporter-junit-export results.xml
CI/CD Testing
# .github/workflows/api-tests.yml
jobs:
integration:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16-alpine
env:
POSTGRES_PASSWORD: test
options: >-
--health-cmd pg_isready
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test # unit tests
- run: npm run test:int # integration tests
- run: npx newman run collection.json # Postman tests
- run: k6 run load-test.js # performance
Testes de API cobrem: unitário (lógica), integração (banco), contrato (Pact), carga (k6), E2E (Postman). Automatize via CI/CD. Testes de performance com thresholds evitam regressão.