Skip to content

Commit d8f83ac

Browse files
committed
Add comprehensive unit tests for ResponsiveImage component
- Create ResponsiveImage.test.js with detailed test coverage - Verify rendering with minimal and full props - Test lazy loading behavior and custom class names - Handle missing image sources gracefully - Implement tests for multiple image sources and formats - Update PropTypes to support spread props pattern - Enhance component testability and documentation
1 parent afb73df commit d8f83ac

File tree

5 files changed

+8779
-11226
lines changed

5 files changed

+8779
-11226
lines changed

TESTING_GUIDELINES.md

Lines changed: 106 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,96 +4,120 @@ This document outlines the intended structure and best practices for testing in
44
These guidelines describe the target state for testing implementations.
55
Future adjustments may be made based on project developments and recommendations provided by coworkers like Cursor AI.
66

7-
Initiallly created with ChatGPT Canvas <https://chatgpt.com/canvas/shared/67c03719cadc8191bf72e015944a81e1>
7+
Initially created with ChatGPT Canvas <https://chatgpt.com/canvas/shared/67c03719cadc8191bf72e015944a81e1>
88

9-
### 1. **Testing Framework Selection**
9+
## 1. Testing Framework Selection
1010

1111
- **Jest**: A widely used testing framework for JavaScript/React applications.
1212
- **React Testing Library**: Preferred for testing React components to ensure a user-centric approach.
1313
- **Vitest**: Considered for future adoption due to its speed and compatibility with Vite and TypeScript.
1414

15-
#### Transition Considerations
15+
### Transition Considerations
1616

17-
- Initially, Jest is expected to be used due to its deep integration with Create React App (CRA).
17+
- Initially, Jest is used due to its deep integration with Create React App (CRA).
1818
- As the project moves towards Vite and TypeScript, Vitest may replace Jest to take advantage of its performance benefits and native support.
1919

20-
### 2. **Planned Directory Structure for Tests**
20+
## 2. Directory Structure for Tests
2121

22-
To maintain a clean separation between source code and tests, the following directory structure is proposed:
22+
For better organization and maintainability, we follow a hybrid approach:
2323

2424
```
2525
project-root/
2626
├── src/
2727
│ ├── components/
28-
│ │ ├── ImageWithContent/
29-
│ │ │ ├── ImageWithContent.js
30-
│ │ │ ├── ImageWithContent.scss
28+
│ │ ├── ComponentName/
29+
│ │ │ ├── ComponentName.js
30+
│ │ │ ├── ComponentName.scss
31+
│ │ │ ├── ComponentName.test.js
3132
│ │ │ ├── index.js
3233
│ │ │ ├── README.md
33-
│ │ ├── LinkCard/
34-
│ │ │ ├── ...
35-
│ │ ├── ResponsiveImage/
36-
│ │ │ ├── ...
3734
│ ├── tests/
38-
│ │ ├── unit/
39-
│ │ │ ├── ImageWithContent.test.js
4035
│ │ ├── snapshot/
41-
│ │ │ ├── ImageWithContent.snapshot.test.js
4236
│ │ ├── integration/
43-
│ │ │ ├── ImageWithContent.integration.test.js
4437
│ │ ├── accessibility/
45-
│ │ │ ├── ImageWithContent.a11y.test.js
38+
│ │ ├── fixtures/
39+
│ │ │ ├── testData.js
4640
├── package.json
47-
├── jest.config.js (if using Jest)
48-
├── vitest.config.ts (if using Vitest in the future)
49-
├── babel.config.js
50-
├── tsconfig.json (if using TypeScript)
51-
└── README.md
41+
└── setupTests.js
5242
```
5343

54-
### 3. **Planned Test Organization**
44+
## 3. Test Organization
5545

56-
- All test types will be placed in a `tests/` directory to avoid cluttering source files.
57-
- Separate subdirectories will be created for different test types, ensuring clarity and maintainability.
46+
- **Unit Tests**: Co-located with their respective components for easier discovery and maintenance
47+
- **Specialized Tests**: Placed in a dedicated `tests/` directory by test type (snapshot, integration, accessibility)
5848

59-
### 4. **Types of Tests to Implement**
49+
## 4. Types of Tests to Implement
6050

6151
- **Unit Tests**: Verify the smallest functional parts of the application.
6252
- **Snapshot Tests**: Ensure the rendered output remains consistent over time.
6353
- **Integration Tests**: Confirm components work correctly with dependencies and external APIs.
6454
- **Accessibility Tests**: Use `jest-axe` to enforce accessibility best practices.
6555

