[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6JV31WA2CC2QQDJVCJ2T2QS":3,"skill-same:01M6JV31WA2CC2QQDJVCJ2T2QS":74},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":50,"commitSha":51,"skillDirectory":52,"forksCount":53,"repositoryHtmlUrl":54,"repositoryHomepageUrl":55,"ownerHtmlUrl":56,"ownerBlogUrl":57,"ownerDescription":58,"updatedAt":59,"install":60,"resources":73},"01M6JV31WA2CC2QQDJVCJ2T2QS","golang-testing",null,"Go testing patterns including table-driven tests, subtests, benchmarks, fuzzing, and test coverage. Follows TDD methodology with idiomatic Go practices.","hashgraph-online\u002Fawesome-codex-plugins","hashgraph-online","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F160371962?v=4","01M6CNB6NRJVNNGN14TR01Q6D3","HOL (Hashgraph Online)","01M6JT1HSKKG9V68KQAQGBA7XP",1559,"Apache-2.0","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002FColin4k1024\u002Ftsp\u002Fskills\u002Fgolang-testing\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"golang","golang testing","testing","go testing","idiomatic go","idiomatic","with","driven","tests","patterns","benchmarks","test coverage","coverage","table","testing patterns","methodology","test","tdd","fuzzing","go","2026-11-10 10:12:30",false,"---\nname: golang-testing\ndescription: Go testing patterns including table-driven tests, subtests, benchmarks, fuzzing, and test coverage. Follows TDD methodology with idiomatic Go practices.\norigin: ECC\n---\n\n# Go Testing Patterns\n\nComprehensive Go testing patterns for writing reliable, maintainable tests following TDD methodology.\n\n## When to Activate\n\n- Writing new Go functions or methods\n- Adding test coverage to existing code\n- Creating benchmarks for performance-critical code\n- Implementing fuzz tests for input validation\n- Following TDD workflow in Go projects\n\n## TDD Workflow for Go\n\n### The RED-GREEN-REFACTOR Cycle\n\n```\nRED     → Write a failing test first\nGREEN   → Write minimal code to pass the test\nREFACTOR → Improve code while keeping tests green\nREPEAT  → Continue with next requirement\n```\n\n### Step-by-Step TDD in Go\n\n```go\n\u002F\u002F Step 1: Define the interface\u002Fsignature\n\u002F\u002F calculator.go\npackage calculator\n\nfunc Add(a, b int) int {\n    panic(\"not implemented\") \u002F\u002F Placeholder\n}\n\n\u002F\u002F Step 2: Write failing test (RED)\n\u002F\u002F calculator_test.go\npackage calculator\n\nimport \"testing\"\n\nfunc TestAdd(t *testing.T) {\n    got := Add(2, 3)\n    want := 5\n    if got != want {\n        t.Errorf(\"Add(2, 3) = %d; want %d\", got, want)\n    }\n}\n\n\u002F\u002F Step 3: Run test - verify FAIL\n\u002F\u002F $ go test\n\u002F\u002F --- FAIL: TestAdd (0.00s)\n\u002F\u002F panic: not implemented\n\n\u002F\u002F Step 4: Implement minimal code (GREEN)\nfunc Add(a, b int) int {\n    return a + b\n}\n\n\u002F\u002F Step 5: Run test - verify PASS\n\u002F\u002F $ go test\n\u002F\u002F PASS\n\n\u002F\u002F Step 6: Refactor if needed, verify tests still pass\n```\n\n## Table-Driven Tests\n\nThe standard pattern for Go tests. Enables comprehensive coverage with minimal code.\n\n```go\nfunc TestAdd(t *testing.T) {\n    tests := []struct {\n        name     string\n        a, b     int\n        expected int\n    }{\n        {\"positive numbers\", 2, 3, 5},\n        {\"negative numbers\", -1, -2, -3},\n        {\"zero values\", 0, 0, 0},\n        {\"mixed signs\", -1, 1, 0},\n        {\"large numbers\", 1000000, 2000000, 3000000},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            got := Add(tt.a, tt.b)\n            if got != tt.expected {\n                t.Errorf(\"Add(%d, %d) = %d; want %d\",\n                    tt.a, tt.b, got, tt.expected)\n            }\n        })\n    }\n}\n```\n\n### Table-Driven Tests with Error Cases\n\n```go\nfunc TestParseConfig(t *testing.T) {\n    tests := []struct {\n        name    string\n        input   string\n        want    *Config\n        wantErr bool\n    }{\n        {\n            name:  \"valid config\",\n            input: `{\"host\": \"localhost\", \"port\": 8080}`,\n            want:  &Config{Host: \"localhost\", Port: 8080},\n        },\n        {\n            name:    \"invalid JSON\",\n            input:   `{invalid}`,\n            wantErr: true,\n        },\n        {\n            name:    \"empty input\",\n            input:   \"\",\n            wantErr: true,\n        },\n        {\n            name:  \"minimal config\",\n            input: `{}`,\n            want:  &Config{}, \u002F\u002F Zero value config\n        },\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            got, err := ParseConfig(tt.input)\n\n            if tt.wantErr {\n                if err == nil {\n                    t.Error(\"expected error, got nil\")\n                }\n                return\n            }\n\n            if err != nil {\n                t.Fatalf(\"unexpected error: %v\", err)\n            }\n\n            if !reflect.DeepEqual(got, tt.want) {\n                t.Errorf(\"got %+v; want %+v\", got, tt.want)\n            }\n        })\n    }\n}\n```\n\n## Subtests and Sub-benchmarks\n\n### Organizing Related Tests\n\n```go\nfunc TestUser(t *testing.T) {\n    \u002F\u002F Setup shared by all subtests\n    db := setupTestDB(t)\n\n    t.Run(\"Create\", func(t *testing.T) {\n        user := &User{Name: \"Alice\"}\n        err := db.CreateUser(user)\n        if err != nil {\n            t.Fatalf(\"CreateUser failed: %v\", err)\n        }\n        if user.ID == \"\" {\n            t.Error(\"expected user ID to be set\")\n        }\n    })\n\n    t.Run(\"Get\", func(t *testing.T) {\n        user, err := db.GetUser(\"alice-id\")\n        if err != nil {\n            t.Fatalf(\"GetUser failed: %v\", err)\n        }\n        if user.Name != \"Alice\" {\n            t.Errorf(\"got name %q; want %q\", user.Name, \"Alice\")\n        }\n    })\n\n    t.Run(\"Update\", func(t *testing.T) {\n        \u002F\u002F ...\n    })\n\n    t.Run(\"Delete\", func(t *testing.T) {\n        \u002F\u002F ...\n    })\n}\n```\n\n### Parallel Subtests\n\n```go\nfunc TestParallel(t *testing.T) {\n    tests := []struct {\n        name  string\n        input string\n    }{\n        {\"case1\", \"input1\"},\n        {\"case2\", \"input2\"},\n        {\"case3\", \"input3\"},\n    }\n\n    for _, tt := range tests {\n        tt := tt \u002F\u002F Capture range variable\n        t.Run(tt.name, func(t *testing.T) {\n            t.Parallel() \u002F\u002F Run subtests in parallel\n            result := Process(tt.input)\n            \u002F\u002F assertions...\n            _ = result\n        })\n    }\n}\n```\n\n## Test Helpers\n\n### Helper Functions\n\n```go\nfunc setupTestDB(t *testing.T) *sql.DB {\n    t.Helper() \u002F\u002F Marks this as a helper function\n\n    db, err := sql.Open(\"sqlite3\", \":memory:\")\n    if err != nil {\n        t.Fatalf(\"failed to open database: %v\", err)\n    }\n\n    \u002F\u002F Cleanup when test finishes\n    t.Cleanup(func() {\n        db.Close()\n    })\n\n    \u002F\u002F Run migrations\n    if _, err := db.Exec(schema); err != nil {\n        t.Fatalf(\"failed to create schema: %v\", err)\n    }\n\n    return db\n}\n\nfunc assertNoError(t *testing.T, err error) {\n    t.Helper()\n    if err != nil {\n        t.Fatalf(\"unexpected error: %v\", err)\n    }\n}\n\nfunc assertEqual[T comparable](t *testing.T, got, want T) {\n    t.Helper()\n    if got != want {\n        t.Errorf(\"got %v; want %v\", got, want)\n    }\n}\n```\n\n### Temporary Files and Directories\n\n```go\nfunc TestFileProcessing(t *testing.T) {\n    \u002F\u002F Create temp directory - automatically cleaned up\n    tmpDir := t.TempDir()\n\n    \u002F\u002F Create test file\n    testFile := filepath.Join(tmpDir, \"test.txt\")\n    err := os.WriteFile(testFile, []byte(\"test content\"), 0644)\n    if err != nil {\n        t.Fatalf(\"failed to create test file: %v\", err)\n    }\n\n    \u002F\u002F Run test\n    result, err := ProcessFile(testFile)\n    if err != nil {\n        t.Fatalf(\"ProcessFile failed: %v\", err)\n    }\n\n    \u002F\u002F Assert...\n    _ = result\n}\n```\n\n## Golden Files\n\nTesting against expected output files stored in `testdata\u002F`.\n\n```go\nvar update = flag.Bool(\"update\", false, \"update golden files\")\n\nfunc TestRender(t *testing.T) {\n    tests := []struct {\n        name  string\n        input Template\n    }{\n        {\"simple\", Template{Name: \"test\"}},\n        {\"complex\", Template{Name: \"test\", Items: []string{\"a\", \"b\"}}},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            got := Render(tt.input)\n\n            golden := filepath.Join(\"testdata\", tt.name+\".golden\")\n\n            if *update {\n                \u002F\u002F Update golden file: go test -update\n                err := os.WriteFile(golden, got, 0644)\n                if err != nil {\n                    t.Fatalf(\"failed to update golden file: %v\", err)\n                }\n            }\n\n            want, err := os.ReadFile(golden)\n            if err != nil {\n                t.Fatalf(\"failed to read golden file: %v\", err)\n            }\n\n            if !bytes.Equal(got, want) {\n                t.Errorf(\"output mismatch:\\ngot:\\n%s\\nwant:\\n%s\", got, want)\n            }\n        })\n    }\n}\n```\n\n## Mocking with Interfaces\n\n### Interface-Based Mocking\n\n```go\n\u002F\u002F Define interface for dependencies\ntype UserRepository interface {\n    GetUser(id string) (*User, error)\n    SaveUser(user *User) error\n}\n\n\u002F\u002F Production implementation\ntype PostgresUserRepository struct {\n    db *sql.DB\n}\n\nfunc (r *PostgresUserRepository) GetUser(id string) (*User, error) {\n    \u002F\u002F Real database query\n}\n\n\u002F\u002F Mock implementation for tests\ntype MockUserRepository struct {\n    GetUserFunc  func(id string) (*User, error)\n    SaveUserFunc func(user *User) error\n}\n\nfunc (m *MockUserRepository) GetUser(id string) (*User, error) {\n    return m.GetUserFunc(id)\n}\n\nfunc (m *MockUserRepository) SaveUser(user *User) error {\n    return m.SaveUserFunc(user)\n}\n\n\u002F\u002F Test using mock\nfunc TestUserService(t *testing.T) {\n    mock := &MockUserRepository{\n        GetUserFunc: func(id string) (*User, error) {\n            if id == \"123\" {\n                return &User{ID: \"123\", Name: \"Alice\"}, nil\n            }\n            return nil, ErrNotFound\n        },\n    }\n\n    service := NewUserService(mock)\n\n    user, err := service.GetUserProfile(\"123\")\n    if err != nil {\n        t.Fatalf(\"unexpected error: %v\", err)\n    }\n    if user.Name != \"Alice\" {\n        t.Errorf(\"got name %q; want %q\", user.Name, \"Alice\")\n    }\n}\n```\n\n## Benchmarks\n\n### Basic Benchmarks\n\n```go\nfunc BenchmarkProcess(b *testing.B) {\n    data := generateTestData(1000)\n    b.ResetTimer() \u002F\u002F Don't count setup time\n\n    for i := 0; i \u003C b.N; i++ {\n        Process(data)\n    }\n}\n\n\u002F\u002F Run: go test -bench=BenchmarkProcess -benchmem\n\u002F\u002F Output: BenchmarkProcess-8   10000   105234 ns\u002Fop   4096 B\u002Fop   10 allocs\u002Fop\n```\n\n### Benchmark with Different Sizes\n\n```go\nfunc BenchmarkSort(b *testing.B) {\n    sizes := []int{100, 1000, 10000, 100000}\n\n    for _, size := range sizes {\n        b.Run(fmt.Sprintf(\"size=%d\", size), func(b *testing.B) {\n            data := generateRandomSlice(size)\n            b.ResetTimer()\n\n            for i := 0; i \u003C b.N; i++ {\n                \u002F\u002F Make a copy to avoid sorting already sorted data\n                tmp := make([]int, len(data))\n                copy(tmp, data)\n                sort.Ints(tmp)\n            }\n        })\n    }\n}\n```\n\n### Memory Allocation Benchmarks\n\n```go\nfunc BenchmarkStringConcat(b *testing.B) {\n    parts := []string{\"hello\", \"world\", \"foo\", \"bar\", \"baz\"}\n\n    b.Run(\"plus\", func(b *testing.B) {\n        for i := 0; i \u003C b.N; i++ {\n            var s string\n            for _, p := range parts {\n                s += p\n            }\n            _ = s\n        }\n    })\n\n    b.Run(\"builder\", func(b *testing.B) {\n        for i := 0; i \u003C b.N; i++ {\n            var sb strings.Builder\n            for _, p := range parts {\n                sb.WriteString(p)\n            }\n            _ = sb.String()\n        }\n    })\n\n    b.Run(\"join\", func(b *testing.B) {\n        for i := 0; i \u003C b.N; i++ {\n            _ = strings.Join(parts, \"\")\n        }\n    })\n}\n```\n\n## Fuzzing (Go 1.18+)\n\n### Basic Fuzz Test\n\n```go\nfunc FuzzParseJSON(f *testing.F) {\n    \u002F\u002F Add seed corpus\n    f.Add(`{\"name\": \"test\"}`)\n    f.Add(`{\"count\": 123}`)\n    f.Add(`[]`)\n    f.Add(`\"\"`)\n\n    f.Fuzz(func(t *testing.T, input string) {\n        var result map[string]interface{}\n        err := json.Unmarshal([]byte(input), &result)\n\n        if err != nil {\n            \u002F\u002F Invalid JSON is expected for random input\n            return\n        }\n\n        \u002F\u002F If parsing succeeded, re-encoding should work\n        _, err = json.Marshal(result)\n        if err != nil {\n            t.Errorf(\"Marshal failed after successful Unmarshal: %v\", err)\n        }\n    })\n}\n\n\u002F\u002F Run: go test -fuzz=FuzzParseJSON -fuzztime=30s\n```\n\n### Fuzz Test with Multiple Inputs\n\n```go\nfunc FuzzCompare(f *testing.F) {\n    f.Add(\"hello\", \"world\")\n    f.Add(\"\", \"\")\n    f.Add(\"abc\", \"abc\")\n\n    f.Fuzz(func(t *testing.T, a, b string) {\n        result := Compare(a, b)\n\n        \u002F\u002F Property: Compare(a, a) should always equal 0\n        if a == b && result != 0 {\n            t.Errorf(\"Compare(%q, %q) = %d; want 0\", a, b, result)\n        }\n\n        \u002F\u002F Property: Compare(a, b) and Compare(b, a) should have opposite signs\n        reverse := Compare(b, a)\n        if (result > 0 && reverse >= 0) || (result \u003C 0 && reverse \u003C= 0) {\n            if result != 0 || reverse != 0 {\n                t.Errorf(\"Compare(%q, %q) = %d, Compare(%q, %q) = %d; inconsistent\",\n                    a, b, result, b, a, reverse)\n            }\n        }\n    })\n}\n```\n\n## Test Coverage\n\n### Running Coverage\n\n```bash\n# Basic coverage\ngo test -cover .\u002F...\n\n# Generate coverage profile\ngo test -coverprofile=coverage.out .\u002F...\n\n# View coverage in browser\ngo tool cover -html=coverage.out\n\n# View coverage by function\ngo tool cover -func=coverage.out\n\n# Coverage with race detection\ngo test -race -coverprofile=coverage.out .\u002F...\n```\n\n### Coverage Targets\n\n| Code Type | Target |\n|-----------|--------|\n| Critical business logic | 100% |\n| Public APIs | 90%+ |\n| General code | 80%+ |\n| Generated code | Exclude |\n\n### Excluding Generated Code from Coverage\n\n```go\n\u002F\u002Fgo:generate mockgen -source=interface.go -destination=mock_interface.go\n\n\u002F\u002F In coverage profile, exclude with build tags:\n\u002F\u002F go test -cover -tags=!generate .\u002F...\n```\n\n## HTTP Handler Testing\n\n```go\nfunc TestHealthHandler(t *testing.T) {\n    \u002F\u002F Create request\n    req := httptest.NewRequest(http.MethodGet, \"\u002Fhealth\", nil)\n    w := httptest.NewRecorder()\n\n    \u002F\u002F Call handler\n    HealthHandler(w, req)\n\n    \u002F\u002F Check response\n    resp := w.Result()\n    defer resp.Body.Close()\n\n    if resp.StatusCode != http.StatusOK {\n        t.Errorf(\"got status %d; want %d\", resp.StatusCode, http.StatusOK)\n    }\n\n    body, _ := io.ReadAll(resp.Body)\n    if string(body) != \"OK\" {\n        t.Errorf(\"got body %q; want %q\", body, \"OK\")\n    }\n}\n\nfunc TestAPIHandler(t *testing.T) {\n    tests := []struct {\n        name       string\n        method     string\n        path       string\n        body       string\n        wantStatus int\n        wantBody   string\n    }{\n        {\n            name:       \"get user\",\n            method:     http.MethodGet,\n            path:       \"\u002Fusers\u002F123\",\n            wantStatus: http.StatusOK,\n            wantBody:   `{\"id\":\"123\",\"name\":\"Alice\"}`,\n        },\n        {\n            name:       \"not found\",\n            method:     http.MethodGet,\n            path:       \"\u002Fusers\u002F999\",\n            wantStatus: http.StatusNotFound,\n        },\n        {\n            name:       \"create user\",\n            method:     http.MethodPost,\n            path:       \"\u002Fusers\",\n            body:       `{\"name\":\"Bob\"}`,\n            wantStatus: http.StatusCreated,\n        },\n    }\n\n    handler := NewAPIHandler()\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            var body io.Reader\n            if tt.body != \"\" {\n                body = strings.NewReader(tt.body)\n            }\n\n            req := httptest.NewRequest(tt.method, tt.path, body)\n            req.Header.Set(\"Content-Type\", \"application\u002Fjson\")\n            w := httptest.NewRecorder()\n\n            handler.ServeHTTP(w, req)\n\n            if w.Code != tt.wantStatus {\n                t.Errorf(\"got status %d; want %d\", w.Code, tt.wantStatus)\n            }\n\n            if tt.wantBody != \"\" && w.Body.String() != tt.wantBody {\n                t.Errorf(\"got body %q; want %q\", w.Body.String(), tt.wantBody)\n            }\n        })\n    }\n}\n```\n\n## Testing Commands\n\n```bash\n# Run all tests\ngo test .\u002F...\n\n# Run tests with verbose output\ngo test -v .\u002F...\n\n# Run specific test\ngo test -run TestAdd .\u002F...\n\n# Run tests matching pattern\ngo test -run \"TestUser\u002FCreate\" .\u002F...\n\n# Run tests with race detector\ngo test -race .\u002F...\n\n# Run tests with coverage\ngo test -cover -coverprofile=coverage.out .\u002F...\n\n# Run short tests only\ngo test -short .\u002F...\n\n# Run tests with timeout\ngo test -timeout 30s .\u002F...\n\n# Run benchmarks\ngo test -bench=. -benchmem .\u002F...\n\n# Run fuzzing\ngo test -fuzz=FuzzParse -fuzztime=30s .\u002F...\n\n# Count test runs (for flaky test detection)\ngo test -count=10 .\u002F...\n```\n\n## Best Practices\n\n**DO:**\n- Write tests FIRST (TDD)\n- Use table-driven tests for comprehensive coverage\n- Test behavior, not implementation\n- Use `t.Helper()` in helper functions\n- Use `t.Parallel()` for independent tests\n- Clean up resources with `t.Cleanup()`\n- Use meaningful test names that describe the scenario\n\n**DON'T:**\n- Test private functions directly (test through public API)\n- Use `time.Sleep()` in tests (use channels or conditions)\n- Ignore flaky tests (fix or remove them)\n- Mock everything (prefer integration tests when possible)\n- Skip error path testing\n\n## Integration with CI\u002FCD\n\n```yaml\n# GitHub Actions example\ntest:\n  runs-on: ubuntu-latest\n  steps:\n    - uses: actions\u002Fcheckout@v4\n    - uses: actions\u002Fsetup-go@v5\n      with:\n        go-version: '1.22'\n\n    - name: Run tests\n      run: go test -race -coverprofile=coverage.out .\u002F...\n\n    - name: Check coverage\n      run: |\n        go tool cover -func=coverage.out | grep total | awk '{print $3}' | \\\n        awk -F'%' '{if ($1 \u003C 80) exit 1}'\n```\n\n**Remember**: Tests are documentation. They show how your code is meant to be used. Write them clearly and keep them up to date.\n","# Go Testing Patterns\n\nComprehensive Go testing patterns for writing reliable, maintainable tests following TDD methodology.\n\n## When to Activate\n\n- Writing new Go functions or methods\n- Adding test coverage to existing code\n- Creating benchmarks for performance-critical code\n- Implementing fuzz tests for input validation\n- Following TDD workflow in Go projects\n\n## TDD Workflow for Go\n\n### The RED-GREEN-REFACTOR Cycle\n\n```\nRED     → Write a failing test first\nGREEN   → Write minimal code to pass the test\nREFACTOR → Improve code while keeping tests green\nREPEAT  → Continue with next requirement\n```\n\n### Step-by-Step TDD in Go\n\n```go\n\u002F\u002F Step 1: Define the interface\u002Fsignature\n\u002F\u002F calculator.go\npackage calculator\n\nfunc Add(a, b int) int {\n    panic(\"not implemented\") \u002F\u002F Placeholder\n}\n\n\u002F\u002F Step 2: Write failing test (RED)\n\u002F\u002F calculator_test.go\npackage calculator\n\nimport \"testing\"\n\nfunc TestAdd(t *testing.T) {\n    got := Add(2, 3)\n    want := 5\n    if got != want {\n        t.Errorf(\"Add(2, 3) = %d; want %d\", got, want)\n    }\n}\n\n\u002F\u002F Step 3: Run test - verify FAIL\n\u002F\u002F $ go test\n\u002F\u002F --- FAIL: TestAdd (0.00s)\n\u002F\u002F panic: not implemented\n\n\u002F\u002F Step 4: Implement minimal code (GREEN)\nfunc Add(a, b int) int {\n    return a + b\n}\n\n\u002F\u002F Step 5: Run test - verify PASS\n\u002F\u002F $ go test\n\u002F\u002F PASS\n\n\u002F\u002F Step 6: Refactor if needed, verify tests still pass\n```\n\n## Table-Driven Tests\n\nThe standard pattern for Go tests. Enables comprehensive coverage with minimal code.\n\n```go\nfunc TestAdd(t *testing.T) {\n    tests := []struct {\n        name     string\n        a, b     int\n        expected int\n    }{\n        {\"positive numbers\", 2, 3, 5},\n        {\"negative numbers\", -1, -2, -3},\n        {\"zero values\", 0, 0, 0},\n        {\"mixed signs\", -1, 1, 0},\n        {\"large numbers\", 1000000, 2000000, 3000000},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            got := Add(tt.a, tt.b)\n            if got != tt.expected {\n                t.Errorf(\"Add(%d, %d) = %d; want %d\",\n                    tt.a, tt.b, got, tt.expected)\n            }\n        })\n    }\n}\n```\n\n### Table-Driven Tests with Error Cases\n\n```go\nfunc TestParseConfig(t *testing.T) {\n    tests := []struct {\n        name    string\n        input   string\n        want    *Config\n        wantErr bool\n    }{\n        {\n            name:  \"valid config\",\n            input: `{\"host\": \"localhost\", \"port\": 8080}`,\n            want:  &Config{Host: \"localhost\", Port: 8080},\n        },\n        {\n            name:    \"invalid JSON\",\n            input:   `{invalid}`,\n            wantErr: true,\n        },\n        {\n            name:    \"empty input\",\n            input:   \"\",\n            wantErr: true,\n        },\n        {\n            name:  \"minimal config\",\n            input: `{}`,\n            want:  &Config{}, \u002F\u002F Zero value config\n        },\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            got, err := ParseConfig(tt.input)\n\n            if tt.wantErr {\n                if err == nil {\n                    t.Error(\"expected error, got nil\")\n                }\n                return\n            }\n\n            if err != nil {\n                t.Fatalf(\"unexpected error: %v\", err)\n            }\n\n            if !reflect.DeepEqual(got, tt.want) {\n                t.Errorf(\"got %+v; want %+v\", got, tt.want)\n            }\n        })\n    }\n}\n```\n\n## Subtests and Sub-benchmarks\n\n### Organizing Related Tests\n\n```go\nfunc TestUser(t *testing.T) {\n    \u002F\u002F Setup shared by all subtests\n    db := setupTestDB(t)\n\n    t.Run(\"Create\", func(t *testing.T) {\n        user := &User{Name: \"Alice\"}\n        err := db.CreateUser(user)\n        if err != nil {\n            t.Fatalf(\"CreateUser failed: %v\", err)\n        }\n        if user.ID == \"\" {\n            t.Error(\"expected user ID to be set\")\n        }\n    })\n\n    t.Run(\"Get\", func(t *testing.T) {\n        user, err := db.GetUser(\"alice-id\")\n        if err != nil {\n            t.Fatalf(\"GetUser failed: %v\", err)\n        }\n        if user.Name != \"Alice\" {\n            t.Errorf(\"got name %q; want %q\", user.Name, \"Alice\")\n        }\n    })\n\n    t.Run(\"Update\", func(t *testing.T) {\n        \u002F\u002F ...\n    })\n\n    t.Run(\"Delete\", func(t *testing.T) {\n        \u002F\u002F ...\n    })\n}\n```\n\n### Parallel Subtests\n\n```go\nfunc TestParallel(t *testing.T) {\n    tests := []struct {\n        name  string\n        input string\n    }{\n        {\"case1\", \"input1\"},\n        {\"case2\", \"input2\"},\n        {\"case3\", \"input3\"},\n    }\n\n    for _, tt := range tests {\n        tt := tt \u002F\u002F Capture range variable\n        t.Run(tt.name, func(t *testing.T) {\n            t.Parallel() \u002F\u002F Run subtests in parallel\n            result := Process(tt.input)\n            \u002F\u002F assertions...\n            _ = result\n        })\n    }\n}\n```\n\n## Test Helpers\n\n### Helper Functions\n\n```go\nfunc setupTestDB(t *testing.T) *sql.DB {\n    t.Helper() \u002F\u002F Marks this as a helper function\n\n    db, err := sql.Open(\"sqlite3\", \":memory:\")\n    if err != nil {\n        t.Fatalf(\"failed to open database: %v\", err)\n    }\n\n    \u002F\u002F Cleanup when test finishes\n    t.Cleanup(func() {\n        db.Close()\n    })\n\n    \u002F\u002F Run migrations\n    if _, err := db.Exec(schema); err != nil {\n        t.Fatalf(\"failed to create schema: %v\", err)\n    }\n\n    return db\n}\n\nfunc assertNoError(t *testing.T, err error) {\n    t.Helper()\n    if err != nil {\n        t.Fatalf(\"unexpected error: %v\", err)\n    }\n}\n\nfunc assertEqual[T comparable](t *testing.T, got, want T) {\n    t.Helper()\n    if got != want {\n        t.Errorf(\"got %v; want %v\", got, want)\n    }\n}\n```\n\n### Temporary Files and Directories\n\n```go\nfunc TestFileProcessing(t *testing.T) {\n    \u002F\u002F Create temp directory - automatically cleaned up\n    tmpDir := t.TempDir()\n\n    \u002F\u002F Create test file\n    testFile := filepath.Join(tmpDir, \"test.txt\")\n    err := os.WriteFile(testFile, []byte(\"test content\"), 0644)\n    if err != nil {\n        t.Fatalf(\"failed to create test file: %v\", err)\n    }\n\n    \u002F\u002F Run test\n    result, err := ProcessFile(testFile)\n    if err != nil {\n        t.Fatalf(\"ProcessFile failed: %v\", err)\n    }\n\n    \u002F\u002F Assert...\n    _ = result\n}\n```\n\n## Golden Files\n\nTesting against expected output files stored in `testdata\u002F`.\n\n```go\nvar update = flag.Bool(\"update\", false, \"update golden files\")\n\nfunc TestRender(t *testing.T) {\n    tests := []struct {\n        name  string\n        input Template\n    }{\n        {\"simple\", Template{Name: \"test\"}},\n        {\"complex\", Template{Name: \"test\", Items: []string{\"a\", \"b\"}}},\n    }\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            got := Render(tt.input)\n\n            golden := filepath.Join(\"testdata\", tt.name+\".golden\")\n\n            if *update {\n                \u002F\u002F Update golden file: go test -update\n                err := os.WriteFile(golden, got, 0644)\n                if err != nil {\n                    t.Fatalf(\"failed to update golden file: %v\", err)\n                }\n            }\n\n            want, err := os.ReadFile(golden)\n            if err != nil {\n                t.Fatalf(\"failed to read golden file: %v\", err)\n            }\n\n            if !bytes.Equal(got, want) {\n                t.Errorf(\"output mismatch:\\ngot:\\n%s\\nwant:\\n%s\", got, want)\n            }\n        })\n    }\n}\n```\n\n## Mocking with Interfaces\n\n### Interface-Based Mocking\n\n```go\n\u002F\u002F Define interface for dependencies\ntype UserRepository interface {\n    GetUser(id string) (*User, error)\n    SaveUser(user *User) error\n}\n\n\u002F\u002F Production implementation\ntype PostgresUserRepository struct {\n    db *sql.DB\n}\n\nfunc (r *PostgresUserRepository) GetUser(id string) (*User, error) {\n    \u002F\u002F Real database query\n}\n\n\u002F\u002F Mock implementation for tests\ntype MockUserRepository struct {\n    GetUserFunc  func(id string) (*User, error)\n    SaveUserFunc func(user *User) error\n}\n\nfunc (m *MockUserRepository) GetUser(id string) (*User, error) {\n    return m.GetUserFunc(id)\n}\n\nfunc (m *MockUserRepository) SaveUser(user *User) error {\n    return m.SaveUserFunc(user)\n}\n\n\u002F\u002F Test using mock\nfunc TestUserService(t *testing.T) {\n    mock := &MockUserRepository{\n        GetUserFunc: func(id string) (*User, error) {\n            if id == \"123\" {\n                return &User{ID: \"123\", Name: \"Alice\"}, nil\n            }\n            return nil, ErrNotFound\n        },\n    }\n\n    service := NewUserService(mock)\n\n    user, err := service.GetUserProfile(\"123\")\n    if err != nil {\n        t.Fatalf(\"unexpected error: %v\", err)\n    }\n    if user.Name != \"Alice\" {\n        t.Errorf(\"got name %q; want %q\", user.Name, \"Alice\")\n    }\n}\n```\n\n## Benchmarks\n\n### Basic Benchmarks\n\n```go\nfunc BenchmarkProcess(b *testing.B) {\n    data := generateTestData(1000)\n    b.ResetTimer() \u002F\u002F Don't count setup time\n\n    for i := 0; i \u003C b.N; i++ {\n        Process(data)\n    }\n}\n\n\u002F\u002F Run: go test -bench=BenchmarkProcess -benchmem\n\u002F\u002F Output: BenchmarkProcess-8   10000   105234 ns\u002Fop   4096 B\u002Fop   10 allocs\u002Fop\n```\n\n### Benchmark with Different Sizes\n\n```go\nfunc BenchmarkSort(b *testing.B) {\n    sizes := []int{100, 1000, 10000, 100000}\n\n    for _, size := range sizes {\n        b.Run(fmt.Sprintf(\"size=%d\", size), func(b *testing.B) {\n            data := generateRandomSlice(size)\n            b.ResetTimer()\n\n            for i := 0; i \u003C b.N; i++ {\n                \u002F\u002F Make a copy to avoid sorting already sorted data\n                tmp := make([]int, len(data))\n                copy(tmp, data)\n                sort.Ints(tmp)\n            }\n        })\n    }\n}\n```\n\n### Memory Allocation Benchmarks\n\n```go\nfunc BenchmarkStringConcat(b *testing.B) {\n    parts := []string{\"hello\", \"world\", \"foo\", \"bar\", \"baz\"}\n\n    b.Run(\"plus\", func(b *testing.B) {\n        for i := 0; i \u003C b.N; i++ {\n            var s string\n            for _, p := range parts {\n                s += p\n            }\n            _ = s\n        }\n    })\n\n    b.Run(\"builder\", func(b *testing.B) {\n        for i := 0; i \u003C b.N; i++ {\n            var sb strings.Builder\n            for _, p := range parts {\n                sb.WriteString(p)\n            }\n            _ = sb.String()\n        }\n    })\n\n    b.Run(\"join\", func(b *testing.B) {\n        for i := 0; i \u003C b.N; i++ {\n            _ = strings.Join(parts, \"\")\n        }\n    })\n}\n```\n\n## Fuzzing (Go 1.18+)\n\n### Basic Fuzz Test\n\n```go\nfunc FuzzParseJSON(f *testing.F) {\n    \u002F\u002F Add seed corpus\n    f.Add(`{\"name\": \"test\"}`)\n    f.Add(`{\"count\": 123}`)\n    f.Add(`[]`)\n    f.Add(`\"\"`)\n\n    f.Fuzz(func(t *testing.T, input string) {\n        var result map[string]interface{}\n        err := json.Unmarshal([]byte(input), &result)\n\n        if err != nil {\n            \u002F\u002F Invalid JSON is expected for random input\n            return\n        }\n\n        \u002F\u002F If parsing succeeded, re-encoding should work\n        _, err = json.Marshal(result)\n        if err != nil {\n            t.Errorf(\"Marshal failed after successful Unmarshal: %v\", err)\n        }\n    })\n}\n\n\u002F\u002F Run: go test -fuzz=FuzzParseJSON -fuzztime=30s\n```\n\n### Fuzz Test with Multiple Inputs\n\n```go\nfunc FuzzCompare(f *testing.F) {\n    f.Add(\"hello\", \"world\")\n    f.Add(\"\", \"\")\n    f.Add(\"abc\", \"abc\")\n\n    f.Fuzz(func(t *testing.T, a, b string) {\n        result := Compare(a, b)\n\n        \u002F\u002F Property: Compare(a, a) should always equal 0\n        if a == b && result != 0 {\n            t.Errorf(\"Compare(%q, %q) = %d; want 0\", a, b, result)\n        }\n\n        \u002F\u002F Property: Compare(a, b) and Compare(b, a) should have opposite signs\n        reverse := Compare(b, a)\n        if (result > 0 && reverse >= 0) || (result \u003C 0 && reverse \u003C= 0) {\n            if result != 0 || reverse != 0 {\n                t.Errorf(\"Compare(%q, %q) = %d, Compare(%q, %q) = %d; inconsistent\",\n                    a, b, result, b, a, reverse)\n            }\n        }\n    })\n}\n```\n\n## Test Coverage\n\n### Running Coverage\n\n```bash\n# Basic coverage\ngo test -cover .\u002F...\n\n# Generate coverage profile\ngo test -coverprofile=coverage.out .\u002F...\n\n# View coverage in browser\ngo tool cover -html=coverage.out\n\n# View coverage by function\ngo tool cover -func=coverage.out\n\n# Coverage with race detection\ngo test -race -coverprofile=coverage.out .\u002F...\n```\n\n### Coverage Targets\n\n| Code Type | Target |\n|-----------|--------|\n| Critical business logic | 100% |\n| Public APIs | 90%+ |\n| General code | 80%+ |\n| Generated code | Exclude |\n\n### Excluding Generated Code from Coverage\n\n```go\n\u002F\u002Fgo:generate mockgen -source=interface.go -destination=mock_interface.go\n\n\u002F\u002F In coverage profile, exclude with build tags:\n\u002F\u002F go test -cover -tags=!generate .\u002F...\n```\n\n## HTTP Handler Testing\n\n```go\nfunc TestHealthHandler(t *testing.T) {\n    \u002F\u002F Create request\n    req := httptest.NewRequest(http.MethodGet, \"\u002Fhealth\", nil)\n    w := httptest.NewRecorder()\n\n    \u002F\u002F Call handler\n    HealthHandler(w, req)\n\n    \u002F\u002F Check response\n    resp := w.Result()\n    defer resp.Body.Close()\n\n    if resp.StatusCode != http.StatusOK {\n        t.Errorf(\"got status %d; want %d\", resp.StatusCode, http.StatusOK)\n    }\n\n    body, _ := io.ReadAll(resp.Body)\n    if string(body) != \"OK\" {\n        t.Errorf(\"got body %q; want %q\", body, \"OK\")\n    }\n}\n\nfunc TestAPIHandler(t *testing.T) {\n    tests := []struct {\n        name       string\n        method     string\n        path       string\n        body       string\n        wantStatus int\n        wantBody   string\n    }{\n        {\n            name:       \"get user\",\n            method:     http.MethodGet,\n            path:       \"\u002Fusers\u002F123\",\n            wantStatus: http.StatusOK,\n            wantBody:   `{\"id\":\"123\",\"name\":\"Alice\"}`,\n        },\n        {\n            name:       \"not found\",\n            method:     http.MethodGet,\n            path:       \"\u002Fusers\u002F999\",\n            wantStatus: http.StatusNotFound,\n        },\n        {\n            name:       \"create user\",\n            method:     http.MethodPost,\n            path:       \"\u002Fusers\",\n            body:       `{\"name\":\"Bob\"}`,\n            wantStatus: http.StatusCreated,\n        },\n    }\n\n    handler := NewAPIHandler()\n\n    for _, tt := range tests {\n        t.Run(tt.name, func(t *testing.T) {\n            var body io.Reader\n            if tt.body != \"\" {\n                body = strings.NewReader(tt.body)\n            }\n\n            req := httptest.NewRequest(tt.method, tt.path, body)\n            req.Header.Set(\"Content-Type\", \"application\u002Fjson\")\n            w := httptest.NewRecorder()\n\n            handler.ServeHTTP(w, req)\n\n            if w.Code != tt.wantStatus {\n                t.Errorf(\"got status %d; want %d\", w.Code, tt.wantStatus)\n            }\n\n            if tt.wantBody != \"\" && w.Body.String() != tt.wantBody {\n                t.Errorf(\"got body %q; want %q\", w.Body.String(), tt.wantBody)\n            }\n        })\n    }\n}\n```\n\n## Testing Commands\n\n```bash\n# Run all tests\ngo test .\u002F...\n\n# Run tests with verbose output\ngo test -v .\u002F...\n\n# Run specific test\ngo test -run TestAdd .\u002F...\n\n# Run tests matching pattern\ngo test -run \"TestUser\u002FCreate\" .\u002F...\n\n# Run tests with race detector\ngo test -race .\u002F...\n\n# Run tests with coverage\ngo test -cover -coverprofile=coverage.out .\u002F...\n\n# Run short tests only\ngo test -short .\u002F...\n\n# Run tests with timeout\ngo test -timeout 30s .\u002F...\n\n# Run benchmarks\ngo test -bench=. -benchmem .\u002F...\n\n# Run fuzzing\ngo test -fuzz=FuzzParse -fuzztime=30s .\u002F...\n\n# Count test runs (for flaky test detection)\ngo test -count=10 .\u002F...\n```\n\n## Best Practices\n\n**DO:**\n- Write tests FIRST (TDD)\n- Use table-driven tests for comprehensive coverage\n- Test behavior, not implementation\n- Use `t.Helper()` in helper functions\n- Use `t.Parallel()` for independent tests\n- Clean up resources with `t.Cleanup()`\n- Use meaningful test names that describe the scenario\n\n**DON'T:**\n- Test private functions directly (test through public API)\n- Use `time.Sleep()` in tests (use channels or conditions)\n- Ignore flaky tests (fix or remove them)\n- Mock everything (prefer integration tests when possible)\n- Skip error path testing\n\n## Integration with CI\u002FCD\n\n```yaml\n# GitHub Actions example\ntest:\n  runs-on: ubuntu-latest\n  steps:\n    - uses: actions\u002Fcheckout@v4\n    - uses: actions\u002Fsetup-go@v5\n      with:\n        go-version: '1.22'\n\n    - name: Run tests\n      run: go test -race -coverprofile=coverage.out .\u002F...\n\n    - name: Check coverage\n      run: |\n        go tool cover -func=coverage.out | grep total | awk '{print $3}' | \\\n        awk -F'%' '{if ($1 \u003C 80) exit 1}'\n```\n\n**Remember**: Tests are documentation. They show how your code is meant to be used. Write them clearly and keep them up to date.\n",{"name":5,"origin":49,"description":7},"ECC","main","b0f0a87593c578a7898eccaf1b363f7f87c1f99b","plugins\u002FColin4k1024\u002Ftsp\u002Fskills\u002Fgolang-testing",474,"https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins","https:\u002F\u002Fhol.org\u002Fplugins\u002Fbest-codex-plugins","https:\u002F\u002Fgithub.com\u002Fhashgraph-online","https:\u002F\u002Fhol.org","Open-source standards and developer tools for interoperable AI agents: discovery, identity, communication, payments, privacy and security.","2026-11-11 14:40:14",{"source":8,"skillName":5,"commands":61,"prompt":71,"zipAvailable":72},[62,65,68],{"tool":63,"command":64},"npx","npx skills add hashgraph-online\u002Fawesome-codex-plugins --skill golang-testing",{"tool":66,"command":67},"bunx","bunx skills add hashgraph-online\u002Fawesome-codex-plugins --skill golang-testing",{"tool":69,"command":70},"pnpm","pnpm dlx skills add hashgraph-online\u002Fawesome-codex-plugins --skill golang-testing","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002FColin4k1024\u002Ftsp\u002Fskills\u002Fgolang-testing\u002FSKILL.md",true,[],[75,83,90,97,124,148],{"skillNo":76,"name":77,"nameZh":6,"description":78,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":79,"categories":80,"keywords":81,"publishedAt":82},"01M746ZWACVKMZ1BJXJZHYJSSX","migrate-to-e2e","Moves an existing Playwright, Cypress, Selenium, Appium, Detox, Maestro, or TesterArmy suite to e2e one slice at a time, with the old suite running beside the new one until each ported test is proven. Keeps a MIGRATION.md progress file so any later session resumes where the last stopped. Optionally plants a defect to show both suites catch it. Use for \u002Fmigrate-to-e2e, \"migrate our tests to e2e\", \"port these Maestro flows\", \"move our TesterArmy tests\", or when a project has an e2e config and an older suite still running.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fmigrate-to-e2e\u002FSKILL.md",[],[],"2026-11-11 15:11:14",{"skillNo":84,"name":85,"nameZh":6,"description":86,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":87,"categories":88,"keywords":89,"publishedAt":82},"01M746ZPTAX1Q0FBKAB1CYND7E","e2e","Writes, runs, and debugs end-to-end tests for web and mobile apps with e2e, the agentic test runner, which mixes agent.act goals with exact locator assertions on a Playwright browser or an iOS or Android device. Also drives a project's running app live over the e2e MCP server to look at a screen, check a UI change, take a screenshot or record a video, and try a locator; and runs bug bashes, parallel e2e explore runs with each bug proven by a repro test. Use when a project depends on e2e or has an e2e.config.ts, when asked for end-to-end, browser, mobile, or agentic UI tests, to check a change in the running app, to QA or bug bash an app or branch, or when an e2e run fails.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fe2e\u002FSKILL.md",[],[],{"skillNo":91,"name":92,"nameZh":6,"description":93,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":94,"categories":95,"keywords":96,"publishedAt":82},"01M746ZJN784HVHMDP9MQGCSGG","create-verification-skill","Generate a project-local verify-\u003Capp> skill on top of e2e, so any coding agent can launch the app, check it is worth driving, exercise a feature the way a user does, keep evidence, and bug bash it. Writes the skill, a feature map with one explore charter per feature, and proves it once. Use for \u002Fcreate-verification-skill, \"make a verification skill for this repo\", or when a project has no scripted way to prove UI behavior.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftester-army\u002Fe2e\u002Fskills\u002Fcreate-verification-skill\u002FSKILL.md",[],[],{"skillNo":98,"name":99,"nameZh":6,"description":100,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":101,"categories":102,"keywords":103,"publishedAt":44},"01M716A6ETNB9B1SQ3GXZC75VR","deja-search","deja-vu memory — search the user's past AI coding sessions with the deja CLI. Holds what they already settled and never wrote into the repo (naming rules, banned or already-tried tools, required checks before merge, preferred values, who owns what). Use before your first edit in a task, before you call a change done or ready to merge, before you recommend a tool, library, design or reviewer, before re-debugging an error that may already be solved, when they say 'didn't we fix this before', 'what did we decide about X' or 'I already have that', and before telling them something on this machine does not exist.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fvshulcz\u002Fdeja-vu\u002Fskills\u002Fdeja-search\u002FSKILL.md",[],[104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123],"search","deja search","never","error","ready","memory","re","decide","fix","design","debugging","when","you","done","reviewer","io","change","cli","merge","past",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":130,"publishedAt":44},"01M716A3J2W5SENSE9VGMXB375","deja-reflect","End-of-session reflection and memory curation with deja-vu. Review what was decided, what commands broke and what repaired them, and record durable project rules or decisions with deja remember so the next session starts with them.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Fvshulcz\u002Fdeja-vu\u002Fskills\u002Fdeja-reflect\u002FSKILL.md",[],[131,132,133,119,30,134,135,136,137,138,139,140,141,142,109,143,144,145,146,147],"deja reflect","reflect","review","record","github","next","https","node","Rules","decisions","brew","remember","project rules","project","session","end","reflection",{"skillNo":149,"name":150,"nameZh":6,"description":151,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":152,"categories":153,"keywords":163,"publishedAt":44},"01M715T3RR4BAYSR57HPPTJ0PF","revid","Make, edit, export and post AI videos with Revid (revid.ai) through the Revid MCP server. Use whenever the user wants a short-form or long-form video made (from an idea, a script, a URL, an article, a PDF, a tweet, a product page, their own clips, or a song), wants to find what is going viral on TikTok, YouTube, Instagram or X before making something, wants to edit or re-export an existing Revid project, generate a standalone AI image or clip, make a series episode, or publish and schedule a finished video to connected social accounts. Covers setup (hosted MCP with OAuth, or an API key), the 36 tools, credits, polling and the rules for publishing. Routes to the more specific revid-* skills when one fits.","https:\u002F\u002Fgithub.com\u002Fhashgraph-online\u002Fawesome-codex-plugins\u002Fblob\u002Fmain\u002Fplugins\u002Ftmakersas\u002Frevid-skills\u002Fskills\u002Frevid\u002FSKILL.md",[154,157,160],{"categoryNo":155,"categoryName":156,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":158,"categoryName":159,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":161,"categoryName":162,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",[150,164,165,166,167,168,169,144,170,110,171,172,173,174,115,175,176,177,178,179],"URL","Video","short-form","standalone","PDF","viral","tiktok","short","social","MCP","song","image","mcp server","schedule","api","publish"]