항해플러스 3기를 수료하면서 배웠던 내용인데 바쁘다 핑계로 정리를 안했더니 내용이 기억이 나지 않는다. 늦었지만 다시 복습을 하면서 TDD에 대해 공부했던 내용을 기록하려고 한다.
# objects
- TDD?
- unit Test 적용예시
## TDD?
TDD(Test Driven Development)는 테스트 주도 개발이다. 쉽게 이야기를 하면 Test Code를 먼저 작성하고 Code를 수정하는 방식이다.
TDD 개발론
하단에 그림을 보면 아래와 같이 표현이 된다.
- Red: test fail
- Green: test success
- Purple: refactoring
TDD 개발 방법론을 선택했다면 다음과 같은 순서로 진행이 된다.
- Red > Green > Purple
Red: Test 코드를 작성하고 작성한 코드는 실패를 한다(비즈니스 로직 구현전)
Green: 작성한 Test 코드를 통과될 수 있도록 비즈니스 로직을 구현하고 Test 통과를 시킨다
Purple: 작성한 코드를 재사용성을 위해 캡슐화, 중복제거, 의존성 제거로 리팩토링 한다
Red: 리팩토링한 소스가 테스트 실패한다
... 반복...

TDD 장점
- QA 이전에 기능이 정상 동작 확인 가능(QA에서 검증하는데 많은 시간과 비용이 발생)
- 비지니스 코드 이해력 높아짐
- 이슈 예측 및 빠른 디버깅 가능(유지보수 용이)
- 코드 품질 향상(코드 의존성을 낮춤)
- 서비스(레거시) 안정화
- 레거시에 새로운 코드를 작성해도 이전에 테스트 코드를 통해 레거시 소스에 문제 없는 판단 가능
TDD 단점
- 코드 작성 시간이 길어짐
- e2e 테스트 할때 비용이 올라감
- e2e 진행 할수록 테스트 속도 저하
TDD When ?
- 요구사항이 명확할 때
- 비지니스 로직 검증이 필요할 때
TDD Priciple
- Fast: 의존성 낮추기 (mock 사용으로 의존성 낮추기)
- Isolated: 최소한의 유닛으로 검증하기
- Repeatable: 실행할 때마다 동일한 결과를 유지
- Self Validatation: 스스로 결과를 검증하기 (기존에 코드에 영향을 주는지 확인)
- Timely: 시기적절하게 테스트 코드 작성
TDD 범위
- 모든 요구 사항이 정상 동작 하는지 확인
- Boundary conditions
- 모든 코너 케이스에 대해 테스트를 하기 (1명, 100명..bulk test)
- ex) 잘못된 포맷의 input, null, 특수문자, 잘못된 이메일
- Inverse relationship
- 역관계를 적용해서 결과값을 확인
- 일관성 유지 (어떤값을 생성 후 삭제한 경우와 값을 생성하기 전과 동일)
- Cross check
- 다른 수단을 이용해서 결과값이 맞는지 확인
- 재사용 했을 때 문제 없는지 확인
- Error conditions
- Error 처리 확인
- Performance characteristics
- 성능 확인은 테스트를 통해 정확한 수치로 확인
- 기본적으로 측정하는 방법(Test code 작동 시간 측정)
TDD conditions
- Conformance
- 특정 포맷을 준수
- 전화번호, 이메일, 아이디, 파일확장자...
- Ordering
- 순서 조건 확인하기
- Range
- 숫자의 범위(제한된 범위보다 작거나 큰 경우)
- ex) 콘서트 예약시
- Reference
- 외부 의존성 유무, 특정한 조건 (~일때, 어떤 특정한 상황/상태일 때 확인)
- Existence
- 값이 존재 하지 않을때 어떻게 존재? (null, undefiend)
- Cardinality
- 0 1 N 법칙에 따라 검증
- 하나도 없을 때, 하나만 있을때, 여러개가 있을 때
- Time
- 상대, 절대, 동시의 일들
- 순서가 맞지 않은 경우, 소비한 시간, 지역 시간
## unit Test 적용예시
TDD Structure
- beforeEach, beforeAll: Test 실행전 실행됨
- Test
- Arrange 준비: 실행할 부분 정의 및 검증 데이터 정의
- Act 실행: 비즈니스 로직 실행
- Assert 검증: 로직 실행 후 예상한 결과가 나오는지 확인
- afterEach, afterAll: Test 실행후 실행됨
import { Test, TestingModule } from '@nestjs/testing';
import { TweetsService } from './tweets.service';
describe('TweetsService', () => {
let service: TweetsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [TweetsService],
}).compile();
service = module.get<TweetsService>(TweetsService);
});
describe('createTweet', () => {
it('should create tweet', () => {
// Arrange(준비)
// tweets을 생성할 text 선정
service.tweets = [];
const payload = 'First My tweet!';
// Act(실행)
// tweet 생성
const tweet = service.createTweet(payload);
// Assert(검증)
// tweet를 생성하고 return 값 검증
// tweet을 한개 생성 했기 때문에 결과 검증
expect(tweet).toBe(payload);
expect(service.tweets).toHaveLength(1);
});
});
});
*참조
- 항해플러스 3기
- 드림코딩 아카데미
### 마치며
- 예전에 공부했던 TDD 개념에 대해서 다시 한번 정리하면서 그때 못했던 부분과 놓친부분을 다시 상기되었다.
- 더욱더 안정화를 위해서 더욱더 코드 퀄리티를 높이기 위해서 개발자로써 더 발전을 위해서 Test로 코드 퀄리티를 높이고 싶다.
- Server에 관련된 Test 대해서만 공부를 했었는데 개발자 모임에서 Front Test 코드에서도 검증할 부분들이 있다고 해서 작성을 한다는 분이 계셨다. Server 뿐만아니라 Front Test 공부 해야겠다.
'Coding > server' 카테고리의 다른 글
Server - abortController is not defined error (0) | 2022.03.28 |
---|---|
Server - REMOTE HOST IDENTIFICATION HAS CHANGED error (0) | 2022.01.18 |
Server - mediasoup 설치 error (0) | 2022.01.05 |
Server - login-server-tutorial (0) | 2021.12.05 |