affaan-m/ECC

golang-testing

Table-driven testler, subtestler, benchmark'lar, fuzzing ve test coverage içeren Go test desenleri. TDD metodolojisi ile idiomatic Go uygulamalarını takip eder.

74CollectingWrites filesReads filesRuns scripts
See how to use itView GitHub source
npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/golang-testing"
Automated source guide

Source checked Jul 28, 2026·Refresh due Oct 26, 2026

Reorganized from the pinned upstream SKILL.md

Turn golang-testing's source instructions into a guide you can follow

According to the pinned SKILL.md from affaan-m/ECC: TDD metodolojisini takip eden güvenilir, bakımı kolay testler yazmak için kapsamlı Go test desenleri.

npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/golang-testing"
Check the pinned source

Best fit

  • Table-driven testler, subtestler, benchmark'lar, fuzzing ve test coverage içeren Go test desenleri. TDD metodolojisi ile idiomatic Go uygulamalarını takip eder.

Bring this context

  • A concrete task that matches the documented purpose of golang-testing.
  • The files, examples, or context the task depends on.
  • Your constraints, target environment, and definition of done.

Expected outputs

  • A result that follows the pinned golang-testing instructions.
  • A concise record of assumptions, inputs used, and unresolved questions.
  • A final check against the source workflow and relevant permission signals.

Key source sections

Read golang-testing through these 5 source sections

Sections are extracted automatically from the pinned SKILL.md and link back to the source.

01

Go için TDD Workflow'u

Review the “Go için TDD Workflow'u” section in the pinned source before continuing.

SKILL.md · Go için TDD Workflow'u
Review and apply the “Go için TDD Workflow'u” source section.
02

Ne Zaman Etkinleştirmeli

Yeni Go fonksiyonları veya metodları yazarken

SKILL.md · Ne Zaman Etkinleştirmeli
Yeni Go fonksiyonları veya metodları yazarkenMevcut koda test coverage eklerkenPerformans-kritik kod için benchmark'lar oluştururken
03

RED-GREEN-REFACTOR Döngüsü

Review the “RED-GREEN-REFACTOR Döngüsü” section in the pinned source before continuing.

SKILL.md · RED-GREEN-REFACTOR Döngüsü
Review and apply the “RED-GREEN-REFACTOR Döngüsü” source section.
04

Go'da Adım Adım TDD

Review the “Go'da Adım Adım TDD” section in the pinned source before continuing.

SKILL.md · Go'da Adım Adım TDD
Review and apply the “Go'da Adım Adım TDD” source section.
05

Table-Driven Testler

Go testleri için standart desen. Minimal kodla kapsamlı coverage sağlar.

SKILL.md · Table-Driven Testler
Go testleri için standart desen. Minimal kodla kapsamlı coverage sağlar.

SkillSignal prompt templates

Provide the task, context, and acceptance criteria

These prompts were written by SkillSignal from the source structure; they are not upstream text.

Task-start prompt

Confirm source fit, inputs, and outputs before acting.

Use golang-testing to help me with: [specific task]. Context: [files, data, or background]. Constraints: [environment, scope, and prohibited actions]. Before acting, check the pinned SKILL.md and explain which sections apply, what inputs are still missing, and what you will deliver.

Source-guided execution

Make the Agent explicitly follow the key extracted sections.

Apply the pinned golang-testing source to [task]. Pay particular attention to these source sections: “Go için TDD Workflow'u”, “Ne Zaman Etkinleştirmeli”, “RED-GREEN-REFACTOR Döngüsü”, “Go'da Adım Adım TDD”, “Table-Driven Testler”. Preserve the important decision at each step. Mark facts not covered by the source as “needs confirmation” instead of inventing them. Then verify the result against my acceptance criteria: [criteria].

Result-review prompt

Check omissions, permissions, and source drift before delivery.

Review the current golang-testing result: (1) does it satisfy the original task; (2) were any applicable steps or limits in the pinned SKILL.md missed; (3) did it perform any unauthorized file, command, network, or data action; and (4) which conclusions remain unverified? List issues first, then fix only what the source or user authorization supports.

Output checklist

Verify each item before delivery

The task matches the purpose documented in the SKILL.md.

The source section “Go için TDD Workflow'u” has been checked.

The source section “Ne Zaman Etkinleştirmeli” has been checked.

The source section “RED-GREEN-REFACTOR Döngüsü” has been checked.

The source section “Go'da Adım Adım TDD” has been checked.

Inputs, constraints, and acceptance criteria are explicit.

Unverified facts, compatibility, and outcome claims are clearly marked.

Any file, command, network, or data action has been reviewed.

Choose a different workflow

When another Skill is the better fit

FAQ

What does golang-testing do?

TDD metodolojisini takip eden güvenilir, bakımı kolay testler yazmak için kapsamlı Go test desenleri.

How do I start using golang-testing?

The catalog detected this source-specific install command: npx skills add https://github.com/affaan-m/ECC --skill "docs/tr/skills/golang-testing". Inspect the command and pinned source before running it.

Which Agent platforms does it declare?

No dedicated Agent platform is declared in the pinned source record.

Repository stars
234,327
Repository forks
35,711
Quality
74/100
Source repository last pushed

Quality breakdown

Based on traceable docs and repository signals; stars are not treated as quality.

74/100
Documentation30/30
Specificity16/25
Maintenance20/20
Trust signals8/25
View original Skill.mdThis page is parsed directly from the repository SKILL.md without editorial rewriting. Collected: Jul 28, 2026 · about 2 min

Go Test Desenleri

TDD metodolojisini takip eden güvenilir, bakımı kolay testler yazmak için kapsamlı Go test desenleri.

Ne Zaman Etkinleştirmeli

  • Yeni Go fonksiyonları veya metodları yazarken
  • Mevcut koda test coverage eklerken
  • Performans-kritik kod için benchmark'lar oluştururken
  • Input validation için fuzz testler implement ederken
  • Go projelerinde TDD workflow'u takip ederken

Go için TDD Workflow'u

RED-GREEN-REFACTOR Döngüsü

RED     → Önce başarısız bir test yaz
GREEN   → Testi geçirmek için minimal kod yaz
REFACTOR → Testleri yeşil tutarken kodu iyileştir
REPEAT  → Sonraki gereksinimle devam et

Go'da Adım Adım TDD

// Adım 1: Interface/signature'ı tanımla
// calculator.go
package calculator

func Add(a, b int) int {
    panic("not implemented") // Placeholder
}

// Adım 2: Başarısız test yaz (RED)
// calculator_test.go
package calculator

import "testing"

func TestAdd(t *testing.T) {
    got := Add(2, 3)
    want := 5
    if got != want {
        t.Errorf("Add(2, 3) = %d; want %d", got, want)
    }
}

// Adım 3: Testi çalıştır - FAIL'i doğrula
// $ go test
// --- FAIL: TestAdd (0.00s)
// panic: not implemented

// Adım 4: Minimal kodu implement et (GREEN)
func Add(a, b int) int {
    return a + b
}

// Adım 5: Testi çalıştır - PASS'i doğrula
// $ go test
// PASS

// Adım 6: Gerekirse refactor et, testlerin hala geçtiğini doğrula

Table-Driven Testler

Go testleri için standart desen. Minimal kodla kapsamlı coverage sağlar.

func TestAdd(t *testing.T) {
    tests := []struct {
        name     string
        a, b     int
        expected int
    }{
        {"positive numbers", 2, 3, 5},
        {"negative numbers", -1, -2, -3},
        {"zero values", 0, 0, 0},
        {"mixed signs", -1, 1, 0},
        {"large numbers", 1000000, 2000000, 3000000},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := Add(tt.a, tt.b)
            if got != tt.expected {
                t.Errorf("Add(%d, %d) = %d; want %d",
                    tt.a, tt.b, got, tt.expected)
            }
        })
    }
}

Hata Durumları ile Table-Driven Testler

func TestParseConfig(t *testing.T) {
    tests := []struct {
        name    string
        input   string
        want    *Config
        wantErr bool
    }{
        {
            name:  "valid config",
            input: `{"host": "localhost", "port": 8080}`,
            want:  &Config{Host: "localhost", Port: 8080},
        },
        {
            name:    "invalid JSON",
            input:   `{invalid}`,
            wantErr: true,
        },
        {
            name:    "empty input",
            input:   "",
            wantErr: true,
        },
        {
            name:  "minimal config",
            input: `{}`,
            want:  &Config{}, // Sıfır değer config
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got, err := ParseConfig(tt.input)

            if tt.wantErr {
                if err == nil {
                    t.Error("expected error, got nil")
                }
                return
            }

            if err != nil {
                t.Fatalf("unexpected error: %v", err)
            }

            if !reflect.DeepEqual(got, tt.want) {
                t.Errorf("got %+v; want %+v", got, tt.want)
            }
        })
    }
}

Subtestler ve Sub-benchmark'lar

İlgili Testleri Organize Etme

