tutorial

90 Strategi Pengujian dan CI/CD graphql-go


title: 90 Strategi Pengujian dan CI/CD GraphQL-Go: Panduan Komprehensif untuk Engineer Backend
subtitle: Langkah demi langkah mengamankan kualitas dan keandalan API GraphQL berbasis Golang
date: 2024-06-11
author: engineer.medium

Pendahuluan

API GraphQL menjadi primadona dalam membangun layanan backend yang scalable dan mantap performanya. Apalagi jika kita mengimplementasikannya di Go (graphql-go), kita mendapat kombinasi efisiensi dan type safety tingkat dewa.

Namun, membangun API saja tidak cukup. Kita butuh strategi pengujian (Testing) dan Continuous Integration/Continuous Delivery (CI/CD) yang solid agar perubahan kode tetap terjamin kualitasnya. Artikel ini akan membedah 90 strategi pengujian dan CI/CD untuk proyek graphql-go. Tak lupa, saya sertakan potongan kode, simulasi proses, tabel, dan diagram Mermaid untuk visualisasi.


Rangkaian Pengujian untuk graphql-go

Mari mulai dengan skema besar proses pengujian, dari paling mendasar hingga yang kompleks:

flowchart TD
    A(Unit Test) --> B(Integration Test)
    B --> C(Contract Test)
    C --> D(Schema Validation)
    D --> E(Security Test)
    E --> F(Load Test)
    F --> G(E2E Test)

Sederhananya: Unit ➜ Integration ➜ Contract ➜ Schema ➜ Security ➜ Load ➜ End-to-End.

1. Strategi Unit Testing (15+)

Unit test berfokus pada simpul-simpul terkecil: resolver dan fungsi utility. Contoh:

func TestHelloResolver(t *testing.T) {
    r := NewResolver()
    got, err := r.Hello(context.Background(), nil)
    if err != nil {
        t.Fatalf("expected no error, got %v", err)
    }
    if got != "Hello, world!" {
        t.Fatalf("got %v, want 'Hello, world!'", got)
    }
}

Tips strategi:

  • Mock dependency eksternal (DB, HTTP, Cache)
  • Uji semua cabang logika
  • Tes error handling secara eksplisit
  • Gunakan table-driven test
  • Isolir side effect

2. Strategi Integration Testing (15+)

Integration test menguji komponen-komponen yang saling terhubung, misal resolver + DB.

func TestUserQuery_Integration(t *testing.T) {
    db := InitTestDB()
    defer db.Cleanup()
    r := NewResolverWithDB(db)
    got, err := r.User(context.Background(), &UserArgs{ID: "abc123"})
    if err != nil || got.Name != "Budi" {
        t.Fatalf("unexpected: %v, %+v", err, got)
    }
}

Strategi lanjutan:

  • Injeksi dependency mock
  • Setup dan teardown data
  • Simulasi kegagalan jaringan/DB

3. Contract Testing (10+)

Pastikan server GraphQL konsisten dengan spesifikasi schema:

gql-contract-tester --schema schema.graphql --endpoint http://localhost:8080/graphql

Tips:

  • Simpan snapshot schema pada tiap PR
  • Gunakan schema diff tools
  • Cek resolabilitas semua query/mutation utama

4. Schema Validation & Codegen (10+)

Validasi schema memastikan breaking change tidak “ngumpet”.

# Validasi schema
gqlint schema.graphql

# Code generation: Go struct dari schema
gqlgen generate

Dengan auto-codegen, banyak bug teratasi sejak tahap compile-time.

5. Security Testing (10+)

Simulasikan query injection, invalid input, dan introspeksi tak diinginkan.

Test CaseTujuanTools
Query injectionValidasi sanitizerCustom/Fuzz
Deep recursion attackBypass depth limitationGraphQL Fuzzer
Introspection disablingCegah schema leakageCurl/Postman

Contoh pengujian depth-limit:

func TestDepthLimit(t *testing.T) {
    // Coba query nested terlalu dalam
    query := `{ user { friends { friends { friends { name }}}}}`
    resp := DoGraphQLRequest(query)
    if resp.HasError("exceeds max depth") == false {
        t.Errorf("should block deep nested query")
    }
}

