1. TDD(Test Driven Development)
- 테스트 주도 개발이라고도 한다.
- 기능을 업그레이드 할때마다 다른 것도 테스트를 다시 해봐야한다.
- 이런 문제를 해결하기 위해 테스트 코드가 필요하다.(검증코드)
- 각 기능마다 테스트 코드가 필요하다 => 단점으로는 시간이 많이 걸린다. 왜냐하면, 기능 만들때 마다 각각의 테스트 코드를 만들어야 하기 때문이다.
- 오픈예정 : 기능이 모두 다 작동하는지 확인을 해봐야하기 때문에 기능을 다 뽑아도 된다. 만약 오픈을 하게 되면, 오픈을 알리는 동안에 개발자들은 추가기능을 업그레이드하고, 기존 기능에 대해서 테스트코드를 작성한다.
- 운영중 : 운영 중에는 테스트코드를 만들면서 테스트를 진행해야 한다. 그래서, 시간이 오래 걸린다.
- 결국은 업그레이드 하는 요소가 기존 기능에 영향을 끼칠수 있기 때문에 테스트코드가 필요하다.
2. 테스트 종류
- 단위테스트 : 버튼 클릭과 같은 개별 기능
- 통합테스트 : 여러기능 한꺼번에
- E2E테스트 : 접속해서 로그인하고 구매하는 등 시나리오가 있음(끝에서 끝까지 테스트) / end to end
3. 실제 테스트 코드 구현 & 방법(실습)
- 테스트 코드 구현 전 필요한 것들!
1. Jest
- new nest 33-01-test로 새로운 nest폴더를 만듬
- nest에 .git이 남아있기 때문에 rm -rf .git을 통해서 삭제!
- Test코드 파일 : xxx.spec.ts 이런식으로 파일을 만들어줘야 한다.
it('더하기 테스트', () => {
const a = 1;
const b = 2;
expect(a + b).toBe(3);
});
- 한개 테스트하기 // 위 예제 테스트를 실행해보면,
describe('나의 멋진 테스트 그룹', () => {
it('더하기 테스트', () => {
const a = 1;
const b = 2;
expect(a + b).toBe(3);
});
it('곱하기 테스트', () => {
const a = 1;
const b = 2;
expect(a * b).toBe(2);
});
});
- 근데 얼마나 디테일하게 만들어야 할지 고민이다... => 처음부터 빈틈없이 완벽하게 만들지 말고, 점점 크게 그리고 디테일 하게 만든다!
- 테스트에도 순서가 있다!!
- 처음부분은 it이 아니라 beforeEach를 써서 위 사진처럼 작성을 한다.
- decribe 부분이 하나의 API라고 보면 된다.
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
let appService: AppService;
beforeEach(() => {
appService = new AppService();
appController = new AppController(appService);
});
describe('getHello', () => {
it('이 테스트의 검증 결과는 Hello World를 리턴해야 함!!!', () => {
const result = appController.getHello();
expect(result).toBe('Hello World!');
});
});
});
- 밖에 appController를 만들어 놓음으로써 아무곳에서나 쓸 수 있다.
- Controller나 Service를 직접 만들어서 쓰는 방식
- Test를 import해서 직접 모듈을 불러와서 주입하는 방법도 있다.
- 실무에서도 이 방법을 제일 많이 쓴다고 한다.
- 원래 기본적으로 만들어진 app.controller.spec.ts와 같아졌다.
- 이번에는 원본 appService말고 가짜 서비스를 만들어서 넣어 볼거다.
- 첫번째는 하면 안된다! => 말이안된다..
- 두번째는 꽤 많이 쓰인다! => Test를 돌릴때마다 DB에 계속 접근해야 하기 때문에 시간이 너무 오래 걸린다.
- 세번째는 배열을 만들고, 거기에 push해서 넣는 방법이다. 이 방법이 가장 많이 쓰인다!
- 세번째 방법 하기!
- 주입하는 것을 바꾸는 것이지 그 뒤에 있는 소스코드를 바꾸는 것은 아니다!
- Mock이라는 가짜 서비스를 직접 만들어야 한다.
- Test할때만 Mock으로 바꿔서 Test를 한다.
import { Test } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
class MockAppService {
getHello() {
return 'Hello World!';
}
}
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const appModule = await Test.createTestingModule({
controllers: [AppController],
providers: [
{
provide: AppService,
useClass: MockAppService,
},
],
}).compile();
appController = appModule.get<AppController>(AppController);
});
describe('getHello', () => {
it('이 테스트의 검증 결과는 Hello World를 리턴해야 함!!!', () => {
const result = appController.getHello();
expect(result).toBe('Hello World!');
});
});
});
마무리
=> TDD,Jest를 사용해보면서 여기에는 왜 이 명령어를 써야하는지를 꼼꼼히 공부해봐야 할거 같다.