This document explains the comprehensive testing strategy for the ClickHouse monitoring dashboard, including unit tests, integration tests, component tests, and best practices.
Fast, isolated tests that don't require external dependencies.
Examples:
lib/clickhouse.test.ts- Tests configuration parsing and client setuplib/utils.test.ts- Tests utility functionslib/format-readable.test.ts- Tests data formatting
Pattern:
// Mock external dependencies
jest.mock('@clickhouse/client', () => ({
createClient: jest.fn(),
}))
// Test the logic, not the external service
it('should parse host configuration correctly', () => {
process.env.CLICKHOUSE_HOST = 'host1,host2'
const result = getClickHouseHosts()
expect(result).toEqual(['host1', 'host2'])
})Tests that simulate integration between components without real external services.
Examples:
lib/query-config/__tests__/query-config.test.ts- Tests query configurations with mocked databaselib/__tests__/host-switching-integration.test.ts- Tests host switching logic
Pattern:
// Mock the external service
jest.mock('@/lib/clickhouse', () => ({
fetchData: jest.fn(),
}))
// Test the integration logic
it('should handle host switching correctly', async () => {
const mockFetchData = fetchData as jest.MockedFunction<typeof fetchData>
mockFetchData.mockResolvedValue({ data: [...], metadata: {...} })
// Test your component logic here
})Tests that analyze code without executing it.
Examples:
lib/__tests__/fetchdata-hostid.test.ts- Ensures all fetchData calls include hostId
Tests that run only when real ClickHouse is available.
Examples:
lib/__tests__/integration-environment.test.ts- Real database tests when available
Visual and behavioral tests for UI components using Cypress.
Component tests are essential for ensuring the reliability and stability of the UI components, helping to catch regressions and errors early in the development process.
When contributing new component tests, please follow these guidelines:
- Isolate the Component: Ensure the component is tested in isolation, mocking any external dependencies if necessary.
- Test the Interface, Not the Implementation: Focus on testing the behavior visible to the user, not the internal implementation details.
- Cover All Use Cases: Include tests for all the component's use cases, including rendering with different props and user interactions.
- Use Descriptive Test Names: Test names should clearly describe what they are testing and the expected outcome.
- Arrange-Act-Assert Pattern: Structure your tests with setup ('Arrange'), execution ('Act'), and verification ('Assert') steps.
Here are some common assertions and patterns used in our component tests:
- Rendering: Verify that the component renders correctly with various props.
- User Interaction: Simulate user interactions (e.g., clicks, typing) and verify the component behaves as expected.
- Event Handling: Ensure that the component correctly handles events and calls the appropriate callback functions.
- Conditional Rendering: Test the component's behavior when conditional rendering logic is involved.
For more detailed examples, refer to the existing component tests in the components directory.
We use Cypress for our component testing. Refer to the Cypress documentation for more details on writing tests using Cypress.
All component tests are automatically run as part of the Continuous Integration (CI) pipeline on every pull request. Ensure your tests pass locally before submitting your pull request.
bun run testThis runs unit tests with mocked dependencies - fast and reliable.
bun run test-queries-configTests query configurations with mocked database responses.
bun run test:component:headless # Run component tests
bun run test:e2e:headless # Run end-to-end testsbun run jest # Excludes query-config tests
bun run test-queries-config # Only query-config testsTests use jest.setup.js for:
- Mock implementations of
fetchDataandgetHostIdCookie - Test utilities for host switching scenarios
- Consistent mock data across tests
For running optional integration tests:
# Start ClickHouse with Docker
docker run -d -p 8123:8123 --name clickhouse-test clickhouse/clickhouse-server
# Set environment variables
export CLICKHOUSE_HOST=http://localhost:8123
export CLICKHOUSE_USER=default
export CLICKHOUSE_PASSWORD=
# Run tests (integration tests will now execute)
bun run test- Mock external dependencies (ClickHouse, APIs)
- Test business logic, not external services
- Use the existing mock utilities from
jest.setup.js
- Add to
queriesarray in your config file - Mark as
optional: trueif the query depends on optional ClickHouse features - The test will automatically validate SQL syntax and parameter handling
- Use
mockGetHostIdCookieandmockFetchDatafrom test utilities - Test both host switching scenarios and error cases
- Verify
hostIdparameter is included in allfetchDatacalls
- Mock external dependencies (databases, APIs, file system)
- Test business logic and component behavior
- Use descriptive test names that explain the scenario
- Test both success and error cases
- Include timeout configuration for async tests
- Make real database connections in unit tests
- Rely on external services being available
- Test implementation details instead of behavior
- Skip error handling scenarios
- Leave tests without timeout configuration
If tests are timing out:
- Check if you're making real HTTP/database calls instead of using mocks
- Verify
jest.config.jshas appropriate timeout settings - Ensure async tests are properly awaited
If mocks aren't working:
- Verify mock setup in
jest.setup.js - Check that mocks are imported before the modules they mock
- Use
jest.clearAllMocks()inbeforeEachhooks
Integration tests automatically skip when:
CI=trueenvironment variable is setCLICKHOUSE_HOSTis not configured- ClickHouse connection fails within 5 seconds
This is expected behavior - unit tests with mocks provide sufficient coverage.
The project recently fixed Jest timeout issues caused by:
- Real Database Connections:
query-config.test.tswas trying to connect to real ClickHouse - Missing Timeout Configuration: Jest had no timeout limits configured
- Missing Mock Setup: Integration tests lacked proper mock infrastructure
- Added Jest timeout configuration (30 seconds)
- Created comprehensive mock setup in
jest.setup.js - Converted integration tests to use mocks instead of real connections
- Added optional integration tests that only run when ClickHouse is available
- Enhanced error handling with proper mock responses