7.7 KiB
End-to-End Testing Documentation for Home Monitor
Table of Contents
- Introduction
- Testing Strategy
- Test Environment Setup
- Running Tests
- Test Structure
- Test Cases Overview
- Writing New Tests
- Best Practices
- Troubleshooting
- References
Introduction
End-to-End (E2E) testing verifies that the application functions correctly from a user's perspective by testing the complete application workflow. This document outlines the E2E testing approach for the Home Monitor application.
Goals of E2E Testing
- Validate critical user flows function correctly
- Ensure components work together as expected
- Detect regression issues before production deployment
- Verify application behavior in real-world scenarios
Testing Strategy
Home Monitor uses Cypress for E2E testing with two primary approaches:
- Mock Testing (Without Server): Fast, reliable tests using mocked DOM elements and data
- Real Environment Testing (With Server): Full application testing with a running development server
Mock vs. Real Testing Comparison
| Aspect | Mock Testing | Real Environment Testing |
|---|---|---|
| Speed | Very fast (< 1s per test) | Slower (depends on app loading time) |
| Reliability | Highly stable | May be affected by server/network issues |
| Coverage | Limited to structure and basic interactions | Tests actual rendering and behaviors |
| Dependencies | None (no server needed) | Requires development server |
| Best for | CI/CD, quick verification | Final validation, regression testing |
Test Environment Setup
Prerequisites
- Node.js (v14+)
- npm or yarn
- Chrome browser (for visual testing)
Installation
# Install dependencies
cd project-softweng/web-app
npm install
Running Tests
Option 1: Tests with Mock Environment (No Server)
# Run all tests in headless mode
export CYPRESS_SKIP_SERVER_CHECK=true
npm run test:e2e
# Run specific test file
export CYPRESS_SKIP_SERVER_CHECK=true
npx cypress run --spec "tests/e2e/app.spec.ts"
Option 2: Tests with Real Application (Server Required)
Automated Script Method
# Use the automated script (starts server, runs tests, stops server)
./tests/e2e/run-e2e-tests.sh
Manual Method
-
Start the development server:
# Terminal 1 npm run serve -
Run the tests:
# Terminal 2 # Headless mode npx cypress run --spec "tests/e2e/app.spec.ts" # Interactive mode npx cypress open
Interactive Mode (Development)
npm run cypress:open
This opens the Cypress Test Runner where you can:
- Select individual tests to run
- See test execution in real-time
- Debug failing tests with time-travel debugging
Test Structure
Directory Structure
web-app/
├── tests/
│ ├── e2e/ # E2E test files
│ │ ├── app.spec.ts # Main application tests
│ │ └── run-e2e-tests.sh # Script for running tests with server
│ └── support/ # Support files
│ ├── commands.ts # Custom Cypress commands
│ └── e2e.ts # Global setup for E2E tests
└── cypress.config.ts # Cypress configuration
Test Files Organization
Each test file follows this structure:
- Setup: Import dependencies and set up the test environment
- Beforehooks: Prepare the application state before each test
- Test Cases: Individual test scenarios grouped by feature
- Helper Functions: Support functions for test cases
Test Cases Overview
The E2E test suite covers the following scenarios:
-
Application Loading
- Verify application loads with correct title
- Confirm main layout sections are visible
-
Control Panel Functionality
- Verify control panel buttons are present
- Test "Fetch Measurements" button works
- Test "New Measurements" button works
-
Filtering Controls
- Test user selection dropdown
- Test room selection dropdown
- Test device selection dropdown
-
Data Visualization
- Verify chart displays correctly
- Test chart updates when data changes
-
Error Handling
- Test error state display
- Test empty data state display
-
Responsive Design
- Verify layout adapts to desktop viewport
- Verify layout adapts to mobile viewport
Writing New Tests
Adding a New Test Case
- Identify the feature or flow to test
- Determine the expected behavior
- Add a new test case to the appropriate spec file:
it('should [describe expected behavior]', () => {
// Setup any preconditions
// Perform actions
// Assert expected outcomes
});
Custom Commands
Custom commands are available to simplify test writing:
// Select an option from a multiselect dropdown
cy.selectMultiselectOption('user-select', 'user1');
// Wait for chart to load and be visible
cy.waitForChart();
// Check application loading state
cy.checkLoadingState(false);
API Mocking
Use Cypress's intercept feature to mock API responses:
// Mock GET request
cy.intercept('GET', '**/api/measurements*', {
statusCode: 200,
body: {
data: [
{ time: new Date(2023, 0, 1, 10, 0).getTime(), value: 22.5, type: 'temperature' }
]
}
}).as('getMeasurements');
// Wait for the intercepted request
cy.wait('@getMeasurements');
Best Practices
-
Test Independence
- Each test should be able to run independently
- Avoid dependencies between tests
- Reset state between tests
-
Selector Strategy
- Prefer data attributes for test selectors (e.g.,
data-cy,data-testid) - Avoid using CSS classes that might change with styling updates
- Establish a consistent selector naming convention
- Prefer data attributes for test selectors (e.g.,
-
Handling Asynchronous Operations
- Use explicit waits rather than arbitrary timeouts
- Wait for specific elements or network requests rather than fixed delays
- Handle loading states appropriately
-
Test Data Management
- Use consistent test data
- Mock external dependencies
- Consider using fixtures for complex data structures
-
Error Handling
- Add proper error handling in tests
- Use
Cypress.on('uncaught:exception')for expected application errors
Troubleshooting
Common Issues and Solutions
| Issue | Solution |
|---|---|
| Tests fail with 401 errors | Add Cypress.on('uncaught:exception', () => false) to handle authentication errors |
| Elements not found | Increase timeouts or check selectors; ensure elements are in the DOM |
| Click actions failing | Use { force: true } option if elements might be covered by overlays |
| Tests passing locally but failing in CI | Check environment differences; ensure CI has all required dependencies |
| Timeouts on waiting for elements | Increase defaultCommandTimeout in cypress.config.ts |
Debugging Strategies
-
Use Cypress's Debug Tools
- Add
.debug()to pause execution at a specific point - Use the time-travel debugger in interactive mode
- Add
-
Add Logging
- Use
cy.log()to add informative messages in the test - Check browser console for application errors
- Use
-
Visualize Test State
- Enable screenshots and videos for failed tests
- Use
cy.screenshot()at critical points