If you don't consider how you'll test the code, UI, business logic, and API calls can get tangled in one component. When the immediate goal is to get something working, it is easy to put everything into useEffect.
Asking yourself how to test the code pushes you to improve its structure.
src/hooks/useUserList.ts
// [변화] 로직은 Hook으로 분리되어 독립적으로 테스트 가능해졌습니다.export function useUserList() { const [users, setUsers] = useState([]); // ... 데이터 fetching 로직 return { users };}
Custom hook
— Separating business logic makes it easier to reuse and test.
Container and presenter
— Separating data handling from rendering simplifies UI tests.
3. Frontend Testing Strategy: The Testing Trophy 🔗
In Part 13, we learned about the
Testing Trophy
. Choose a type of test that fits the behavior you're verifying.
Static analysis
Use
TypeScript
and
ESLint
to catch typos and basic errors. These checks give you a lot of coverage for little effort.
Unit tests
Check utility functions or complex hook logic.
Integration tests
These are the
most important
. Use
RTL
to verify how users interact with components.
End-to-end (E2E) tests
Verify critical scenarios such as checkout and sign-in in a real browser.
We tested in jsdom, a simulated browser environment. To check that styles and navigation work in real browsers such as Chrome and Safari, use an
E2E tool
. We'll cover this in an upcoming
bonus installment
.
Visual Regression Testing with Storybook or Chromatic 🔗
What if a feature still works but someone accidentally changes the button color? These tools compare screenshots pixel by pixel to check visual details that are hard to verify in code.
If the frontend's mock data and the real API specification diverge, the application can fail. Contract testing helps catch that by failing a test when the agreed API specification changes.