chore: initial plan
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
# Integration Testing
|
||||
|
||||
## Docker Compose Fixture
|
||||
|
||||
Create `pkg/myfeature/testdata/docker-compose.yml` for test services:
|
||||
|
||||
```yaml
|
||||
version: "3.8"
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_USER: test
|
||||
POSTGRES_PASSWORD: test
|
||||
POSTGRES_DB: testdb
|
||||
ports:
|
||||
- "5433:5432"
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U test"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
ports:
|
||||
- "6380:6379"
|
||||
healthcheck:
|
||||
test: ["CMD", "redis-cli", "ping"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
```
|
||||
|
||||
## SQL Schema Fixture
|
||||
|
||||
Create `pkg/myfeature/testdata/schema.sql` for database initialization:
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS orders (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id),
|
||||
amount DECIMAL(10,2) NOT NULL,
|
||||
status VARCHAR(50) DEFAULT 'pending',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
## Test Data Fixture
|
||||
|
||||
Create `pkg/myfeature/testdata/testdata.sql`:
|
||||
|
||||
```sql
|
||||
INSERT INTO users (name, email) VALUES
|
||||
('Alice Johnson', 'alice@example.com'),
|
||||
('Bob Smith', 'bob@example.com'),
|
||||
('Charlie Brown', 'charlie@example.com');
|
||||
|
||||
INSERT INTO orders (user_id, amount, status) VALUES
|
||||
(1, 100.00, 'completed'),
|
||||
(1, 50.00, 'pending'),
|
||||
(2, 200.00, 'completed');
|
||||
```
|
||||
|
||||
## Using Fixtures in Tests
|
||||
|
||||
```go
|
||||
//go:build integration
|
||||
|
||||
package database_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"os"
|
||||
"os/exec"
|
||||
"testing"
|
||||
"time"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
)
|
||||
|
||||
type DatabaseTestSuite struct {
|
||||
suite.Suite
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func (s *DatabaseTestSuite) SetupSuite() {
|
||||
cmd := exec.Command("docker-compose", "-f", "testdata/docker-compose.yml", "up", "-d")
|
||||
if err := cmd.Run(); err != nil {
|
||||
s.T().Fatalf("failed to start docker-compose: %v", err)
|
||||
}
|
||||
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
db, err := sql.Open("postgres", "postgres://test:test@localhost:5433/testdb?sslmode=disable")
|
||||
if err != nil {
|
||||
s.T().Fatalf("failed to connect to database: %v", err)
|
||||
}
|
||||
s.db = db
|
||||
|
||||
schema, _ := os.ReadFile("testdata/schema.sql")
|
||||
_, err = db.Exec(string(schema))
|
||||
if err != nil {
|
||||
s.T().Fatalf("failed to run schema: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DatabaseTestSuite) TearDownSuite() {
|
||||
cmd := exec.Command("docker-compose", "-f", "testdata/docker-compose.yml", "down", "-v")
|
||||
_ = cmd.Run()
|
||||
}
|
||||
|
||||
func (s *DatabaseTestSuite) SetupTest() {
|
||||
_, err := s.db.Exec("TRUNCATE TABLE orders, users CASCADE")
|
||||
if err != nil {
|
||||
s.T().Fatalf("failed to clear database: %v", err)
|
||||
}
|
||||
|
||||
testdata, _ := os.ReadFile("testdata/testdata.sql")
|
||||
_, err = s.db.Exec(string(testdata))
|
||||
if err != nil {
|
||||
s.T().Fatalf("failed to load test data: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *DatabaseTestSuite) TestUserCount() {
|
||||
is := assert.New(s.T())
|
||||
|
||||
var count int
|
||||
err := s.db.QueryRow("SELECT COUNT(*) FROM users").Scan(&count)
|
||||
is.NoError(err)
|
||||
is.Equal(3, count)
|
||||
}
|
||||
|
||||
func (s *DatabaseTestSuite) TestOrderSum() {
|
||||
is := assert.New(s.T())
|
||||
|
||||
var sum float64
|
||||
err := s.db.QueryRow("SELECT SUM(amount) FROM orders").Scan(&sum)
|
||||
is.NoError(err)
|
||||
is.InDelta(350.0, sum, 0.01)
|
||||
}
|
||||
|
||||
func TestDatabaseTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(DatabaseTestSuite))
|
||||
}
|
||||
```
|
||||
|
||||
## Test Helper with Embedded Fixtures
|
||||
|
||||
```go
|
||||
package myfeature
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"embed"
|
||||
)
|
||||
|
||||
//go:embed testdata/schema.sql testdata/testdata.sql
|
||||
var fixtures embed.FS
|
||||
|
||||
func SetupDB(db *sql.DB) error {
|
||||
schema, err := fixtures.ReadFile("testdata/schema.sql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.Exec(string(schema)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data, err := fixtures.ReadFile("testdata/testdata.sql")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.Exec(string(data)); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user