Testing
This guide introduces the testing strategy for flywave.gl and how to run tests.
Test Types
flywave.gl uses multiple test types to ensure code quality:
- Unit Tests: Test individual functions and classes
- Integration Tests: Test interactions between modules
- Performance Tests: Evaluate rendering and computational performance
- Rendering Tests: Validate the correctness of visual output
Testing Tools Used
- Jest: Testing framework
- Karma: Test runner
- Playwright: End-to-end testing
- Chrome DevTools Protocol: Performance testing
Running Tests
Running the Full Test Suite
# Run all unit tests using Chrome Headless
pnpm test
Running Tests in Watch Mode
For development, run tests in watch mode to automatically re-run when files change:
# Run tests in watch mode
pnpm test:watch
Running Tests in Browser
To run tests in an actual browser:
# Run tests in browser
pnpm test-browser
Debugging Tests
To debug tests with Chrome DevTools:
# Run tests in debug mode
pnpm test-debug
Test Configuration
Jest Configuration
Jest configuration is defined in jest.config.js at the root of the project.
Karma Configuration
Karma configuration is defined in karma.conf.js.
Test Environment
Tests run in a headless Chrome environment by default, but can be configured to run in other browsers.
Writing Tests
Test Structure
Tests are organized in __tests__ directories within each package.
Unit Tests
Example unit test:
import { MapView } from '../src/MapView';
describe('MapView', () => {
it('should create a new instance', () => {
const mapView = new MapView();
expect(mapView).toBeInstanceOf(MapView);
});
});
Integration Tests
Integration tests verify interactions between components:
import { MapView, TerrainDataSource } from '@flywave/flywave.gl';
describe('MapView with TerrainDataSource', () => {
it('should add terrain data source', () => {
const mapView = new MapView();
const terrainDataSource = new TerrainDataSource();
mapView.addDataSource(terrainDataSource);
expect(mapView.getDataSources()).toContain(terrainDataSource);
});
});
Async Tests
For asynchronous operations:
import { loadData } from '../src/dataLoader';
describe('Data Loader', () => {
it('should load data asynchronously', async () => {
const data = await loadData('test-data.json');
expect(data).toBeDefined();
});
});
Test Coverage
Generating Coverage Reports
To generate test coverage reports:
# Generate coverage report
pnpm test-cov
Coverage Requirements
Aim for at least 80% test coverage for new features.
Coverage reports are generated in the coverage/ directory.
Performance Testing
Running Performance Tests
To run performance tests:
# Run performance tests in Node.js environment
pnpm performance-test-node
Browser Performance Tests
To run performance tests in browser:
# Run browser performance tests
pnpm performance-test-browser
Rendering Tests
Visual Regression Testing
Visual regression tests ensure consistent rendering:
# Run rendering tests
pnpm test-rendering
Continuous Integration Testing
CI Test Suite
All tests are run automatically in the CI pipeline:
# Run CI test suite
pnpm ci:test
This includes:
- Unit tests
- Integration tests
- Code linting
- Type checking
Mocking and Stubbing
Using Mocks
For mocking dependencies:
import { mocked } from 'jest-mock';
jest.mock('../src/dataService');
describe('Component', () => {
it('should use mocked service', () => {
const mockService = mocked(dataService);
mockService.fetchData.mockResolvedValue({ data: 'test' });
// Test implementation
});
});
Stubbing External Dependencies
To stub external APIs:
beforeEach(() => {
global.fetch = jest.fn(() =>
Promise.resolve({
json: () => Promise.resolve({ data: 'test' })
})
);
});
Test Best Practices
- Write clear test descriptions: Use descriptive
itanddescribeblocks - Test one thing at a time: Keep tests focused and isolated
- Use meaningful assertions: Assert specific outcomes
- Mock external dependencies: Isolate the code under test
- Clean up after tests: Use
afterEachto clean up state - Test edge cases: Include boundary conditions and error cases
Troubleshooting
Common Test Issues
-
Async test timeouts: Increase timeout values for slow tests:
it('slow test', async () => {
// Test implementation
}, 10000); // 10 second timeout -
Mocking issues: Ensure mocks are properly configured before tests run
-
Environment issues: Verify test environment matches development environment
Debugging Test Failures
To debug failing tests:
- Run the specific failing test in isolation
- Use
console.logstatements to trace execution - Run tests in debug mode with breakpoints
- Check for race conditions in async tests
For persistent issues, consult the project documentation or seek help from the development team.