테스트주도개발 08

Updated:

테스트 주도개발 8장

8.1 TDD와 소프트웨어 디자인

8.1.1 TDD와 객체 지향 프로그래밍(OOP)

  • 안전한 부품
  • 재사용성
  • 모듈은 높은 응집도를 유지하고 낮은 결합도를 갖도록 만들어야 한다.

  • 예제1
public class MeasureCounter {
    public String getTotalMeasure(String name){
        Stock b = new Stock(name); // 객체 생성
        
        int firstCountRate = b.getFirstCountRate(); // 최초 비율
        int runningCount = b.getRunningCount()/2; // 러닝카운트
        int remainingCount = b.getRemainings(); // 남은 수량
        
        return name + ": " + (firstCountRate + runningCount + remainingCount);
    }
}
  • 위의 경우 TotalMeasure 구하기 위해 Stock 정보가 있어야 한다. 그런데 해당 메소드가 있는 MeasureCounter 클래스에는 Stock에 대한 정보가 없다. 따라서 내가 테스트하고자 하는 기능은 MeasureCounter클래스가 아닌 Stock클래스에서 해야 하는 기능이다.
  • 이것이 응집도를 높이고 결합도를 낮추는 것이다.
  • 예제 2
public class PublicItem {
    public int getDualCharge(Sender sender){
        int fare = 0; // 요금
        
        if ( this.item.getStore().getCustomer(sender.getName()).isVip() ){
        	fare = sender.getBox().getFare() * 0.8;
        } else {
        	fare = sender.getBox().getFare();
        }
        
        return fare;
    }
}
  • 위의 경우도 PublicItem에 존재해야하는 객체가 Item인지 customer인지 고민해야한다.

8.1.2 유연한 코드

  • 소프트웨어 변경이 쉬워지려면 코드가 유연해야 한다.
  • 현재 필요한 기능에 최대한 집중해야한다.
  • 시스템에 익숙하지 않은 사람이 새로운 요구사항 반영을 위해 소프트웨어에 변경을 가하는데 소요되는 시간

8.1.3 계약에 의한 설계

  • 로직의 선/후 조건 or 개발에 필요한 업무규칙 or 고객의 요구사항 등을 의미
  • 일반적으로 의도와 로직, 제한 조건이 명확히 분리될수록 좋은 프로그램에 가까워진다.
  • 의도는 보통 잘 작성된 이름에서 시작하고, 로직은 간결하게 작성하며, 제한조건은 로직과 분리해서 작성하는 것을 원칙으로 삼는다.

8.2 TDD 유의사항

8.2.1 테스트 케이스는 이름이 중요하다.

  • 일련의 번호는 좋지 않다.
  • 경우에 따라서 메소드에 한글도 좋다. 길어진다고 불편하거나 약어를 쓸 필요는 없다.
  • 의미만 전달할 줄 알면 된다.

8.2.2 더 이상 제대로 동작하지 않는 테스트 케이스는 제거한다.

8.2.3 TDD는 자동화된 테스트를 만드는 것이 최종 목표가 아니다

  • 자동화 테스트는 단순한 TDD의 부산물. 정상 여부 판단이 주 목적. 주와 부가 바뀌지 말자.

8.2.4 모든 상황에 대한 테스트 케이스를 만들 필요는 없다

8.2.5 여러 개의 실패하는 테스트 케이스를 한 번에 만들지 않는다

  • 하나의 실패하는 테스트만 유지. 실패 성공 후 다른 실패하는 케이스를 작성

8.2.6 하나의 테스트 케이스는 하나만 테스트하도록 작성한다

8.2.7 전통적인 테스트 기법을 배워두자

  • 각종 테스트 기법을 잘 알면 좀 더 효율적인 테스트 클래스 작성이 가능해진다

8.2.8 테스트 케이스는 최대한 고립시킨다

  • 아래의 경우들이 테스트에 들어가지 않도록 한다.

  • 테스트 케이스가 작성되어 있지 않는 다른 모듈
  • 데이터베이스 연동
  • 외부 시스템
  • 콘솔 출력
  • 네트워크

8.3 TDD와 리펙토링

  • 매우 중요하다.

8.4 TDD와 짝 프로그래밍

  • 팀원 간의 좀 더 많은 대화로 목표 시스템에 대한 이해 증가
  • 제품에 대한 공동설계와 공동소유
  • 개발에 효율을 높일 수 있는 작업 방식의 공유
  • 개발 스킬 향상

8.5 TDD와 심리학

8.6 TDD를 어렵게 만드는 요인

8.6.1 환경적 요인

8.6.2 산만한 아키텍쳐

  • TDD만 지나치게 강조하면 발생할 때가 있다. 적절한 레벨의 설계를 선행해야 한다.

8.6.3 의존성 전파로 인한 연쇄적인 테스트 실패들

  • 고립된 테스트 케이스를 만들어야 하나 경우에 따라 그럴 수 없는 경우

8.7 행위 주도 개발

  • TDD는 처음에 단위 메소드 기능에 집중한다.
  • 케이스 작성이 추가 되고 메소드 호출 단계가 상위로 갈수록 사용자 테스트에 가까워 진다.
  • 이러한 방식을 인사이드 아웃 방식이라고 한다.
  • 이럴 때 흔히 어디서 시작할 것인가, 어느 정도 작성하면 될 것인가 고민이 된다.
  • 때에 따라서 어떤 것은 꼭 해야하는가 어떤건 안해도 될까 고민이 된다.
  • 이런 문제를 좀 더 문맥적으로 해결할 수 있게 돕는 것이 행위 주도 개발이다.

8.7.1 BDD의 정의와 목표

  • 책임관계자의 관점에서 보는 애플리케이션 행위 중 가치 있는 기능부터 개발하는 방식
  • 프로젝트 참여 인원들의 협업을 증진시키는 것이 목표

8.7.2 BDD 특징

  • 사용자에 좀 더 가까운 고수준의 기능영역을 우선적으로 다룬다.
  • 무엇을 테스트 할 것인가에 초점을 맞추고 있다. 즉, 현재 시스템에 가장 먼저 구현해야 하는 기능이 무엇인가?를 말한다. 기존의 TDD와 다르게 사용자에게 가까운 부분에서 시작하므로 아웃사이드 인 방식이라 한다.
  • 테스트 메소드 작성에 집중할 수 있는 문장적인 템플릿을 제공한다.
  • Given(주어진 상황이나 조건), When(기능 수행), Then(예상 결과)가 기본 템플릿
  • 메소드 이름에 should 같은 목표 행위를 기술하기 위한 단어를 적절히 사용하면 더 분명해진다.

8.7.3 BDD 접근 전략

  • BDD와 TDD는 개발하려는 프로그램에 따라 적절하게 적용해라.
  • 개발자가 반드시 알고 견뎌야 하면 TDD
  • 고객 관점에서 이야기하거나 대상 시스템의 최종 형태를 파악하며 개발할 때는 BDD

8.7.4 BDD와 TDD

  • TDD는 예제에 의한 개발과 단위 테스트 케이스를 지향
  • BDD는 사용자 시나리오를 통해 사용자 테스트와 회귀 테스트를 지향 (둘다 자동화는 지향)

8.7.5 BDD 정리

  • BDD와 TDD는 사용하는 어휘와 목적이 조금 다를 뿐, 목표가 같다. 간결한 설계를 만들고, 소프트웨어를 만들기 위한 출발점을 제공한다는 것이다.

Tags:

Categories:

Updated: