# Run all tests (fastest)
task test
# Run tests with coverage report
task test:coverage
# Run only unit tests
task test:unit
# Run only integration tests
task test:integration
# Run CI checks locally (before commit)
task ci:local# Automatically run tests and checks before each commit
task hooks:installAfter running task test:coverage, open coverage.html in your browser to see detailed coverage.
-
User Service Tests (100% usecase coverage)
- Repository layer: 8 tests (CRUD operations, duplicate prevention)
- Usecase layer: 8 tests (business logic, GetOrCreate pattern)
- HTTP layer: 8 tests (API endpoints, validation, error handling)
-
API Service Tests (52% usecase coverage)
- Usecase layer: 11 tests (link management, view stats)
- Error handling scenarios
-
Integration Tests (3 tests)
- End-to-end user flows
- Multiple user scenarios
- Database integration
Total: 38 tests covering critical functionality
Located in .github/workflows/ci.yml
Runs automatically on:
- Every push to
mainanddevelopbranches - Every pull request to
mainanddevelop
Pipeline stages:
- Test - Runs all tests with PostgreSQL, generates coverage
- Lint - Checks code quality with golangci-lint
- Build - Verifies all services compile
- Docker - Builds Docker images (main branch only)
Located in .pre-commit-config.yaml
Automatically runs before each commit:
- Code formatting (go fmt)
- Static analysis (go vet)
- Dependency management (go mod tidy)
- Unit tests (fast, < 30s)
.golangci.yml- Linter configuration.pre-commit-config.yaml- Pre-commit hooksTaskfile.yml- Task runner with all project commands
- TESTING.md - Comprehensive testing guide
- CI_CD.md - CI/CD documentation
- TEST_SUMMARY.md - Coverage summary
- README_TESTING_CI.md - This file
github.com/stretchr/testify- Assertions & mockinggorm.io/driver/sqlite- In-memory test database
golangci-lint- Comprehensive Go linterpre-commit- Git hook framework- GitHub Actions - CI/CD platform
LinkKeeper/
├── .github/
│ └── workflows/
│ └── ci.yml # CI/CD pipeline
├── internal/
│ ├── user-service/
│ │ ├── repository/
│ │ │ ├── user.go
│ │ │ └── user_test.go # ✨ Repository tests
│ │ ├── usecase/
│ │ │ ├── user.go
│ │ │ └── user_test.go # ✨ Business logic tests
│ │ └── transport/http/
│ │ ├── http.go
│ │ └── http_test.go # ✨ HTTP handler tests
│ └── api-service/
│ └── usecase/
│ ├── link.go
│ └── link_test.go # ✨ Link service tests
├── tests/
│ └── integration_test.go # ✨ Integration tests
├── .golangci.yml # ✨ Linter config
├── .pre-commit-config.yaml # ✨ Pre-commit hooks
├── Taskfile.yml # ✨ Task runner with all commands
├── docs/
│ ├── TESTING.md # ✨ Testing guide
│ ├── CI_CD.md # ✨ CI/CD guide
│ ├── TEST_SUMMARY.md # ✨ Coverage summary
│ └── README_TESTING_CI.md # ✨ This file
# Install pre-commit hooks (once)
task hooks:installWrite code and tests together:
# Run tests continuously while developing
task test:unit
# Check specific package
go test -v ./internal/user-service/usecase/...# Run all CI checks locally
task ci:local
# This runs:
# - go fmt ./...
# - go vet ./...
# - golangci-lint run
# - go test with coverageOr just commit - pre-commit hooks will run automatically!
The CI pipeline will run automatically:
- ✅ Tests must pass
- ✅ Linting must pass
- ✅ Build must succeed
- ✅ Coverage should not decrease
On main branch, Docker images are automatically built.
| Component | Current | Target | Status |
|---|---|---|---|
| User Service (Usecase) | 100% | 100% | ✅ |
| User Service (Repository) | 86.4% | 90% | |
| API Service (Usecase) | 52.2% | 80% | 🔴 |
| User Service (HTTP) | 50.7% | 80% | 🔴 |
| Overall | ~70% | 85% |
# Task (recommended)
task test # All tests
task test:unit # Unit tests only
task test:integration # Integration tests only
task test:coverage # With HTML coverage report
task ci:local # Full CI simulation
# Go directly
go test ./... # All tests
go test -v ./... # Verbose
go test -race ./... # With race detector
go test -short ./... # Skip integration tests
go test -coverprofile=coverage.out ./... # Generate coveragetask lint # Run all linters
task fmt # Format code
golangci-lint run # Direct command
go fmt ./... # Format code
go vet ./... # Static analysistask ci:local # Run CI checks locally
task hooks:install # Install pre-commit hooks
pre-commit run --all-files # Run hooks manuallygo mod tidy
go mod vendor# Reinstall hooks
pre-commit uninstall
task hooks:install
# Or manually
pre-commit install# Install golangci-lint
brew install golangci-lint # macOS
# Or
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest# Clean cache
go clean -cache -testcache
# Run with same flags as CI
go test -v -race -coverprofile=coverage.out ./...
# Check formatting
gofmt -s -l .# Generate coverage
task test:coverage
# Or manually
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
open coverage.html # macOS✅ On push to main or develop
✅ On pull requests to main or develop
❌ On feature branches without PR
- Checkout code
- Setup Go 1.23
- Setup PostgreSQL 16 (for integration tests)
- Install dependencies
- Format check (
go fmt) - Static analysis (
go vet) - Run linter (
golangci-lint) - Run all tests with race detector
- Generate coverage report
- Upload to Codecov (optional)
- Build all services
- Build Docker images (main branch only)
- Fast: ~3-5 minutes
- Includes all checks and builds
Before EVERY commit:
- ✅ Trailing whitespace removed
- ✅ File ends with newline
- ✅ YAML files valid
- ✅ No large files
- ✅ No merge conflicts
- ✅ No private keys
- ✅ Code formatted (
go fmt) - ✅ Static analysis (
go vet) - ✅ Dependencies tidy (
go mod tidy) - ✅ Unit tests pass (fast only)
git commit --no-verify -m "emergency fix"When adding features:
- Write tests first (TDD)
- Ensure tests pass
- Check coverage doesn't decrease
- Update documentation if needed
Priority areas for improvement:
- 🔴 API Service HTTP handlers
- 🔴 User Service HTTP handlers
⚠️ API Service repository⚠️ Bot Service (not covered yet)
# Run benchmarks
go test -bench=. ./...
# With memory profiling
go test -bench=. -benchmem ./...- Write tests for new features
- Run tests before committing
- Keep tests fast (<100ms each)
- Use meaningful test names
- Test error cases
- Mock external dependencies
- Clean up test resources
- Skip tests (except in emergency)
- Commit without running CI locally
- Write flaky tests
- Test implementation details
- Share state between tests
- Leave commented-out code
Use Conventional Commits:
feat(user): add user registration
fix(api): handle nil pointer in link creation
test(user): add repository tests
ci: update GitHub Actions workflow
docs(testing): add coverage guide
Types:
feat- New featurefix- Bug fixtest- Add/update testsci- CI/CD changesdocs- Documentationrefactor- Code refactoringchore- Maintenance
- TESTING.md - Detailed testing guide
- CI_CD.md - CI/CD documentation
- TEST_SUMMARY.md - Coverage summary
If you have questions:
- Check documentation (TESTING.md, CI_CD.md)
- Look at existing tests for examples
- Ask team members
- Create an issue
✅ 38 tests covering user service, API service, and integration flows
✅ GitHub Actions CI/CD running on every push/PR
✅ Pre-commit hooks catching issues before commit
✅ 70% code coverage with clear targets for improvement
✅ Comprehensive documentation for testing and CI/CD
You're all set! Start developing with confidence! 🚀
Last updated: January 19, 2026