title | date | author | category |
---|---|---|---|
JS TDD 개론 |
2020-12-03 11:00:00 -0800 |
wooooooood |
S2_Round2 |
테스트 케이스 생성→테스트→개발
의 짧은 개발 사이클을 반복적으로 수행하며 소프트웨어를 개발하는 프로세스.
Red-Green Refactor 라고도 한다.
- 테스트 케이스 작성
- 테스트 케이스를 통과하기 위한 최소한의 코드 작성
- 표준에 맞도록 리팩토링
Uncle Bob describes TDD with three rules:
- You are not allowed to write any production code unless it is to make a failing unit test pass.
- You are not allowed to write any more of a unit test than is sufficient to fail; and compilation failures are failures.
- You are not allowed to write any more production code than is sufficient to pass the one failing unit test.
- 설계 수정 시간 단축
- 디버깅 및 버그 수정 시간 단축
- 문제 발생 시 모듈별 테스트를 통해 문제 지점을 빠르게 파악 가능
- Production 레벨에서 버그를 수정하는 것은 Software development lifecycle (SDLC)에서 버그를 수정하는 것보다 훨씬 큰 비용과 시간을 소모
- Refactoring을 통해 Clean code를 유지
- 객체지향적인 코드 개발
- 세부 비즈니스 로직을 객체 내부로 숨겨 변경에 대응
- 유지보수 및 재사용에 용이
- 테스트 코드를 작성, 유지하기 위한 비용과 시간
- Mock객체를 생성하여 테스트
- 변경할 수 없는 객체, 프레임워크, 외부 라이브러리는 Mock하지 않는다
- ex.
Jest
에서 기본적으로 제공하는 mock functions
const myMockFunc = jest.fn().mockName("myMockFunc"); const myExampleModule = jest.mock("./exampleModule");
- Private객체의 테스트는?
- Public 객체에서 커버되는 경우 테스트하지 않는다.
- 리팩토링 고려. 해당 객체가 불필요한 책임을 가졌을 수 있다.
- 접근 제한을 Public으로 변경 후
@VisibleForTesting
추가
- 하나의 테스트에는 하나의 기능만 테스트한다
- 대상 코드의 의도 표현
- 데이터가 아닌 행위를 테스트한다
given-when-then
- 테스트하기 어려운 코드가 있다면 어떻게 하면 테스트할 수 있을까 가 아닌, 왜 테스트하기 어려울까를 고민
- Unit Testing: 가장 작은 단위 테스트(함수)
- Integration Testing: 시스템 모델링에서 실제 기능, 퍼포먼스, 의존성, DB 데이터 등을 테스트
- UI Testing (E2E): 사용자 관점 테스트(UI)
- 가장 작은 단위
- 단위 테스트이므로 다른 Unit과 의존성이 있어서는 안된다.
- 툴은 Mocha, Jasmine, Chai, Jest, Tape, Enzyme, Karma, Selenium, phantomjs 등 다양하며, 조합해서 사용할 수 있다.
npm init -y
으로 package.json을 생성한다.npm i -D jest
로 development 모드로 jest를 실행한다.- package.json의
test
를 수정한다. (test를 입력했을 때 jest를 실행하겠다는 의미)
"scripts": {
"test": "jest"
},
- 테스트를 진행할 파일
unit.test.js
를 생성한다..test.js
suffix를 사용해야 한다.
const add = (a, b) => {
return 1;
};
test('solution', () => {
expect(add(1, 1)).toBe(2);
});
- 영어 문법과 비슷: expect ~ toBe (보통 value) / expect ~ toEqual (array 등의 object)
- 테스트
npm test ./unit.test.js
결과는 반드시 실패한다. (Red)
- 성공하는 테스트 코드를 작성한다. (Green)
const add = (a, b) => {
const num1 = a;
const num2 = b;
return num1 + num2;
};
test('solution', () => {
expect(add(1, 1)).toBe(2);
});
- 성공 확인 후 리팩토링한다. (Refactor)
const add = (a, b) => {
return a+b;
};
test('solution', () => {
expect(add(1, 1)).toBe(2);
});
- 앞서 unit테스트한 각각의 module들이 통합되었을 때 올바르게 동작하는지 확인하기 위함
- 주요 목적은 module들 간의 인터페이스 동작 테스트
- db, platform, environment등이 포함되어 테스트되므로 복잡해질 수 있음
- Unit test 방법과 거의 동일하며, 여기에서 샘플 코드 일부를 가져왔다.
import { calculateTopEmployee } from './top-employee-provider';
import { get } from './api-wrapper';
jest.mock('./api-wrapper');
test('returns the top-performing employee', async () => {
mockApiResponse('/employees', [
{name: 'foo', numOfSales: 1 },
{name: 'bar', numOfSales: 2 }
]);
const topEmployee = await calculateTopEmployee();
expect(topEmployee).toEqual({ name: 'bar', numOfSales: 2 });
});
function mockApiResponse(endpoint, payload) {
const successfulPromise = new Promise(resolve => process.nextTick(() => resolve(payload)));
get.mockImplementationOnce(e => e === endpoint ? successfulPromise : Promise.reject());
}
- 사용자 입장 (환경 Latency, 관점 Workflow 등)에서의 테스트를 통해 사용자 경험 증대
- Web, App 등에서의 시나리오, 기능 확인
- 가장 확실하고 가장 필요한 테스트
- 여기에 자세한 예제가 나와있어 일부 사진과 기능만을 가져왔다.
Cypress
는 다양한 helper를 지원하여 사용자 action에 따른 테스트가 가능하다.- 현재는 Chrome과 Electron만 지원한다.
- Visit
describe('My First Test', function() {
it('Visits page', function() {
cy.visit('https://example.cypress.io')
})
})
- Interact
cy.contains('type').click()
- Debug
- https://m.blog.naver.com/PostView.nhn?blogId=suresofttech&logNo=221569611618&proxyReferer=https:%2F%2Fwww.google.com%2F
- https://medium.com/hbsmith/e2e-test-알아보기-3c524862469d
- https://velog.io/@rosewwross/unit-test
- https://www.slideshare.net/koreakihoon/tdd-112099012
- https://docs.reactioncommerce.com/docs/testing-reaction
- https://www.softwaretestinghelp.com/what-is-integration-testing/
- https://gist.github.com/cowchimp/0158efe57df3b845927e450fc2b87eeb
- https://softchris.github.io/pages/cypress.html