마스터클래스 질의응답 모음

테스트
- 단위테스트
- 인풋에 대한 아웃풋을 검증하는 것
- A라는 함수를 검증한다
- B라는 함수를 의존할 수 있고
- C라는 함수도 의존할 수 있고
- D라는 함수도 의존할 수 있고
- …. 대략 한 20개의 함수를 의존하는 코드가 있다.
- 어떻게 해야 좋을까?
- mock을 한다
- 무지성으로 mock을 하면
- B라는 함수의 중요한 로직이 변경
- 그런데 B를 목킹한 A의 테스트는 이 부분을 놓쳐서 그냥 통과를 해버리네?
- 어…?
- A라는 함수가 Redux에 의존하고 있음
- Redux를 구성해서 주입 X
- input에 대한 output을 예상해서 주입
- 1이라는 input에 대해 10이라는 output이 나와야 하는 상황
- 중요한점 - mock의 경계선을 잘 생각하자.
- 통합테스트
- A라는 함수를 검증한다.
- A가 의존하고 있는 함수들을 다 실행시켜서 A를 검증한다.
- A라는 함수가 Redux에 의존하고 있음
- Redux를 구성해서 주입
- 인수테스트
- end to end
- 브라우저 환경에서 사용자의 동작을 테스트해보는 것
- 비주얼테스트
- 차트를 그렸음 → 저장
- 다른 input에 대해서 차트를 그리고 → 비교
- 차트 → 브라우저마다, 운영체제마다 다를 수 있음
- API 데이터에 대해 렌더링을 해보고 캡쳐
- 코드를 수정
- 다시 렌더링 후 캡쳐
- 비교
- 어디가 달라졌는지 확인
- 5% 이내의 차이만 있으면 통과
- 테스트는 어떤 상황에 필요할까?
리팩토링
- 리팩토링의 의미는?
- 커밋로그
- feat: xxx
- fix: xxx
- refactor: xxx
- 기능은 그대로
- 코드는 다르게
- 코드를 수정했는데, 정상적으로 작동하는지 검증할 수 있나?
- 안심하고 수정할 수 있나?
- 그게 가능한가?
- 리팩토링을 할 때 필요한게 바로 테스트 코드
- 기능 추가를 했는데, 어… 사이드 이펙트가 있네?
- → 테스트 코드가 필요하다
- test: xxx
- 신입이 우리 팀에 들어왔네
- 코드를 막 수정했네
- 어…? 이거… 배포해도돼?
- 테스트코드가 있다면?
좋은 코드임을 증명하는 방법
- 좋은 코드라는 것을 어떻게 알 수 있을까?
- 테스트가 불가능한 코드는 좋은 코드가 아니다
- 이유?
- A라는 기능에 대해서만 테스트를 하고 싶은데
- 어쩔 수 없이 B라는 기능까지 같이 테스트를 해야 되네?
- 문제가 있는게 아닐까?
- A가 꼭 B를 의존해야 하는걸까?
- 코드를 분리할 수 있지 않을까?
- A가 B를 꼭 의존해야만 한다면,
- B가 아니라
- B의 interface를 의존하게 하면 어떨까?
- DB Layer
- Service Layer
- 보통 DB가 꼭 필요함
- DB를 사용하는 어떤 코드 혹은 함수 (Repository)를 의존하게 한다면 꼭 DB를 의존하지 않아도 테스트할 수 있지 않을까?
- 꼭 DB를 의존한 형태로 테스트를 해야 되는 경우도 있을 것 같은데?
- 인수테스트
- 통합테스트
- 단위테스트를 해보자
- 의존 관계가 명확해진다.
- 꼭 필요하지 않은 의존도를 찾아낼 수 있겠네요
준일님 혹시 쉬는시간이 끝나고 답변을 부탁드려도 될까요? 아까 함수를 작게 쪼개는거에서 반복문 2개를 collectRows, collectRow 로 쪼개면 collectRows 는 collectRow 를 의존하게 되는 건 아닌가요? 만약 그렇다면 단위 테스트 하기가 더 까다로워지는건 아닌지 궁금합니다.
→ collectRows의 역할을 명시했다.
예시
- DOM Diff 알고리즘 만들기
- 텍스트(문자열)일 때
- 태그일 때
- 속성이 없을 때
- 속성의 개수가 다를 때
- 속성은 똑같은데 값이 다를 때
- …
- 파서
- JSON 파서
- …
- HTML 파서
- …
- CSS 파서
- …
- 프로그래밍 언어를 만든다고 치면?
- 리액트를 만든다고 치면?
- 결제모듈을 만든다고 치면?
- 할인율
- 청소년할인
- 성인할인
- 생일할인
- 이벤트(행사)
- 쿠폰
- 프론트엔드에서는?
- 비지니스 로직이라고 할만한 것들
- Custom Hook
- 컴포넌트에서 Hook을 떼어내고
- Hook의 로직을 테스트하자
테스트가 불필요한 상황
- 반대로 어떤 상황에는 테스트가 필요하지 않을까?
- 비지니스 로직이라고 할만한 것들
- Custom Hook
- 컴포넌트에서 Hook을 떼어내고
- Hook의 로직을 테스트하자
- 그러면 왜 컴포넌트는 테스트하지 않는거죠?
- 보통은 컴포넌트를 테스트 하는 경우는 거의 없음
- 너무 브라우저에 종속적이라서
- 컴포넌트 자체에 대해서 단위테스트를 하는게 의미가 있을까?
- https://www.youtube.com/watch?v=L1dtkLeIz-M
- 브라우저를 키지 않고
- IDE에서만 개발을 하겠다.
- 검증을 하겠다.
- 대신에 e2e 테스트를 하자
- cypress
TDD
- 테스트 주도 개발
- 테스트 코드를 먼저 작성하고, 실행 코드를 작성한다
- input에 대한 output을 미리 정의하는 것
- 스펙을 미리 정의해놓고
- 정의된 스펙대로 작성하는 것
- 함수의 인터페이스를 미리 정의하고
- 해당 함수에 대한 테스트코드를 작성하고
- 실제 구현코드를 작성하고
- A라는 입력에 대해 B라는 결과가 나와야 해
- 아직 명확하게 스펙이 정의되지 않는 상황
- 작성하다보면 갑자기 분리해야되는 부분이 생긴다거나
- 예측할 수 없는 경우가 많음
- → 테스트만 작성하다가 한 세월 가게 됨
- → 이렇게 까지 해야하나?
- 개인적으로 선호하진 않음
- 순서가 어찌되었든 테스트 코드 자체는 필요하다고 생각함
- 테스트 코드를 먼저 작성하진 않더라도
- 테스트코드가 필요하긴 하다
실습
- DOM Diff 알고리즘 만들기