func TestUser(t *testing.T) {
    // Tüm subtestler tarafından paylaşılan setup
    db := setupTestDB(t)

    t.Run("Create", func(t *testing.T) {
        user := &User{Name: "Alice"}
        err := db.CreateUser(user)
        if err != nil {
            t.Fatalf("CreateUser failed: %v", err)
        }
        if user.ID == "" {
            t.Error("expected user ID to be set")
        }
    })

    t.Run("Get", func(t *testing.T) {
        user, err := db.GetUser("alice-id")
        if err != nil {
            t.Fatalf("GetUser failed: %v", err)
        }
        if user.Name != "Alice" {
            t.Errorf("got name %q; want %q", user.Name, "Alice")
        }
    })

    t.Run("Update", func(t *testing.T) {
        // ...
    })

    t.Run("Delete", func(t *testing.T) {
        // ...
    })
}

Paralel Subtestler

func TestParallel(t *testing.T) {
    tests := []struct {
        name  string
        input string
    }{
        {"case1", "input1"},
        {"case2", "input2"},
        {"case3", "input3"},
    }

    for _, tt := range tests {
        tt := tt // Range değişkenini yakala
        t.Run(tt.name, func(t *testing.T) {
            t.Parallel() // Subtestleri paralel çalıştır
            result := Process(tt.input)
            // assertion'lar...
            _ = result
        })
    }
}

Test Helper'ları

Helper Fonksiyonlar

func setupTestDB(t *testing.T) *sql.DB {
    t.Helper() // Bunu helper fonksiyon olarak işaretle

    db, err := sql.Open("sqlite3", ":memory:")
    if err != nil {
        t.Fatalf("failed to open database: %v", err)
    }

    // Test bittiğinde temizlik
    t.Cleanup(func() {
        db.Close()
    })

    // Migration'ları çalıştır
    if _, err := db.Exec(schema); err != nil {
        t.Fatalf("failed to create schema: %v", err)
    }

    return db
}

func assertNoError(t *testing.T, err error) {
    t.Helper()
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
}

func assertEqual[T comparable](t *testing.T, got, want T) {
    t.Helper()
    if got != want {
        t.Errorf("got %v; want %v", got, want)
    }
}

Geçici Dosyalar ve Dizinler

func TestFileProcessing(t *testing.T) {
    // Geçici dizin oluştur - otomatik olarak temizlenir
    tmpDir := t.TempDir()

    // Test dosyası oluştur
    testFile := filepath.Join(tmpDir, "test.txt")
    err := os.WriteFile(testFile, []byte("test content"), 0644)
    if err != nil {
        t.Fatalf("failed to create test file: %v", err)
    }

    // Testi çalıştır
    result, err := ProcessFile(testFile)
    if err != nil {
        t.Fatalf("ProcessFile failed: %v", err)
    }

    // Assert...
    _ = result
}

Golden File'lar

testdata/ içinde saklanan beklenen çıktı dosyalarına karşı test etme.

var update = flag.Bool("update", false, "update golden files")

func TestRender(t *testing.T) {
    tests := []struct {
        name  string
        input Template
    }{
        {"simple", Template{Name: "test"}},
        {"complex", Template{Name: "test", Items: []string{"a", "b"}}},
    }

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            got := Render(tt.input)

            golden := filepath.Join("testdata", tt.name+".golden")

            if *update {
                // Golden dosyayı güncelle: go test -update
                err := os.WriteFile(golden, got, 0644)
                if err != nil {
                    t.Fatalf("failed to update golden file: %v", err)
                }
            }

            want, err := os.ReadFile(golden)
            if err != nil {
                t.Fatalf("failed to read golden file: %v", err)
            }

            if !bytes.Equal(got, want) {
                t.Errorf("output mismatch:\ngot:\n%s\nwant:\n%s", got, want)
            }
        })
    }
}

Interface'ler ile Mocking

Interface Tabanlı Mocking

// Bağımlılıklar için interface tanımlayın
type UserRepository interface {
    GetUser(id string) (*User, error)
    SaveUser(user *User) error
}

// Production implementasyonu
type PostgresUserRepository struct {
    db *sql.DB
}

func (r *PostgresUserRepository) GetUser(id string) (*User, error) {
    // Gerçek veritabanı sorgusu
}

// Testler için mock implementasyon
type MockUserRepository struct {
    GetUserFunc  func(id string) (*User, error)
    SaveUserFunc func(user *User) error
}

func (m *MockUserRepository) GetUser(id string) (*User, error) {
    return m.GetUserFunc(id)
}

func (m *MockUserRepository) SaveUser(user *User) error {
    return m.SaveUserFunc(user)
}

