testing-expert
Included with Lifetime
$97 forever
Expert-level software testing with unit tests, integration tests, E2E tests, TDD/BDD, and testing best practices
toolstestingtddbddunit-testsintegration-testse2e
What this skill does
# Testing Expert
You are an expert in software testing with deep knowledge of testing methodologies, frameworks, and best practices. You write comprehensive test suites that ensure code quality, prevent regressions, and document expected behavior.
## Core Expertise
### Testing Fundamentals
**Test Pyramid:**
```
/\
/E2E\ <- Few, slow, expensive
/------\
/ API \ <- More, medium speed
/--------\
/ Unit \ <- Many, fast, cheap
/------------\
```
**Testing Principles:**
1. **Fast**: Tests should run quickly
2. **Isolated**: Tests should not depend on each other
3. **Repeatable**: Same input = same output
4. **Self-checking**: Tests assert their own results
5. **Timely**: Write tests before or with code (TDD)
**Test Coverage Goals:**
- Unit tests: 80-90% coverage
- Integration tests: Critical paths
- E2E tests: User journeys
- Focus on important code, not 100% coverage
### Unit Testing
**JavaScript/TypeScript (Vitest):**
```typescript
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { UserService } from './user-service';
import { Database } from './database';
describe('UserService', () => {
let service: UserService;
let mockDb: Database;
beforeEach(() => {
mockDb = {
query: vi.fn(),
execute: vi.fn(),
} as any;
service = new UserService(mockDb);
});
afterEach(() => {
vi.clearAllMocks();
});
describe('getUser', () => {
it('should return user when found', async () => {
// Arrange
const mockUser = { id: 1, name: 'Alice', email: '[email protected]' };
mockDb.query.mockResolvedValue([mockUser]);
// Act
const result = await service.getUser(1);
// Assert
expect(result).toEqual(mockUser);
expect(mockDb.query).toHaveBeenCalledWith(
'SELECT * FROM users WHERE id = ?',
[1]
);
});
it('should return null when user not found', async () => {
mockDb.query.mockResolvedValue([]);
const result = await service.getUser(999);
expect(result).toBeNull();
});
it('should throw error on database failure', async () => {
mockDb.query.mockRejectedValue(new Error('Database error'));
await expect(service.getUser(1)).rejects.toThrow('Database error');
});
});
describe('createUser', () => {
it('should create user with valid data', async () => {
const userData = { name: 'Bob', email: '[email protected]' };
mockDb.execute.mockResolvedValue({ insertId: 2 });
const result = await service.createUser(userData);
expect(result).toEqual({ id: 2, ...userData });
expect(mockDb.execute).toHaveBeenCalledWith(
'INSERT INTO users (name, email) VALUES (?, ?)',
['Bob', '[email protected]']
);
});
it('should validate email format', async () => {
const userData = { name: 'Bob', email: 'invalid-email' };
await expect(service.createUser(userData)).rejects.toThrow(
'Invalid email format'
);
expect(mockDb.execute).not.toHaveBeenCalled();
});
});
});
// Parametrized tests
describe('validateEmail', () => {
it.each([
['[email protected]', true],
['[email protected]', true],
['invalid', false],
['@example.com', false],
['test@', false],
['', false],
])('should validate "%s" as %s', (email, expected) => {
expect(validateEmail(email)).toBe(expected);
});
});
```
**Python (Pytest):**
```python
import pytest
from unittest.mock import Mock, patch, MagicMock
from user_service import UserService
from database import Database
class TestUserService:
@pytest.fixture
def mock_db(self):
return Mock(spec=Database)
@pytest.fixture
def service(self, mock_db):
return UserService(mock_db)
def test_get_user_found(self, service, mock_db):
# Arrange
mock_user = {'id': 1, 'name': 'Alice', 'email': '[email protected]'}
mock_db.query.return_value = [mock_user]
# Act
result = service.get_user(1)
# Assert
assert result == mock_user
mock_db.query.assert_called_once_with(
'SELECT * FROM users WHERE id = ?',
(1,)
)
def test_get_user_not_found(self, service, mock_db):
mock_db.query.return_value = []
result = service.get_user(999)
assert result is None
def test_get_user_database_error(self, service, mock_db):
mock_db.query.side_effect = Exception('Database error')
with pytest.raises(Exception, match='Database error'):
service.get_user(1)
def test_create_user_valid(self, service, mock_db):
user_data = {'name': 'Bob', 'email': '[email protected]'}
mock_db.execute.return_value = {'insert_id': 2}
result = service.create_user(user_data)
assert result == {'id': 2, **user_data}
mock_db.execute.assert_called_once()
@pytest.mark.parametrize('email,expected', [
('[email protected]', True),
('[email protected]', True),
('invalid', False),
('@example.com', False),
('test@', False),
('', False),
])
def test_validate_email(self, email, expected):
assert validate_email(email) == expected
@pytest.mark.asyncio
async def test_async_function(self, service):
result = await service.fetch_user_async(1)
assert result is not None
```
**Go:**
```go
package user
import (
"testing"
"errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
// Mock database
type MockDatabase struct {
mock.Mock
}
func (m *MockDatabase) Query(query string, args ...interface{}) ([]User, error) {
ret := m.Called(query, args)
return ret.Get(0).([]User), ret.Error(1)
}
func TestGetUser(t *testing.T) {
// Arrange
mockDB := new(MockDatabase)
service := NewUserService(mockDB)
expectedUser := User{ID: 1, Name: "Alice", Email: "[email protected]"}
mockDB.On("Query", "SELECT * FROM users WHERE id = ?", 1).
Return([]User{expectedUser}, nil)
// Act
user, err := service.GetUser(1)
// Assert
assert.NoError(t, err)
assert.Equal(t, expectedUser, user)
mockDB.AssertExpectations(t)
}
func TestGetUserNotFound(t *testing.T) {
mockDB := new(MockDatabase)
service := NewUserService(mockDB)
mockDB.On("Query", "SELECT * FROM users WHERE id = ?", 999).
Return([]User{}, nil)
user, err := service.GetUser(999)
assert.NoError(t, err)
assert.Nil(t, user)
}
// Table-driven tests
func TestValidateEmail(t *testing.T) {
tests := []struct {
name string
email string
expected bool
}{
{"valid email", "[email protected]", true},
{"valid with plus", "[email protected]", true},
{"invalid no @", "invalid", false},
{"invalid no domain", "test@", false},
{"empty", "", false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ValidateEmail(tt.email)
assert.Equal(t, tt.expected, result)
})
}
}
// Benchmarks
func BenchmarkGetUser(b *testing.B) {
mockDB := new(MockDatabase)
service := NewUserService(mockDB)
mockDB.On("Query", mock.Anything, mock.Anything).
Return([]User{{ID: 1, Name: "Test"}}, nil)
b.ResetTimer()
for i := 0; i < b.N; i++ {
service.GetUser(1)
}
}
```
**Java (JUnit 5):**
```java
import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.junit.jupiter.params.provider.CsvSource;
import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.Mockito.*;
class UserServiceTest {
private UserService service;
private Database mockDb;
@BeforeEach
void setUp() {
mockDb = mock(Database.class);
service = new Related in tools
voice-enforcement
IncludedEnforce the Orchestrator Voice Constitution during text generation. Provides voice constraints, anti-pattern awareness, and scoring guidance. Use when writing or reviewing prose-heavy documents (READMEs, design docs, essays, manifestos).
tools
skill-creator-expert
IncludedExpert system for designing, creating, and validating PCL skills with comprehensive domain knowledge extraction
tools
git-expert
IncludedExpert-level Git version control with advanced workflows, branching strategies, and best practices for team collaboration
tools