본문 바로가기
독서/리팩터링

[리팩터링] 챕터04. 테스트 구축하기

by 공부하는개미 2022. 5. 24.

 

😀 책에서 기억하고 싶은 내용을 써보세요.

  • 리팩터링을 제대로 하려면 불가피하게 저지르는 실수를 잡아주는 견고한 테스트 스위트가 뒷받침돼야 한다.

4.1 자가 테스트 코드의 가치

  • 프로그래머는 대부분의 시간을 디버깅에 쓴다.
    • 버그 수정 자체는 금방 끝나지만 버그를 찾는 여정이 고통스럽다.
  • 자가 테스트 코드 자체뿐 아니라 테스트를 자주 수행하는 습관도 버그를 찾는 강력한 도구가 된다.
  • 테스트를 작성하기 가장 좋은 시점은 프로그래밍을 시작하기 전이다.
    • 테스트를 작성하다 보면 원하는 기능을 추가하기 위해 무엇이 필요한지 고민하게 된다.
    • 구현보다 인터페이스에 집중하게 된다는 장점도 있다(무조건 좋은 일이다.)
    • 코딩이 완료되는 시점을 정확하게 판달할 수 있다.
    • 테스트를 모두 통과한 시점이 바로 코드를 완성한 시점이다.
  • 리팩터링에는 테스트가 필요하다. 그러니 리팩터링하고 싶다면 테스트를 반드시 작성해야 한다.
  •  

4.3 첫 번째 테스트

describe('province', function() {
	if('shortfall', function() {
		const asia = new Province(sampleProvinceData()); // 1️⃣ 픽스처 설정
		assert.equal(asia.shortfall, 5);   // 2️⃣ 검증
	}
}
  • 모카 프레임워크를 사용해서 테스트 코드 작성
    • 1️⃣ 첫 번째 단계에서는 테스트에 필요한 데이터와 객체를 픽스처(fixture: 고정장치)를 설정한다. 이 예시에서는 샘플 지역 정보로부터 생성한 Province 객체를 픽스터로 설정했다.
    • 2️⃣두 번째 단계에서는 이 픽스처의 속성들을 검증하는데, 여기서는 주어진 초깃값에 기초하여 생산 부족분을 정확히 계산했는지 확인한다.
  • 실패해야 할 상황에서는 반드시 실패하게 만들자.
    • 수 많은 테스트를 실행했음에도 실패하는 게 없다면 테스트가 내 의도와는 다른 방식으로 코드를 다루는 건 아닌지 불안해진다. 그래서 각각의 테스트가 실패하는 모습을 최소한 한 번씩은 직접 확인해본다.
  • 자주 테스트하라. 작성 중인 코드는 최소한 몇 분 간격으로 테스트하고,
    적어도 하루에 한 번은 전체 테스트를 돌려보자.

 

4.4테스트 추가하기

  • 테스트는 위험 요인을 중심으로 작성해야 한다!
    • 테스트의 목적은 어디까지나 현재 혹은 향후에 발생하는 버그를 찾는 데 있다. 따라서 단순히 필드를 읽고 쓰기만 하는 접근자는 테스트할 필요가 없다. 이런 코드는 너무 단순해서 버그가 숨어들 가능성도 별로 없다.
  • 완벽하게 만드느라 테스트를 수행하지 못하느니, 불완전한 테스트라도 작성해 실행하는 게 낫다.
describe('province', function() {
	const asia = new Province(sampleProvinceData());  // 이렇게 하면 안 된다.
	if('shortfall', function() {
		expect(asia.shortfall).equal(5);
	});
	if('profit', function() {
		expect(asia.profit).equal(230);
	});
}
  • 주석에 적은 것처럼 나는(저자는) 절대로 이렇게 하지 않는다.
    • 일시적인 효과는 있게지만, 테스트 관련 버그 중 가장 지저분한 유형인 ‘테스트끼리 상호작용하게 하는 공유 픽스처’를 생성하는 원인이 된다.
    • 자바스크립트에서 const 키워드는 asia 객체의 ‘내용’이 아니라 asia를 가리키는 참조가 상수임을 뜻한다.
describe('province', function() {
	let asia;
	beforeEach(function() {
		expect(asia.shortfall).equal(5);
	});
	if('profit', function() {
		expect(asia.profit).equal(230);
	});
}
  • beforeEach 구문은 각각의 테스트 바로 전에 실행되어 asia를 초기화하기 때문에 모든 테스트가 자신만의 새로운 asia를 사용하게 된다.
  • 개별 테스트를 실행할 때마다 픽스처를 새로 만들면 모든 테스트를 독립적으로 구성할 수 있어서, 결과를 예측할 수 없어 골치를 썩는 사태를 예방할 수 있다.

 

4.6 경계 조건 검사하기

  • 문제가 생길 가능성이 있는 경계 조건을 생각해보고 그 부분을 집중적으로 테스트하자.
  • 어차피 모든 버그를 잡아낼 수는 없다고 생각하여 테스트를 작성하지 않는다면 대다수의 버그를 잡을 수 있는 기회를 날리는 셈이다.
  • 아무리 테스트해도 버그 없는 완벽한 프로그램을 만들 수는 없다는 말은 많이 들어봤을 것이다. 맞는 말이지만, 테스트가 프로그래밍 속도를 높여준다는 사실에는 변함이 없다.
  • 테스트가 모든 버그를 걸러주지는 못할지라도, 안심하고 리팩터링할 수 있는 보호막은 되어준다. 그리고 리팩터링을 하면서 프로그램을 더욱 깊이 이해하게 되어 더 많은 버그를 찾게 된다.

 

 

🤔 오늘 읽은 소감은? 떠오르는 생각을 가볍게 적어보세요.

  • 테스트 코드의 중요성은 명저라고 불리는 프로그래밍 책에서는 꼭 나오는 것 같습니다.
  • 테스트 코드를 직접 작성하면서 마음이 좀 더 안정되는 기분을 느꼈습니다.
    • 테스트를 통해 빠른 피드백을 얻고 검증을 할 수 있다.
  • Junit에서 @BeforeEach라는 어노테이션이 있는데 자바스크립트 테스트코드에도 비슷한게 있는 걸 보고 신기하다고 느꼈습니다.

 

 

🔎 궁금한 내용이 있거나, 잘 이해되지 않는 내용이 있다면 적어보세요.

  • 테스트에 회의적인 팀원을 만나면 어떻게 해야 할까?
  • 단위 테스트란?
    • 코드의 작은 영역만을 대상으로 빠르게 실행되도록 설계된 테스트다.
    • 단위 테스트는 자가 테스트 코드의 핵심이자, 자가 테스트 시스템은 대부분 단위 테스트가 차지한다.

 

 

반응형