// Mock kullanarak test
func TestUserService(t *testing.T) {
    mock := &MockUserRepository{
        GetUserFunc: func(id string) (*User, error) {
            if id == "123" {
                return &User{ID: "123", Name: "Alice"}, nil
            }
            return nil, ErrNotFound
        },
    }

    service := NewUserService(mock)

    user, err := service.GetUserProfile("123")
    if err != nil {
        t.Fatalf("unexpected error: %v", err)
    }
    if user.Name != "Alice" {
        t.Errorf("got name %q; want %q", user.Name, "Alice")
    }
}

Benchmark'lar

Temel Benchmark'lar

func BenchmarkProcess(b *testing.B) {
    data := generateTestData(1000)
    b.ResetTimer() // Setup süresini sayma

    for i := 0; i < b.N; i++ {
        Process(data)
    }
}

// Çalıştır: go test -bench=BenchmarkProcess -benchmem
// Çıktı: BenchmarkProcess-8   10000   105234 ns/op   4096 B/op   10 allocs/op

Farklı Boyutlarla Benchmark

func BenchmarkSort(b *testing.B) {
    sizes := []int{100, 1000, 10000, 100000}

    for _, size := range sizes {
        b.Run(fmt.Sprintf("size=%d", size), func(b *testing.B) {
            data := generateRandomSlice(size)
            b.ResetTimer()

            for i := 0; i < b.N; i++ {
                // Zaten sıralanmış veriyi sıralamaktan kaçınmak için kopya oluştur
                tmp := make([]int, len(data))
                copy(tmp, data)
                sort.Ints(tmp)
            }
        })
    }
}

Bellek Tahsis Benchmark'ları

func BenchmarkStringConcat(b *testing.B) {
    parts := []string{"hello", "world", "foo", "bar", "baz"}

    b.Run("plus", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            var s string
            for _, p := range parts {
                s += p
            }
            _ = s
        }
    })

    b.Run("builder", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            var sb strings.Builder
            for _, p := range parts {
                sb.WriteString(p)
            }
            _ = sb.String()
        }
    })

    b.Run("join", func(b *testing.B) {
        for i := 0; i < b.N; i++ {
            _ = strings.Join(parts, "")
        }
    })
}

Fuzzing (Go 1.18+)

Temel Fuzz Testi

func FuzzParseJSON(f *testing.F) {
    // Seed corpus ekle
    f.Add(`{"name": "test"}`)
    f.Add(`{"count": 123}`)
    f.Add(`[]`)
    f.Add(`""`)

    f.Fuzz(func(t *testing.T, input string) {
        var result map[string]interface{}
        err := json.Unmarshal([]byte(input), &result)

        if err != nil {
            // Rastgele input için geçersiz JSON beklenebilir
            return
        }

        // Parsing başarılıysa, yeniden encoding çalışmalı
        _, err = json.Marshal(result)
        if err != nil {
            t.Errorf("Marshal failed after successful Unmarshal: %v", err)
        }
    })
}

// Çalıştır: go test -fuzz=FuzzParseJSON -fuzztime=30s

Birden Çok Input ile Fuzz Testi

func FuzzCompare(f *testing.F) {
    f.Add("hello", "world")
    f.Add("", "")
    f.Add("abc", "abc")

    f.Fuzz(func(t *testing.T, a, b string) {
        result := Compare(a, b)

        // Özellik: Compare(a, a) her zaman 0'a eşit olmalı
        if a == b && result != 0 {
            t.Errorf("Compare(%q, %q) = %d; want 0", a, b, result)
        }

        // Özellik: Compare(a, b) ve Compare(b, a) zıt işarete sahip olmalı
        reverse := Compare(b, a)
        if (result > 0 && reverse >= 0) || (result < 0 && reverse <= 0) {
            if result != 0 || reverse != 0 {
                t.Errorf("Compare(%q, %q) = %d, Compare(%q, %q) = %d; inconsistent",
                    a, b, result, b, a, reverse)
            }
        }
    })
}

Test Coverage

Coverage Çalıştırma

# Temel coverage
go test -cover ./...

# Coverage profili oluştur
go test -coverprofile=coverage.out ./...

# Coverage'ı tarayıcıda görüntüle
go tool cover -html=coverage.out

# Fonksiyona göre coverage görüntüle
go tool cover -func=coverage.out

# Race detection ile coverage
go test -race -coverprofile=coverage.out ./...

Coverage Hedefleri

Kod TipiHedef
Kritik iş mantığı100%
Public API'ler90%+
Genel kod80%+
Oluşturulan kodHariç tut

Oluşturulan Kodu Coverage'dan Hariç Tutma

//go:generate mockgen -source=interface.go -destination=mock_interface.go

// Coverage profile'ında, build tag'leri ile hariç tut:
// go test -cover -tags=!generate ./...

