코드를 테스트 하는 테스트코드는 없었던 개념이였지만, 애자일과 TDD의 영향으로 많은 개발자들이 자동화된 유닛테스트를 만들고 있다.

The Three Laws of TDD

첫째 법칙: 실패하는 단위 테스트를 작성할 때까지 실제 코드를 작성하지 않는다.

둘째 법칙: 컴파일은 실패하지 않으면서 실행이 실패하는 정도로만 단위 테스트를 작성한다.

셋째 법칙: 현재 실패하는 테스트를 통과할 정도로만 실제 코드를 작성한다.

위 법칙을 따르면 엄청난 양의 테스트 코드가 등장한다. 사실상 모든 코드를 테스트 하는수준

깨끗한 테스트 코드 유지하기

테스트 코드를 막짜선 안된다, 사실상 관리가 어려워서 폐기하는 코드가 나중에는 등장할것. 테스트 코드를 짜는 노력이 허사가 되지 않게 실제 코드 못지 않게 깨끗하게 짜야 한다. 코드에 유연성, 유지보수성, 재사용성을 제공하는 버팀목이 단위 테스트이다. 테스트코드가 있으면 변경에 대한 공포도 줄어들고 유연성도 증가한다. 테스트 코드가 지저분하면 실제 코드도 망가진다

깨끗한 테스트 코드

깨끗한 코드를 만드려면 가독성 이 필요하다

BUILD-OPERATE-CHECK 패턴 → 테스트 자료 만들기, 자료 조작, 결과 확인

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");
}

도메인에 특화된 테스트 언어

시스템 조작 API를 사용하기보단 테스트를 위한 함수와 유틸리티를 이용하면 보다 간결한 테스트 코드를 작성할수 있게된다.

이중 표준

테스트 API에 적용하는 표준은 실제 코드에 들어가는 표준과는 다를수 있다. 실제 코드만큼 효율적인 필요는 없고 환경도 판이하게 다르기 때문이다.

@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()); 
}

테스트 당 assert 하나

public void testGetPageHierarchyAsXml() throws Exception { 
  givenPages("PageOne", "PageOne.ChildOne", "PageTwo");

  whenRequestIsIssued("root", "type:pages");

  thenResponseShouldBeXML(); 
}

public void testGetPageHierarchyHasRightTags() throws Exception { 
  givenPages("PageOne", "PageOne.ChildOne", "PageTwo");

  whenRequestIsIssued("root", "type:pages");

  thenResponseShouldContain(
    "<name>PageOne</name>", "<name>PageTwo</name>", "<name>ChildOne</name>"
  ); 
}