66-
### 5. **Example Unit Test (Target Implementation)**
67-
68-
```tsx
69-
import { render, screen } from "@testing-library/react";
70-
import ImageWithContent from "../../src/components/ImageWithContent";
71-
72-
test("renders correctly", () => {
73-
render(<ImageWithContent title="Hello" />);
74-
expect(screen.getByText("Hello")).toBeInTheDocument();
56+
## 5. Example Unit Test (Current Implementation)
57+
58+
```javascript
59+
// ResponsiveImage.test.js
60+
import React from 'react';
61+
import { render, screen } from '@testing-library/react';
62+
import ResponsiveImage from './ResponsiveImage';
63+
64+
describe('ResponsiveImage', () => {
65+
const minimalProps = {
66+
sources: { small: '/images/test-small.jpg' },
67+
alt: 'Test image'
68+
};
69+
70+
it('renders with minimal required props', () => {
71+
render(<ResponsiveImage {...minimalProps} />);
72+
const imgElement = screen.getByAltText('Test image');
73+
expect(imgElement).toBeInTheDocument();
74+
expect(imgElement.getAttribute('src')).toBe('/images/test-small.jpg');
75+
});
76+
77+
// Additional tests...
7578
});
7679
```
7780

78-
### 6. **Mocking External Dependencies**
81+
## 6. Mocking External Dependencies
7982

8083
- `jest.fn()` will be used for simple mocks.
8184
- `msw` (Mock Service Worker) will be considered for API interactions.
85+
- For CSS/SCSS modules, use `identity-obj-proxy` in Jest configuration.
86+
- For window/DOM APIs (especially for responsive components), use `jest.spyOn`:
87+
88+
```javascript
89+
// Example of spying on window methods
90+
const consoleSpy = jest.spyOn(console, 'error').mockImplementation();
91+
// Test code...
92+
expect(consoleSpy).toHaveBeenCalled();
93+
consoleSpy.mockRestore();
94+
```
95+
96+
## 7. Test Data Management
97+
98+
- Use fixture files for complex test data in `src/tests/fixtures/`
99+
- For image testing, use mock paths like `/images/test-small.jpg` (no need for actual images)
100+
- Add test IDs with the format `data-testid="component-name-element-type"` when needed
82101

83-
### 7. **Planned CI/CD Integration**
102+
## 8. CI/CD Integration
84103

85104
To ensure code quality, tests will be executed automatically in CI/CD pipelines:
86105

87106
- GitHub Actions (or another CI tool) will run tests on push and pull requests.
88-
- A test script in `package.json` will facilitate local execution:
107+
- Test scripts in `package.json` will facilitate local execution:
89108

90109
```json
110+
{
91111
"scripts": {
92-
"test": "jest --coverage"
112+
"test": "react-scripts test",
113+
"test:coverage": "react-scripts test --coverage",
114+
"test:watch": "react-scripts test --watch",
115+
"test:ci": "react-scripts test --ci --watchAll=false"
93116
}
94-
```
117+
}
118+
```
95119

96-
### 8. **Future Publishing Considerations**
120+
## 9. Future Publishing Considerations
97121

98122
Before publishing to npm or deploying, the following test requirements should be met:
99123

@@ -109,3 +133,43 @@ Before publishing to npm or deploying, the following test requirements should be
109133
By following this guideline, testing in the project will remain well-structured, scalable, and adaptable to future technology choices.
110134

111135
Adjustments to these guidelines may be made as the project evolves, and recommendations from Cursor AI will be considered for further improvements.
136+
137+
## 10. DOM Interaction Best Practices
138+
139+
- **Avoid direct DOM manipulation**: Avoid using methods like `querySelector`, `getElementsByClassName`, `closest`, or direct element property access in tests
140+
141+
- **Use Testing Library queries**: Always prefer queries provided by React Testing Library in this order of preference:
142+
1. `getByRole` - Most accessible and user-centric
143+
2. `getByLabelText` - For form elements with labels
144+
3. `getByPlaceholderText` - For input fields with placeholders
145+
4. `getByText` - For elements containing visible text
146+
5. `getByDisplayValue` - For form elements with a specific value
147+
6. `getByAltText` - For images
148+
7. `getByTitle` - For elements with title attributes
149+
8. `getByTestId` - Last resort when no other selectors work
150+
151+
- **Component design considerations**:
152+
- Design components to accept and spread additional props to their root elements:
153+
154+
```jsx
155+
const MyComponent = ({ className = '', ...otherProps }) => (
156+
<div className={`my-component ${className}`} {...otherProps}>
157+
{/* component content */}
158+
</div>
159+
);
160+
```
161+
162+
- This makes them more testable by allowing `data-testid` attributes
163+
164+
- **Why this matters**:
165+
- Tests become more resilient to implementation changes
166+
- Encourages building accessible components
167+
- Tests better reflect how users interact with the UI
168+
- Improves test maintenance and clarity
169+
170+
- **Origin of these rules**:
171+
- These practices come from the core philosophy of Testing Library: "The more your tests resemble the way your software is used, the more confidence they can give you."
172+
- Enforced by `eslint-plugin-testing-library` rules, particularly `testing-library/no-node-access`
173+
- Developed by Kent C. Dodds and the Testing Library community as a reaction against implementation-detail-focused testing
174+
- The error "Avoid direct Node access. Prefer using the methods from Testing Library" comes from the `testing-library/no-node-access` ESLint rule
175+
- Official documentation: <https://testing-library.com/docs/queries/about/#priority>

0 commit comments

Comments
 (0)