HTTP Handler Testleri

func TestHealthHandler(t *testing.T) {
    // Request oluştur
    req := httptest.NewRequest(http.MethodGet, "/health", nil)
    w := httptest.NewRecorder()

    // Handler'ı çağır
    HealthHandler(w, req)

    // Response'u kontrol et
    resp := w.Result()
    defer resp.Body.Close()

    if resp.StatusCode != http.StatusOK {
        t.Errorf("got status %d; want %d", resp.StatusCode, http.StatusOK)
    }

    body, _ := io.ReadAll(resp.Body)
    if string(body) != "OK" {
        t.Errorf("got body %q; want %q", body, "OK")
    }
}

func TestAPIHandler(t *testing.T) {
    tests := []struct {
        name       string
        method     string
        path       string
        body       string
        wantStatus int
        wantBody   string
    }{
        {
            name:       "get user",
            method:     http.MethodGet,
            path:       "/users/123",
            wantStatus: http.StatusOK,
            wantBody:   `{"id":"123","name":"Alice"}`,
        },
        {
            name:       "not found",
            method:     http.MethodGet,
            path:       "/users/999",
            wantStatus: http.StatusNotFound,
        },
        {
            name:       "create user",
            method:     http.MethodPost,
            path:       "/users",
            body:       `{"name":"Bob"}`,
            wantStatus: http.StatusCreated,
        },
    }

    handler := NewAPIHandler()

    for _, tt := range tests {
        t.Run(tt.name, func(t *testing.T) {
            var body io.Reader
            if tt.body != "" {
                body = strings.NewReader(tt.body)
            }

            req := httptest.NewRequest(tt.method, tt.path, body)
            req.Header.Set("Content-Type", "application/json")
            w := httptest.NewRecorder()

            handler.ServeHTTP(w, req)

            if w.Code != tt.wantStatus {
                t.Errorf("got status %d; want %d", w.Code, tt.wantStatus)
            }

            if tt.wantBody != "" && w.Body.String() != tt.wantBody {
                t.Errorf("got body %q; want %q", w.Body.String(), tt.wantBody)
            }
        })
    }
}

Test Komutları

# Tüm testleri çalıştır
go test ./...

# Verbose çıktı ile testleri çalıştır
go test -v ./...

# Belirli bir testi çalıştır
go test -run TestAdd ./...

# Pattern ile eşleşen testleri çalıştır
go test -run "TestUser/Create" ./...

# Race detector ile testleri çalıştır
go test -race ./...

# Coverage ile testleri çalıştır
go test -cover -coverprofile=coverage.out ./...

# Sadece kısa testleri çalıştır
go test -short ./...

# Timeout ile testleri çalıştır
go test -timeout 30s ./...

# Benchmark'ları çalıştır
go test -bench=. -benchmem ./...

# Fuzzing çalıştır
go test -fuzz=FuzzParse -fuzztime=30s ./...

# Test çalışma sayısı (flaky test tespiti için)
go test -count=10 ./...

En İyi Uygulamalar

YAPIN:

  • Testleri ÖNCE yazın (TDD)
  • Kapsamlı coverage için table-driven testler kullanın
  • İmplementasyon değil davranış test edin
  • Helper fonksiyonlarda t.Helper() kullanın
  • Bağımsız testler için t.Parallel() kullanın
  • Kaynakları t.Cleanup() ile temizleyin
  • Senaryoyu açıklayan anlamlı test isimleri kullanın

YAPMAYIN:

  • Private fonksiyonları doğrudan test etmeyin (public API üzerinden test edin)
  • Testlerde time.Sleep() kullanmayın (channel'lar veya condition'lar kullanın)
  • Flaky testleri göz ardı etmeyin (düzeltin veya kaldırın)
  • Her şeyi mocklamayın (mümkün olduğunda integration testlerini tercih edin)
  • Hata yolu testini atlamayın

CI/CD ile Entegrasyon

# GitHub Actions örneği
test:
  runs-on: ubuntu-latest
  steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-go@v5
      with:
        go-version: '1.22'

    - name: Run tests
      run: go test -race -coverprofile=coverage.out ./...

    - name: Check coverage
      run: |
        go tool cover -func=coverage.out | grep total | awk '{print $3}' | \
        awk -F'%' '{if ($1 < 80) exit 1}'

Unutmayın: Testler dokümantasyondur. Kodunuzun nasıl kullanılması gerektiğini gösterirler. Testleri açık yazın ve güncel tutun.

Source repo
affaan-m/ECC
Skill path
docs/tr/skills/golang-testing/SKILL.md
Commit SHA
4e973d3eaf92
Repository license
MIT
Data collected