즉, 테스트 코드 먼저 작성 후 최대한 빠르게 테스트를 통과할 정도로만 구현 코드 작성하고 리팩토링
하지만 이렇게 나오는 실제 코드와 맞먹을 정도의 방대한 테스트 코드는 관리 문제를 유발한다.
지저분한 테스트 코드를 만드는 것은 테스트 코드를 만들지 않는 것만 못하다.
테스트 코드는 실제 코드 못지 않게 깨끗하게 짜야 한다.
깨끗한 테스트 코드를 만들려면 ? 가독성이 무엇보다 중요하다.
실제 코드보다 더 중요하다고 할 정도로 중요하다.
public void testGetPageHierarchyAsXml() throws Exception {
makePages("PageOne", "PageOne.ChildOne", "PageTwo");
submitRequest("root", "type:pages");
assertResponseIsXML();
assertResponseContains(
"<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>"
);
}
public void testSymbolicLinksAreNotInXmlPageHierarchy() throws Exception {
WikiPage page = makePage("PageOne");
makePages("PageOne.ChildOne", "PageTwo");
addLinkTo(page, "PageTwo", "SymPage");
submitRequest("root", "type:pages");
assertResponseIsXML();
assertResponseContains(
"<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>"
);
assertResponseDoesNotContain("SymPage");
}
public void testGetDataAsXml() throws Exception {
makePageWithContent("TestPageOne", "test page");
submitRequest("TestPageOne", "type:data");
assertResponseIsXML();
assertResponseContains("test page", "<Test");
}
BUILD-OPERATE-CHECK 패턴
첫 부분은 테스트 자료를 만든다.
두 번째 부분은 테스트 자료를 조작한다
세 번째 부분은 조작한 결과가 올바른지 확인한다.
테스트 코드는 잡다하고 세세한 코드가 없어야 하고 진짜 필요한 자료 유형과 함수만 사용해야 한다.
(== 가독성이 좋아야 한다)
@Test
public void turnOnLoTempAlarmAtThreashold() throws Exception {
hw.setTemp(WAY_TOO_COLD);
controller.tic();
assertTrue(hw.heaterState());
assertTrue(hw.blowerState());
assertFalse(hw.coolerState());
assertFalse(hw.hiTempAlarm());
assertTrue(hw.loTempAlarm());
}
@Test
public void turnOnLoTempAlarmAtThreshold() throws Exception {
wayTooCold();
assertEquals("HBchL", hw.getState());
}
이를 응용해서 아래와 같이 테스트 코드를 추가할 수 있다.
@Test
public void turnOnCoolerAndBlowerIfTooHot() throws Exception {
tooHot();
assertEquals("hBChl", hw.getState());
}
@Test
public void turnOnHeaterAndBlowerIfTooCold() throws Exception {
tooCold();
assertEquals("HBchl", hw.getState());
}
@Test
public void turnOnHiTempAlarmAtThreshold() throws Exception {
wayTooHot();
assertEquals("hBCHl", hw.getState());
}
@Test
public void turnOnLoTempAlarmAtThreshold() throws Exception {
wayTooCold();
assertEquals("HBchL", hw.getState());
}
이럴 때 주석이 필요하지 않나 싶습니다.
아래의 예제는 각 절에 assert 문이 여럿이라는 사실이 문제가 아니다.
하나의 테스트 함수에서 여러 개념을 테스트한다는 사실이 문제다.
독자적인 테스트로 쪼개야 마땅하다.
public void testAddMonths() {
SerialDate d1 = SerialDate.createInstance(31, 5, 2004);
SerialDate d2 = SerialDate.addMonths(1, d1);
assertEquals(30, d2.getDayOfMonth());
assertEquals(6, d2.getMonth());
assertEquals(2004, d2.getYYYY());
SerialDate d3 = SerialDate.addMonths(2, d1);
assertEquals(31, d3.getDayOfMonth());
assertEquals(7, d3.getMonth());
assertEquals(2004, d3.getYYYY());
SerialDate d4 = SerialDate.addMonths(1, SerialDate.addMonths(1, d1));
assertEquals(30, d4.getDayOfMonth());
assertEquals(7, d4.getMonth());
assertEquals(2004, d4.getYYYY());
}
작명이 좋진 않지만..
testAddMonthOfEndDay30, testAddMonthOfEndDay31 등이 될 수 있을 것 같네요.
그러므로 가장 좋은 규칙은 아래와 같다.
깨끗한 테스트는 다음 다섯 가지 규칙을 따른다.
깨끗한 테스트 코드라는 주제는 책 한권을 할애해도 모자랄 주제인 만큼 실제 코드만큼이나 중요하다.
테스트 코드가 방치되어 망가지면 실제 코드도 망가지므로 테스트 코드를 깨끗하게 유지해야 한다.