API test’leri manuel yapmak sürdürülmez bir yol. Postman’de collection var, developer’lar GUI’den çalıştırıyor, production’da bug’lar geliyor. Bu cycle’dan çıkmanın yolu: automation.
Bu yazıda Postman collection’dan Newman’a, Newman’dan CI pipeline’a kadar API test automation’u kurmayı anlatacağım.
Postman collection: temelden başla
Postman GUI’de collection oluşturuyorsun. Her folder bir feature, her request bir test.
Collection structure:
MyApp API
/Auth
- Login
- Register
- Logout
- Refresh Token
/Users
- Get User List
- Get User by ID
- Update User
- Delete User
/Products
- List Products
- Create Product
- ...Bu hiyerarşi Postman’de kurulduğunda API’nizin test coverage’ı görünür.
Test script’leri: request’lerin ötesinde
Postman her request’e JavaScript test script’i ekleyebiliyor. Response’u validate eder.
Example test:
// Login request'i sonra bu script çalışıyor
pm.test("Status code is 200", () => {
pm.response.to.have.status(200);
});
pm.test("Response has token", () => {
const jsonData = pm.response.json();
pm.expect(jsonData).to.have.property('token');
pm.expect(jsonData.token).to.not.be.empty;
});
// Token'ı environment variable'a kaydet (sonraki request'lerde kullanılacak)
pm.environment.set("authToken", pm.response.json().token);Bu pattern’la her request:
– Status code validation
– Response schema check
– Business logic assertion
– Dynamic data extraction (token, ID, etc.)
Environment’lar
Postman environment variable’lar farklı ortamları handle etmek için:
Environment: Development
baseUrl: http://localhost:3000
apiKey: dev_abc123
userEmail: dev@example.comEnvironment: Staging
baseUrl: https://staging-api.example.com
apiKey: stg_xyz456
userEmail: test@example.comEnvironment: Production
baseUrl: https://api.example.com
apiKey: prod_... (smoke test only)
userEmail: test@example.comRequest URL: {{baseUrl}}/users/{{userId}}. Environment switch ile tüm request’ler farklı ortamda çalışıyor.
Pre-request scripts
Request öncesi çalışan scripts:
// Dinamik test data oluştur
const randomEmail = `test_${Date.now()}@example.com`;
pm.environment.set("testEmail", randomEmail);
// Authentication header ekle
const token = pm.environment.get("authToken");
pm.request.headers.add({key: "Authorization", value: `Bearer ${token}`});
// Request body'yi prepare et
const body = {
email: randomEmail,
password: "TestPass123",
timestamp: new Date().toISOString()
};
pm.request.body = {mode: 'raw', raw: JSON.stringify(body)};Bu pattern’la her test run unique data ile çalışıyor, duplicate issue’ları önleniyor.
Newman: command-line Postman
Newman Postman collection’unu komut satırından çalıştıran tool:
npm install -g newman
newman run MyApp.postman_collection.json \
-e Staging.postman_environment.json \
--reporters cli,json \
--reporter-json-export results.jsonOutput:
MyApp API
→ Login
POST https://staging-api.example.com/auth/login [200 OK, 234ms]
✓ Status code is 200
✓ Response has token
→ Get User List
GET https://staging-api.example.com/users [200 OK, 156ms]
✓ Status code is 200
✓ Response is array
✓ At least 1 user exists
┌─────────────────────────┬──────────────────┬──────────────────┐
│ │ executed │ failed │
├─────────────────────────┼──────────────────┼──────────────────┤
│ iterations │ 1 │ 0 │
├─────────────────────────┼──────────────────┼──────────────────┤
│ requests │ 15 │ 0 │
├─────────────────────────┼──────────────────┼──────────────────┤
│ test-scripts │ 30 │ 0 │
├─────────────────────────┼──────────────────┼──────────────────┤
│ prerequest-scripts │ 5 │ 0 │
├─────────────────────────┼──────────────────┼──────────────────┤
│ assertions │ 45 │ 0 │
└─────────────────────────┴──────────────────┴──────────────────┘15 request, 45 assertion, 0 failure. Tek komut, tüm API test edildi.
CI pipeline integration
GitHub Actions’a Newman integration:
# .github/workflows/api-tests.yml
name: API Tests
on:
push:
branches: [main]
pull_request:
jobs:
api-tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- name: Install Newman
run: npm install -g newman newman-reporter-htmlextra
- name: Run API Tests
env:
API_BASE_URL: https://staging-api.example.com
API_KEY: ${{ secrets.STAGING_API_KEY }}
run: |
newman run postman/collection.json \
-e postman/staging.json \
--reporters cli,htmlextra \
--reporter-htmlextra-export test-report.html \
--env-var "baseUrl=$API_BASE_URL" \
--env-var "apiKey=$API_KEY"
- name: Upload Test Report
if: always()
uses: actions/upload-artifact@v3
with:
name: api-test-report
path: test-report.htmlEvery push’ta API tests çalışıyor. Fail olursa PR block.
Test coverage strategy
Hangi test’leri yazmak?
Happy path (%60 effort):
– Her endpoint için success scenario
– Valid input → expected response
– Authentication flow complete
Error cases (%30 effort):
– Invalid input → 400 Bad Request
– Missing auth → 401 Unauthorized
– Wrong permission → 403 Forbidden
– Non-existent resource → 404 Not Found
– Rate limit hit → 429 Too Many Requests
Edge cases (%10 effort):
– Boundary values (empty string, max length, negative numbers)
– Special characters (SQL injection, XSS patterns)
– Concurrent request handling
– Race conditions
Happy path coverage prioritize edip, error cases’a investment yap. Edge cases için chaos testing daha uygun.
Contract testing vs integration testing
Two different concepts:
Contract testing: API spec (OpenAPI) ile implementation uyumu. Dredd tool.
dredd api-spec.yaml https://api.example.comSpec’te tanımlı endpoint gerçekten var mı, response’u spec’e uygun mu?
Integration testing: Business logic correct mi? Postman/Newman bu seviyede.
Her ikisi gerekli. Contract spec compliance, integration business logic.
Mock services for tests
Bazen downstream servis test sırasında available değil (third-party API rate limit, external service down).
Solution: Mock server.
Postman’de mock server feature’ı var: collection’u mock server’a çevir, URL’i test’lere ver.
Prism (OpenAPI-based mock) alternative.
Integration test’lerinde real service’i kullan, end-to-end test’lerinde production’a yakın bir environment.
Test data management
Test’lerin idempotent olması gerekiyor. Aynı test 5 kez çalıştırılsa da sonuç aynı.
Pattern 1: Each test creates its own data
// Pre-request: yeni user oluştur
const randomUserId = Date.now();
pm.environment.set("testUserId", randomUserId);
// Test: bu user'ı kullan, sonra sil
pm.test("User created", () => { ... });
// Post-test: delete userPattern 2: Test fixtures
Pre-defined test user, test data baseline. Test’ler bu data’yı kullanıyor, modification yapmıyor.
Pattern 3: Rollback after test
Test yapıyor, sonra database rollback. Production’da impossible, staging’de mümkün.
Pattern 1 benim preferans. Isolated, safe, repeatable.
Performance assertions
Newman’da response time assertion:
pm.test("Response time is less than 500ms", () => {
pm.expect(pm.response.responseTime).to.be.below(500);
});API yavaşlarsa test fail. Performance regression detection.
Ama test tek request’i ölçüyor, load testing değil. k6, Artillery, JMeter load test için daha uygun.
Smoke tests in production
Production’a deploy edildikten sonra smoke test:
newman run production-smoke-tests.json \
-e production.json2-3 kritik endpoint (login, health check, key feature). Her deployment sonrası 30 saniyede çalışıyor. Fail olursa automated rollback.
Postman collection for production:
– Authentication flow
– 3 kritik endpoint
– No data creation/modification (side-effect free)
Common pitfalls
1. Test collection’u developer’ın local Postman’inde. Team sync yok. Solution: collection’u Git’e commit et.
2. Environment dosyaları secret’ları içeriyor. Security risk. Solution: .gitignore‘e ekle, CI’da env var’lar kullan.
3. Test’ler order-dependent. Sıra değişince fail. Solution: her test kendi setup’ını yapsın.
4. Production’da test. Real user data’yı bozabilir. Solution: staging’e test, production’a smoke test only.
5. Assertion’lar çok generic. expect(response).to.be.ok gibi anlamsız. Specific assertion’lar: response shape, exact values.
Test maintenance
API değiştikçe test’ler de güncellenmelidir. Maintenance overhead:
- Endpoint removed → test sil
- Field renamed → test script güncelle
- New required field → test’i update
Her PR’da API change varsa test update’i de bekle. Bu disciplin olmadan test’ler 6 ay içinde stale.
Pre-commit hook: Postman collection validator. Test’ler structure’ı doğru mu?
Reporting
Newman reporters:
- CLI: Terminal output, default
- JSON: Machine-readable, CI parsing için
- HTML (htmlextra): Browser’da renderable, visual report
- JUnit XML: Jenkins/GitLab compatibility
CI’da HTML artifact save. Fail’de team review ediyor, hangi test fail olmuş, neden.
Sonuç
API test automation manual process’in yerini aldığında quality dramatically artar. Postman collection + Newman + CI integration mature, reliable workflow.
Happy path’tan başla, error cases ekle, edge cases later. Idempotent test design, environment management, secret hygiene.
Every release Newman passes = confidence. Fail → fix immediately. Manual testing sadece exploratory için, regression için automated.