| technology | JavaScript | ||||||
|---|---|---|---|---|---|---|---|
| domain | frontend | ||||||
| level | Senior/Architect | ||||||
| version | ES6-ES2024 | ||||||
| tags |
|
||||||
| ai_role | Senior JavaScript Testing Expert | ||||||
| last_updated | 2026-04-05 |
- Primary Goal: Enforce robust, deterministic, and maintainable testing standards for modern JavaScript applications.
- Target Tooling: Cursor, Windsurf, Antigravity.
- Tech Stack Version: ES6-ES2024
Important
Strict Constraints for AI:
- Always favor AAA (Arrange, Act, Assert) pattern.
- Never write tests that rely on global state or execution order.
Note
Context: Tests that share state or depend on a specific execution order.
let user;
test('create user', () => {
user = { id: 1, name: 'Alice' };
expect(user.id).toBe(1);
});
test('update user', () => {
// Relies on the user object created in the previous test
user.name = 'Bob';
expect(user.name).toBe('Bob');
});Tests that depend on global variables or execution order are brittle. If the test runner executes them in parallel or out of order, they will fail unpredictably, leading to flaky test suites.
test('create user', () => {
const user = { id: 1, name: 'Alice' };
expect(user.id).toBe(1);
});
test('update user', () => {
const user = { id: 1, name: 'Alice' }; // Independent setup
user.name = 'Bob';
expect(user.name).toBe('Bob');
});| Feature | Unit Testing | Integration Testing | End-to-End (E2E) Testing |
|---|---|---|---|
| Scope | Single isolated function/component | Multiple connected units | Full application workflow |
| Speed | Extremely Fast (<1ms) | Fast to Medium | Slow (seconds to minutes) |
| Cost to Write/Maintain | Low | Medium | High |
| Confidence Level | Low (doesn't catch contract issues) | Medium | High (simulates real user) |
Ensure every test is fully isolated. Use beforeEach or setup functions to instantiate fresh state for every individual test case.
Note
Context: Testing asynchronous functions.
test('fetches data', () => {
fetchData().then(data => {
expect(data).toBe('success');
});
});If fetchData takes time, the test function will complete synchronously before the Promise resolves. The assertion is never executed, and the test passes falsely.
test('fetches data', async () => {
const data = await fetchData();
expect(data).toBe('success');
});Always use async/await when testing asynchronous code. This ensures the test runner waits for the Promise to resolve or reject before marking the test as complete.