复制安装命令
用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。
复制前请先查看来源、License 和安全提示。
This is the open-source content repository behind
用 Codex 或 Claude 安装复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它先审查 Skill 页面再帮你安装。
复制前请先查看来源、License 和安全提示。
来源文件:README.md
This is the open-source content repository behind Skill Store. It stores every approved Agent Skill, the records that go with it, and the automated security audits published with each skill.
This repo is a companion to the Skill Store platform, not the place to submit skills. Skills are added through skillstore.io — its review pipeline writes to this repo automatically. Please do not open a pull request here to add a skill; PRs adding skills will be closed. See Contributing a skill below.
The recommended way to install any skill is the skillstore CLI — one command works for both Claude Code and Codex:
npx skillstore add author/skill-name
For example:
npx skillstore add aiskillstore/code-review
It downloads the skill and drops it into the right skills/ directory for your tool. Claude Code auto-discovers it; for Codex, restart the session.
Prefer to do it by hand, or installing via Claude Web? See the full Installation Guides for every method (CLI, manual, and ZIP upload) and the scope directories (~/.agents/skills/, .claude/skills/, ~/.claude/skills/, .codex/skills/, …).
Submit through the platform — not through a pull request:
SKILL.md.SKILL.md — the skill definition (required, per the Agent Skills spec)LICENSE (recommended)Every submission is scanned automatically before it can be published. The audit flags things like:
eval, exec, raw system commands)Security analysis is report-only: findings inform maintainers and users, but a risk result does not automatically block an otherwise approved skill from being published. See our Security Trust Center for the methodology, limitations, and risk-level definitions.
Live Security Passport example:
.
├── skills/ # Approved, published skills (one folder each, with SKILL.md)
├── pending/ # Submissions awaiting review
├── packages/
│ ├── cli/ # The `skillstore` CLI (npx skillstore add …)
│ └── skillstore/
├── schemas/ # JSON schemas for skill records
├── scripts/ # Maintenance & scoring scripts
└── .github/workflows/ # Submission, audit, and sync automation
The contents of this repo are maintained by Skill Store's automated pipeline. Manual changes are limited to maintainers.
The marketplace catalog is MIT-licensed. Individual skills carry their own licenses — check each skill's LICENSE file.
name: golang-testing
description: Comprehensive Go testing patterns including table-driven tests, mocking,
integration testing, benchmarks, and test organization.
author: Joseph OBrien
status: unpublished
updated: '2025-12-23'
version: 1.0.1
tag: skill
type: skillThis skill provides guidance on comprehensive testing strategies for Go applications including unit tests, integration tests, benchmarks, and test organization.
func TestAdd(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
}{
{"positive numbers", 2, 3, 5},
{"negative numbers", -2, -3, -5},
{"mixed numbers", -2, 3, 1},
{"zeros", 0, 0, 0},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := Add(tt.a, tt.b)
if result != tt.expected {
t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
}
})
}
}
func TestDivide(t *testing.T) {
tests := []struct {
name string
a, b int
expected int
wantErr bool
errString string
}{
{"valid division", 10, 2, 5, false, ""},
{"divide by zero", 10, 0, 0, true, "division by zero"},
{"negative result", -10, 2, -5, false, ""},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := Divide(tt.a, tt.b)
if tt.wantErr {
if err == nil {
t.Fatalf("expected error, got nil")
}
if !strings.Contains(err.Error(), tt.errString) {
t.Errorf("error = %v; want containing %q", err, tt.errString)
}
return
}
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if result != tt.expected {
t.Errorf("Divide(%d, %d) = %d; want %d", tt.a, tt.b, result, tt.expected)
}
})
}
}
// repository.go
type UserRepository interface {
FindByID(ctx context.Context, id string) (*User, error)
Save(ctx context.Context, user *User) error
}
type EmailSender interface {
Send(ctx context.Context, to, subject, body string) error
}
// mocks/user_repository.go
type MockUserRepository struct {
FindByIDFunc func(ctx context.Context, id string) (*User, error)
SaveFunc func(ctx context.Context, user *User) error
}
func (m *MockUserRepository) FindByID(ctx context.Context, id string) (*User, error) {
if m.FindByIDFunc != nil {
return m.FindByIDFunc(ctx, id)
}
return nil, nil
}
func (m *MockUserRepository) Save(ctx context.Context, user *User) error {
if m.SaveFunc != nil {
return m.SaveFunc(ctx, user)
}
return nil
}
func TestUserService_GetUser(t *testing.T) {
expectedUser := &User{ID: "123", Name: "John"}
repo := &MockUserRepository{
FindByIDFunc: func(ctx context.Context, id string) (*User, error) {
if id == "123" {
return expectedUser, nil
}
return nil, ErrNotFound
},
}
service := NewUserService(repo)
t.Run("existing user", func(t *testing.T) {
user, err := service.GetUser(context.Background(), "123")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if user.Name != expectedUser.Name {
t.Errorf("got name %q; want %q", user.Name, expectedUser.Name)
}
})
t.Run("non-existing user", func(t *testing.T) {
_, err := service.GetUser(context.Background(), "456")
if !errors.Is(err, ErrNotFound) {
t.Errorf("got error %v; want ErrNotFound", err)
}
})
}
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestWithTestify(t *testing.T) {
// assert continues on failure
assert.Equal(t, 5, Add(2, 3), "addition should work")
assert.NotNil(t, result)
assert.Len(t, items, 3)
assert.Contains(t, slice, item)
assert.True(t, condition)
assert.NoError(t, err)
assert.ErrorIs(t, err, ErrNotFound)
// require stops test on failure
require.NoError(t, err, "setup must succeed")
require.NotNil(t, config)
}
import (
"context"
"testing"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/modules/postgres"
)
func TestUserRepository_Integration(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test in short mode")
}
ctx := context.Background()
// Start PostgreSQL container
pgContainer, err := postgres.Run(ctx,
"postgres:15-alpine",
postgres.WithDatabase("testdb"),
postgres.WithUsername("test"),
postgres.WithPassword("test"),
)
require.NoError(t, err)
defer pgContainer.Terminate(ctx)
// Get connection string
connStr, err := pgContainer.ConnectionString(ctx, "sslmode=disable")
require.NoError(t, err)
// Connect and run migrations
db, err := sql.Open("postgres", connStr)
require.NoError(t, err)
defer db.Close()
runMigrations(db)
// Create repository and test
repo := NewUserRepository(db)
t.Run("save and find user", func(t *testing.T) {
user := &User{ID: "123", Name: "John", Email: "john@example.com"}
err := repo.Save(ctx, user)
require.NoError(t, err)
found, err := repo.FindByID(ctx, "123")
require.NoError(t, err)
assert.Equal(t, user.Name, found.Name)
})
}
func TestMain(m *testing.M) {
// Global setup
setup()
code := m.Run()
// Global teardown
teardown()
os.Exit(code)
}
func setup() {
// Initialize test database, load fixtures, etc.
}
func teardown() {
// Clean up resources
}
func setupTest(t *testing.T) (*UserService, func()) {
t.Helper()
db := setupTestDB(t)
repo := NewUserRepository(db)
service := NewUserService(repo)
cleanup := func() {
db.Close()
}
return service, cleanup
}
func TestUserService(t *testing.T) {
service, cleanup := setupTest(t)
defer cleanup()
// Run tests using service
}
func BenchmarkFibonacci(b *testing.B) {
for i := 0; i < b.N; i++ {
Fibonacci(20)
}
}
func BenchmarkFibonacciParallel(b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Fibonacci(20)
}
})
}
// With sub-benchmarks
func BenchmarkSort(b *testing.B) {
sizes := []int{100, 1000, 10000}
for _, size := range sizes {
b.Run(fmt.Sprintf("size-%d", size), func(b *testing.B) {
data := generateData(size)
b.ResetTimer()
for i := 0; i < b.N; i++ {
sort.Ints(data)
}
})
}
}
func TestHandler_GetUser(t *testing.T) {
// Setup mock service
service := &MockUserService{
GetUserFunc: func(ctx context.Context, id string) (*User, error) {
return &User{ID: id, Name: "John"}, nil
},
}
handler := NewHandler(service)
t.Run("success", func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/users/123", nil)
rec := httptest.NewRecorder()
handler.GetUser(rec, req)
assert.Equal(t, http.StatusOK, rec.Code)
var response User
err := json.NewDecoder(rec.Body).Decode(&response)
require.NoError(t, err)
assert.Equal(t, "John", response.Name)
})
t.Run("not found", func(t *testing.T) {
service.GetUserFunc = func(ctx context.Context, id string) (*User, error) {
return nil, ErrNotFound
}
req := httptest.NewRequest(http.MethodGet, "/users/999", nil)
rec := httptest.NewRecorder()
handler.GetUser(rec, req)
assert.Equal(t, http.StatusNotFound, rec.Code)
})
}
/internal
/user
user.go
user_test.go # Unit tests
user_integration_test.go # Integration tests (build tag)
testdata/ # Test fixtures
users.json
//go:build integration
package user
func TestIntegration(t *testing.T) {
// Integration test code
}
Run with: go test -tags=integration ./...
# Generate coverage
go test -coverprofile=coverage.out ./...
# View in browser
go tool cover -html=coverage.out
# Check coverage percentage
go test -cover ./...
t.Parallel() for independent testsTestUserService_CreateUser_WithInvalidEmail-short
评论 (0)
暂无评论,成为第一个评论者吧!