Test Exercises
Practice your testing skills with these hands-on exercises. Start with beginner level and progress to advanced challenges.
π Beginner Exercises
Perfect for those new to test automation. Focus on basic API and UI interactions.
Exercise 1: Basic API Testing
Objective: Write tests to verify CRUD operations on the Task API.
Tasks:
- Write a test to GET all tasks and verify the response contains an array
- Create a new task with POST and verify it returns 201 status
- Retrieve the created task by ID
- Update the task status to "DONE"
- Delete the task and verify 204 response
- Try to GET the deleted task and verify 404 error
Starter Code:
typescript
import axios from 'axios';
const API_URL = 'https://api.testauto.app/api/v1';
describe('Task API CRUD Operations', () => {
let createdTaskId;
test('should list all tasks', async () => {
// Your code here
});
test('should create a new task', async () => {
// Your code here
// Save createdTaskId for next tests
});
test('should get task by id', async () => {
// Use createdTaskId from previous test
});
test('should update task status', async () => {
// Your code here
});
test('should delete task', async () => {
// Your code here
});
test('should return 404 for deleted task', async () => {
// Your code here
});
});Exercise 2: Basic UI Testing
Objective: Test the Task Manager UI using Playwright.
Tasks:
- Navigate to
/task-manager - Verify the page title contains "Task Manager"
- Count the number of tasks displayed
- Click on a filter button (TODO/IN_PROGRESS/DONE)
- Verify only tasks with that status are visible
- Use the search box to filter tasks
- Verify search results are correct
Starter Code:
typescript
import { test, expect } from '@playwright/test';
test.describe('Task Manager UI', () => {
test.beforeEach(async ({ page }) => {
await page.goto('http://localhost:3000/task-manager');
});
test('should display task manager page', async ({ page }) => {
// Your code here
});
test('should filter tasks by status', async ({ page }) => {
// Your code here
});
test('should search tasks', async ({ page }) => {
// Your code here
});
});π Intermediate Exercises
Build on basic skills with more complex scenarios including authentication and error handling.
Exercise 3: JWT Authentication Testing
Objective: Test authenticated API endpoints with JWT tokens.
Tasks:
- Login with valid credentials and store the token
- Use the token to access protected endpoints
- Test with invalid credentials (should fail)
- Test with expired/invalid token (should return 401)
- Test token refresh functionality
- Implement token storage and reuse across tests
Challenge:
Create a helper class to manage authentication across all tests:
typescript
class AuthHelper {
private token: string | null = null;
async login(username: string, password: string) {
// Implement login and store token
}
getAuthHeader() {
return { Authorization: `Bearer ${this.token}` };
}
async refreshToken() {
// Implement token refresh
}
}
// Usage in tests
const auth = new AuthHelper();
await auth.login('user', 'user123');
const response = await axios.get('https://api.testauto.app/api/v2/tasks', {
headers: auth.getAuthHeader()
});Exercise 4: Pagination Testing
Objective: Test pagination, sorting, and filtering combinations.
Tasks:
- Test pagination with different page sizes
- Verify correct total elements count
- Test edge cases (page 0, last page, invalid page)
- Combine filtering and pagination
- Test sorting by different fields
- Verify consistency of results across pages
Exercise 5: UI Form Testing
Objective: Test the create/edit task forms with various inputs.
Tasks:
- Open the create task form
- Fill all required fields and submit
- Verify the task appears in the list
- Test form validation (empty fields, invalid data)
- Edit an existing task and save
- Cancel form without saving
- Test keyboard navigation (Tab, Enter, Esc)
β‘ Advanced Exercises
Challenge yourself with complex scenarios, performance testing, and the Buggy API.
Exercise 6: Buggy API Resilience
Objective: Test error handling with the intentionally buggy API.
Tasks:
- Implement retry logic for failed requests
- Test timeout handling (some requests take 5+ seconds)
- Verify data inconsistencies are caught
- Test pagination off-by-one errors
- Handle 500 errors gracefully
- Validate response schemas (catch missing fields)
Retry Logic Example:
typescript
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const response = await fetch(url, {
...options,
signal: AbortSignal.timeout(5000), // 5 second timeout
});
if (response.ok) return response;
// Don't retry client errors (4xx)
if (response.status >= 400 && response.status < 500) {
throw new Error(`Client error: ${response.status}`);
}
// Retry server errors (5xx)
if (attempt < maxRetries) {
const delay = Math.pow(2, attempt) * 1000; // Exponential backoff
await new Promise(resolve => setTimeout(resolve, delay));
}
} catch (error) {
if (attempt === maxRetries) throw error;
}
}
}
// Usage
test('buggy API with retry logic', async () => {
const response = await fetchWithRetry('https://api.testauto.app/api/buggy/tasks');
const data = await response.json();
expect(data).toBeDefined();
});Exercise 7: Performance Testing
Objective: Measure and test API performance.
Tasks:
- Measure response times for different endpoints
- Test with various page sizes (10, 50, 100)
- Compare V1 vs V2 performance
- Test concurrent requests
- Identify the slowest endpoints
- Create a performance report
Exercise 8: End-to-End User Flow
Objective: Test complete user journeys in the UI.
Tasks:
- Login to the application
- Create 5 tasks with different priorities
- Filter and sort tasks
- Update task statuses (TODO β IN_PROGRESS β DONE)
- Delete completed tasks
- Verify scorecard updates correctly
- Test the flow in SPA mode (
/task-manager-spa) - Compare behavior between SSR and SPA modes
Exercise 9: Visual Testing
Objective: Implement visual regression testing.
Tasks:
- Take baseline screenshots of key pages
- Implement pixel comparison tests
- Test responsive design (mobile, tablet, desktop)
- Test dark mode consistency
- Capture screenshots of different states (loading, empty, error)
Exercise 10: API Contract Testing
Objective: Validate API responses against schemas.
Tasks:
- Define JSON schemas for all endpoints
- Validate response structure matches schema
- Test required vs optional fields
- Verify data types (string, number, boolean, null)
- Test enum values (status, priority)
- Validate date formats
Schema Validation Example:
typescript
import Ajv from 'ajv';
const ajv = new Ajv();
const taskSchema = {
type: 'object',
required: ['id', 'title', 'status', 'priority', 'createdAt', 'updatedAt'],
properties: {
id: { type: 'number' },
title: { type: 'string', minLength: 1, maxLength: 200 },
description: { type: ['string', 'null'] },
status: { enum: ['TODO', 'IN_PROGRESS', 'DONE'] },
priority: { enum: ['LOW', 'MEDIUM', 'HIGH'] },
createdAt: { type: 'string', format: 'date-time' },
updatedAt: { type: 'string', format: 'date-time' }
}
};
test('task response matches schema', async () => {
const response = await axios.get('https://api.testauto.app/api/v1/tasks/1');
const validate = ajv.compile(taskSchema);
const valid = validate(response.data);
expect(valid).toBe(true);
if (!valid) console.log(validate.errors);
});π Challenge: Complete Test Suite
Ultimate Challenge: Create a comprehensive test suite covering all aspects.
Requirements:
- β API tests for all V1 endpoints
- β API tests for all V2 endpoints (with auth)
- β UI tests for both SSR and SPA modes
- β Error handling and edge cases
- β Performance benchmarks
- β Visual regression tests
- β Accessibility tests
- β Mobile responsiveness tests
- β Test data management
- β Comprehensive reporting
Success Criteria:
- All tests pass consistently
- Code coverage > 80%
- Tests run in under 5 minutes
- Clear test organization (folders, naming)
- Reusable helpers and utilities
- Documentation of test approach
Tips for Success
- π‘ Start simple: Get basic tests working before adding complexity
- π‘ Use test data builders: Create reusable fixtures
- π‘ Clean up after tests: Delete test data to avoid conflicts
- π‘ Run tests in isolation: Each test should be independent
- π‘ Use meaningful assertions: Check actual behavior, not just status codes
- π‘ Handle async properly: Use async/await consistently
- π‘ Add useful error messages: Make failures easy to debug
Next Steps
After completing these exercises, you'll have hands-on experience with:
- REST API testing
- JWT authentication
- UI automation with Playwright
- Error handling and resilience
- Performance testing
- Visual regression testing
Continue learning by exploring the Specifications page or dive deeper into the API Reference.