Skip to main content
Documentation

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:

  1. Write a test to GET all tasks and verify the response contains an array
  2. Create a new task with POST and verify it returns 201 status
  3. Retrieve the created task by ID
  4. Update the task status to "DONE"
  5. Delete the task and verify 204 response
  6. 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:

  1. Navigate to /task-manager
  2. Verify the page title contains "Task Manager"
  3. Count the number of tasks displayed
  4. Click on a filter button (TODO/IN_PROGRESS/DONE)
  5. Verify only tasks with that status are visible
  6. Use the search box to filter tasks
  7. 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:

  1. Login with valid credentials and store the token
  2. Use the token to access protected endpoints
  3. Test with invalid credentials (should fail)
  4. Test with expired/invalid token (should return 401)
  5. Test token refresh functionality
  6. 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:

  1. Test pagination with different page sizes
  2. Verify correct total elements count
  3. Test edge cases (page 0, last page, invalid page)
  4. Combine filtering and pagination
  5. Test sorting by different fields
  6. Verify consistency of results across pages

Exercise 5: UI Form Testing

Objective: Test the create/edit task forms with various inputs.

Tasks:

  1. Open the create task form
  2. Fill all required fields and submit
  3. Verify the task appears in the list
  4. Test form validation (empty fields, invalid data)
  5. Edit an existing task and save
  6. Cancel form without saving
  7. 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:

  1. Implement retry logic for failed requests
  2. Test timeout handling (some requests take 5+ seconds)
  3. Verify data inconsistencies are caught
  4. Test pagination off-by-one errors
  5. Handle 500 errors gracefully
  6. 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:

  1. Measure response times for different endpoints
  2. Test with various page sizes (10, 50, 100)
  3. Compare V1 vs V2 performance
  4. Test concurrent requests
  5. Identify the slowest endpoints
  6. Create a performance report

Exercise 8: End-to-End User Flow

Objective: Test complete user journeys in the UI.

Tasks:

  1. Login to the application
  2. Create 5 tasks with different priorities
  3. Filter and sort tasks
  4. Update task statuses (TODO β†’ IN_PROGRESS β†’ DONE)
  5. Delete completed tasks
  6. Verify scorecard updates correctly
  7. Test the flow in SPA mode (/task-manager-spa)
  8. Compare behavior between SSR and SPA modes

Exercise 9: Visual Testing

Objective: Implement visual regression testing.

Tasks:

  1. Take baseline screenshots of key pages
  2. Implement pixel comparison tests
  3. Test responsive design (mobile, tablet, desktop)
  4. Test dark mode consistency
  5. Capture screenshots of different states (loading, empty, error)

Exercise 10: API Contract Testing

Objective: Validate API responses against schemas.

Tasks:

  1. Define JSON schemas for all endpoints
  2. Validate response structure matches schema
  3. Test required vs optional fields
  4. Verify data types (string, number, boolean, null)
  5. Test enum values (status, priority)
  6. 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.