Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[김동규] 8장: 좋은 리액트 코드 작성을 위한 환경 구축하기 #65

Merged
merged 1 commit into from
Feb 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions 8장/김동규.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# 8장 좋은 리액트 코드 작성을 위한 환경 구축하기

#스터디-리액트딥다이브

## 8.1 ESLint를 활용한 정적 코드 분석

### 8.1.1 ESLint 살펴보기

ESLint가 코드를 분석하는 방법은 아래와 같다.

1. 자바스크립트 코드를 문자열로 읽는다.
2. 자바스크립트 코드를 분석할 수 있는 parser로 코드를 구조화한다.
3. 2번에서 구조화 한 트리를 AST(Asbstract Synatx Tree)라 하며, 이 트리를 기준으로 각종 규칙과 대조한다.
4. 규칙과 대조했을 때 이를 위반한 코드를 알리거나 수정한다.

ESLint의 기본 parser는 `espree` 이다. 분석 결과를 바탕으로 코드가 잘못 됬는지, 어떻게 수정해야하는지 판단해야 하는데 이것을 `규칙(Rules)` 이라고 한다. 이 특정한 규칙의 모음을 `plugins`라고 한다.

### 8.1.2 eslint-plugin과 eslint-config

eslint-plugin 접두사의 패키지는 규칙을 모아놓은 패키지, eslint-config 접두사의 패키지는 eslint-plugin을 한데 묶어서 완벽하게 한 세트로 제공하는 패키지 이다.
일반적으로 eslint-config 를 설치해서 당장 사용한다.

### 8.1.3 나만의 ESLint 규칙 만들기

조직 내 규칙이나 코드 변화로 인해 일괄적으로 고쳐야하는 경우, ESLint 규칙을 생성해서 효율적으로 고칠 수 있다. 규칙은 하나씩 만들어 배포하는 것은 불가능하며, 반드시 eslint-plugin 형태로 규칙을 묶음으로 배포하는 것만 가능하다.

### 8.1.4 주의할 점

#### Prettier와 충돌

ESLint가 잠재적인 코드 문제를 분석해 준다면, Prettier는 코드 포맷팅과 관련된 작업을 하는 툴이다. 해결 방법은 아래와 같다.

- 서로 규칙이 충돌되지 않게 규칙을 잘 선언한다.
- 자바스크립트나 타입스크립트는 ESLint에 그외 파일을 Prettier에 맡긴다.

#### react-hooks/no-exhaustive-deps

useEffect나 useMemo 같은 훅의 의존성 배열을 제대로 선언했는지 확인하는 역할을 한다. 총 1,800여줄로 구성되어 있는 규칙이다. 이 규칙을 무시하는것은 대부분 위험한 발상이다.

- **괜찮다고 임의로 판단한 경우,** 의도치 않은 곳에서 잠재적인 버그를 야기할 수 있다.
- **의존성 배열이 너무 긴 경우,** 함수 내부가 너무 길다는 말을 의미한다. 함수를 쪼개 가독성과 안정성을 확보해야한다.
- **마운트 시점에 한 번만 실행하고 싶은 경우,** 상태와 관계없이 한번만 실행해야 하는 것이 있다면 컴포넌트에 존재해야 할 이유가 없다. 적절한 위치로 옮겨서 사용하자

#### ESLint 버전 충돌

이런 문제로 인해 ESLint 공식문서에서는 ESLint를 peerDependencies로 설정해두라고 말하고 있다.

## 8.2 리액트 팀이 권장하는 리액트 테스트 라이브러리

백엔드와 테스트 방법론이 사뭇 다르다. 백엔드는 화이트박스 테스트를 주로 하며, 프론트엔드는 블랙박스 테스트를 주로 한다. 유저의 인터렉션을 최대한 예측해서 확인을 해야하며 단순 함수부터 사용자의 동작을 흉내내는 테스트 등 여러 테스트가 있다.

### 8.2.1. React Testing Library

Dom Testing Library를 기반으로 만들어졌다. 브라우저에서 실행시키지 않아도 Node에서 DOM을 불러오고 조작할 수 있다.

### 8.2.2. 자바스크립트 테스트의 기초

기본적인 테스트 방식은 아래와 같은 방식을 거친다.

1. 테스트할 함수나 모듈을 선정한다
2. 함수나 모듈이 반환하길 기대하는 값을 만든다.
3. 함수나 모듈의 실제 반환값을 적는다.
4. 3번의 기대에 따라 2번의 결과가 일치하는지 확인한다.
5. 기대값과 같으면 성공 다르면 실패를 반환한다.

이런 테스트 결과를 확인할 수 있게 도와주는 라이브러리를 `어설션(assertion)`이라 하며, 테스팅 프레임워크들은 이를 기반으로 테스트를 수행한다.

### 8.2.3 리액트 컴포넌트 테스트 코드 작성하기

리액트 컴포넌트 테스트는 다음과 같은 순서로 진행된다.

1. 컴포넌트를 렌더링한다.
2. 필요하다면 컴포넌트의 특정 액션을 수행한다.
3. 컴포넌트 렌더링과 2번의 액션을 통해 기대하는 결과 실제를 비교한다.

리액트 컴포넌트가하는 일반적인 시나리오는 특정한 무언가를 지난 HTML 요소가 있는지 여부다. 이를 확인하는 방법은 크게 아래와 같이 3가지 정도가 있다.

- **getBy,** 인수의 조건에 맞는 요소 반환.
- **findBy,** getBy와 유사하나 차이점은 Promise를 반환. 즉 비동기로 찾는다.
- **queryBy,** 인수 조건에 맞는 요소를 반환하고, 찾지 못하면 null 반환

#### 데이터셋

HTML의 특정 요소와 관련된 임의 정보를 추가할 수 있는 HTML 속성. `data-testid` 같은 속성을 추가하여 유용하게 사용할 수 있다.

#### 동적 컴포넌트

useState 등의 통해 상태변경도 같이 일어나는 컴포넌트의 경우이다.

- userEvent.type, 사용자가 타이핑을 하는 것을 흉내내는 메소드. fireEvent를 순차적으로 실행한다.

#### 비동기 컴포넌트

MSW를 사용해 해결해보자!

### 8.2.4 사용자 정의 훅 테스트하기

사용자 정의 훅도 동일하게 테스트 가능하다. 훅을 렌더링 하기 위해서는 `renderHook`을 사용해야 한다. initialProps를 지정하여 renderHook의 함수 초기값을 지정할 수 있다.

### 8.2.5 테스트를 작성하기에 앞서 고려해야할 점

테스트 커버리지는 만능이 아니다. 테스트 코드를 작성하기 전 가장 중요한 부분은 애플리케이션에서 가장 취약하거나 중요한 부분을 파악하는 것 이다. 가장 핵심인 부분부터 하나씩 작성해 나가는게 중요하다.

### 8.2.6 그 밖의 해볼만한 여러 가지 테스트

- 유닛테스트
- 통합 테스트
- E2E 테스트
E2E 테스트는 Cypress 같은 외부 라이브러리의 힘을 빌려야 한다.

### 8.2.7 정리

테스트가 이뤄야할 목표는 애플리케이션이 비즈니스 요구사항을 충족하는지 확인하는 것 하나이다.
Loading