6. Load & Performance Testing (10+)

Uji beban query GraphQL dan latency response.

Tools: k6, Gatling, Vegeta.

Contoh skrip k6:

import http from "k6/http";
export default function () {
  http.post("http://localhost:8080/graphql", JSON.stringify({ query: "{users{name}}" }));
}

Monitoring latency, error rate, dan resources secara otomatis.

7. End-to-End Testing (10+)

Uji seluruh flow user: frontend ➜ backend ➜ DB ➜ frontend.

Tools: Cypress, Playwright, Postman.

Contoh custom E2E dengan Go:

func TestE2E_UserFlow(t *testing.T) {
    server := StartTestServer()
    defer server.Shutdown()
    token := LoginAndGetToken()
    req := MakeAuthenticatedGraphQLRequest(token, `{me{name}}`)
    if resp := req.Do(); resp.Data["me"]["name"] != "Budi" {
        t.Fatalf("E2E fail: %+v", resp)
    }
}

Strategi CI/CD untuk graphql-go

CI/CD adalah penenang developer: push kode, otomatis build, testing, deploy.

flowchart LR
    A[Push to GitHub] --> B{Lint & Build}
    B --> C(UnitTests)
    C --> D(IntegrationTests)
    D --|Pass|--> E[Contract/Schema Test]
    E --|Pass|--> F[Deploy to Staging]
    F --|Manual Approve|--> G[Deploy to Production]

8. Github Actions/CI Pipeline (10+)

Sample .github/workflows/ci.yml:

name: GraphQL Go CI

on: [push, pull_request]

jobs:
  build-and-test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Set up Go
        uses: actions/setup-go@v3
        with:
          go-version: 1.22

      - name: Lint
        run: go vet ./...

      - name: Build
        run: go build ./...

      - name: Unit tests
        run: go test -v -short ./...

      - name: Integration tests
        run: go test -v -tags=integration ./...

      - name: Schema validation
        run: gqlint schema.graphql

      - name: Contract test
        run: gql-contract-tester --schema schema.graphql --endpoint http://localhost:8080/graphql

9. Otomatisasi Deployment (5+)

Integrasi otomatis Docker & deployment ke cloud (Kubernetes/Heroku/etc):

- name: Build Docker image
  run: docker build -t registry.io/project/graphql-go:$GITHUB_SHA .

- name: Push to registry
  run: docker push registry.io/project/graphql-go:$GITHUB_SHA

- name: Deploy to k8s
  run: kubectl set image deployment/graphql-go graphql-go=registry.io/project/graphql-go:$GITHUB_SHA

Manfaatkan environment staging sebelum approval ke production.


Simulasi: Workflow CI/CD dengan 90 Strategi

Apa jadinya jika semua strategi dijalankan secara terstruktur? Berikut simulasi alur:

KategoriContoh PraktikJumlah Strategi
Unit TestTable-driven, Error-case, Mock dep, Data edge-case15+
Integration TestPer-connektor, Mock DB, DB failover, API chaining, Side effects15+
Contract TestSnapshot schema diff, Endpoint contract validate10+
Schema ValidationLint, Codegen safety, Build type10+
Security TestQuery injection, Recursion, Introspection disable, Fuzzing10+
Load Testk6/Vegata, Custom script, Latency script, DB under heavy10+
E2E TestFull user journey, Login/register, CRUD, AuthZ, Session timeout10+
CI PipelineParallel job, Matrix test, Artifacts, Lint, Static analysis10+
Deploy AutomationDocker, Image scan, Blue/Green deploy, Rollback, Canary5+

Total: 90+ strategi komplementer.


Penutup

Mengimplementasikan 90 strategi pengujian dan CI/CD bukan sekadar “testing”, tapi cara berpikir sebagai engineer production-grade. Dengan praktik terbaik mulai dari unit, integrasi, kontrak, hingga beban dan keamanan, didukung pipeline CI/CD yang otomatis—kita mampu menjaga GraphQL API Go tetap solid, secure, dan easy to ship.

Sudah siap level-up?
Terapkan strategi di atas ke proyek mu dan selamat menikmati ketenangan deploy minggu malam!


Referensi:

comments powered by Disqus