Unit & Integration Testing
Relevant source files
The following files were used as context for generating this wiki page:
Testing within the Grafana ecosystem is divided into three primary tiers: Frontend tests, Backend tests, and End-to-End (E2E) tests. The project emphasizes clean, readable, and loosely coupled code verified through a combination of unit tests for individual logic components and integration tests for service-level or database interactions.
Sources: contribute/developer-guide.md:126-128, contribute/backend/style-guide.md:12-14
Frontend Testing Architecture
Frontend testing primarily utilizes Jest as the test runner and React Testing Library (RTL) for component testing. The architecture favors testing user behavior over implementation details, encouraging the use of accessibility-based queries and asynchronous interaction simulations.
Key Tools and Libraries
| Tool | Description |
|---|---|
| Jest | Primary test runner and assertion library for frontend code. |
| React Testing Library | Used for rendering components and querying the DOM based on user-centric roles. |
| msw (Mock Service Worker) | Preferred tool for API mocking to simulate realistic network behavior and loading states. |
| user-event | Library used to simulate realistic user interactions (clicks, typing) in tests. |
Sources: contribute/developer-guide.md:130-132, public/app/features/alerting/unified/AGENTS.md:165-174, contribute/style-guides/testing.md:10-12, packages/grafana-test-utils/package.json:52-58
Component Testing Patterns
Grafana's frontend testing guidelines recommend querying elements by their ARIA roles (e.g., *ByRole) to ensure accessibility. When testing asynchronous components like AsyncSelect, developers must mock the backendSrv to provide resolved promises for data.
The diagram shows the standard flow of a frontend component test involving asynchronous data fetching and user interaction.
Sources: contribute/style-guides/testing.md:4-8, contribute/style-guides/testing.md:108-115
Backend Testing Architecture
The backend testing suite is built on the Go standard testing library, supplemented by testify for assertions and mocks. Tests are categorized into unit tests and integration tests, with the latter often requiring a database environment.
Backend Test Categorization
- Unit Tests: Rapid tests covering individual functions or packages without external dependencies.
- Integration Tests: Tests that interact with databases (SQLite, MySQL, PostgreSQL). These functions must start with
TestIntegrationand usetestutil.SkipIntegrationTestInShortMode(t).
Sources: contribute/backend/style-guide.md:16-18, contribute/backend/style-guide.md:41-48
Database and Suite Management
The testsuite package provides utilities for package-level setup and teardown, specifically for managing test databases. Each package using a database MUST define a TestMain function to ensure proper cleanup.
func TestMain(m *testing.M) {
testsuite.Run(m)
}
Sources: contribute/backend/style-guide.md:21-38
Mocking and Assertions
The project uses testify/mock for interface-based mocking. For complex interfaces, mockery is recommended to generate mock implementations automatically.
This diagram illustrates the relationship between the standard Go testing package and the testify extensions used for assertions and mocking.
Sources: contribute/backend/style-guide.md:52-58, contribute/backend/style-guide.md:71-75, contribute/backend/style-guide.md:112-115
Recommended Practices
Grafana maintains a set of "currently recommended practices" to modernize the codebase and improve testability.
Evolution of Testing Standards
- Dependency Injection: Moving away from global state by using Wire to make components more testable.
- Context Propagation: Propagating
context.Contextthrough all layers (API, service, database) to allow for contextual logging and tracing in tests. - Standard Library Transition: Migrating from legacy tools like
GoConveyto standardtestingwithtestify. - JSON Handling: Avoiding the legacy
simplejsonpackage in favor of the standardencoding/jsonwith defined Go structs.
Sources: contribute/backend/recommended-practices.md:60-64, contribute/backend/recommended-practices.md:82-87, contribute/backend/recommended-practices.md:112-117, contribute/backend/recommended-practices.md:126-133
Integration Test Environments
To run integration tests for specific databases, developers use Docker-based environments managed via the Makefile.
| Database | Command to Run Tests | Devenv Block |
|---|---|---|
| SQLite | go test -tags=integration ./pkg/... | Default |
| MySQL | make test-go-integration-mysql | mysql_tests |
| PostgreSQL | make test-go-integration-postgres | postgres_tests |
Sources: contribute/developer-guide.md:139-152
Testing in Feature Modules (Alerting Example)
Specific modules like Unified Alerting have specialized testing patterns. They require MSW for all API mocking to ensure proper handling of loading and error states in the UI.
- Permission Mocking: Uses
grantUserPermissionsto simulate RBAC (Role-Based Access Control) scenarios. - Factory Pattern: Uses
alertingFactoryfor building consistent test data rather than manually creating objects. - MSW Handlers: Located in
packages/grafana-alerting/src/grafana/api/notifications/v0alpha1/mocks/handlers.
Sources: public/app/features/alerting/unified/AGENTS.md:176-180, public/app/features/alerting/unified/AGENTS.md:195-200, public/app/features/alerting/unified/AGENTS.md:214-220
Summary
Unit and integration testing in Grafana is a multi-layered discipline that prioritizes automation, accessibility, and standardized assertions. By leveraging modern tools like Playwright for E2E, RTL for frontend units, and testify for backend logic, the project ensures stability across its diverse tech stack. Continuous refactoring efforts aim to eliminate global state and legacy packages, further improving the reliability of the test suite.
Sources: contribute/developer-guide.md:126-128, contribute/backend/recommended-practices.md:10-15