Ana Sayfa / Blog / API test automation: Postman’den Newman’a, CI’a entegre

API test automation: Postman’den Newman’a, CI’a entegre

API test'leri manuel çalıştırmak çok kötü bir alışkanlık. Postman collection'dan CI pipeline'a kadar automation disciplin.

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.com

Environment: Staging

baseUrl: https://staging-api.example.com
apiKey: stg_xyz456
userEmail: test@example.com

Environment: Production

baseUrl: https://api.example.com
apiKey: prod_... (smoke test only)
userEmail: test@example.com

Request 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.json

Output:

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.html

Every 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.com

Spec’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 user

Pattern 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.json

2-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.

Bu konuda bir projeniz mi var?

Kısa bir özet bırakın, 24 saat içinde size dönüş yapayım.

İletişime Geç