.rulesync/rules/testing.md
This guide covers testing strategies and best practices for the AG Grid codebase.
Behavioural tests in testing/behavioural/ are the primary test suite for AG Grid. They test the grid as a black box, instantiating the full grid to verify complex behaviours and features.
Key principles:
testing/
├── accessibility/ # Accessibility compliance tests
├── behavioural/ # Grid behaviour verification
├── csp/ # Content Security Policy tests
├── module-size/ # Bundle size monitoring
├── performance/ # Performance regression tests
└── shared/ # Shared test utilities
Unit and integration tests are co-located with source code:
packages/ag-grid-community/src/
├── feature/
│ ├── featureName.ts
│ └── featureName.test.ts
Behavioural tests in testing/behavioural/ are the primary test suite for verifying grid behaviour. They use Vitest. Watch mode is disabled by default:
# Run all behavioural tests
./behave.sh
# Run specific test file
./behave.sh "cell-editing-regression"
# Run specific test by name
./behave.sh "cell-editing-regression" -t "should handle"
# Run in watch mode
./behave.sh --watch
# Run all benchmarks
yarn nx run ag-behavioural-testing:benchmark
# Run specific benchmark file
yarn nx run ag-behavioural-testing:benchmark -- src/tree-data/datapath/benchmarks/tree-data-path.bench.ts
Unit tests in packages/ use Jest. Use --testPathPattern and --testNamePattern:
# Run all tests for a package
yarn nx test ag-grid-community
# Run specific test file
yarn nx test ag-grid-community --testPathPattern="featureName"
# Run specific test by name
yarn nx test ag-grid-community --testPathPattern="featureName" --testNamePattern="should handle"
# Run documentation E2E tests
yarn nx e2e ag-grid-docs
Note: Vitest does not support --testPathPattern or --testNamePattern. Use positional arguments for file matching and -t for test name filtering.
Follow the AAA pattern (Arrange, Act, Assert):
describe('FeatureName', () => {
let instance: FeatureName;
beforeEach(() => {
// Arrange - setup
});
afterEach(() => {
// Cleanup
jest.resetAllMocks();
});
describe('#methodName', () => {
it('should handle expected case', () => {
// Arrange
const input = createInput();
// Act
const result = instance.methodName(input);
// Assert
expect(result).toBe(expected);
});
});
});
Use it.each() for testing multiple cases:
it.each([
['case1', input1, expected1],
['case2', input2, expected2],
])('should handle %s', (_, input, expected) => {
expect(functionUnderTest(input)).toBe(expected);
});
For complex test cases, use records:
const EXAMPLES: Record<string, TestCase> = {
BASIC: {
input: {
/* ... */
},
expected: {
/* ... */
},
},
EDGE_CASE: {
input: {
/* ... */
},
expected: {
/* ... */
},
},
};
for (const [name, example] of Object.entries(EXAMPLES)) {
it(`handles ${name}`, () => {
expect(process(example.input)).toEqual(example.expected);
});
}
afterEach