Blog

테스트 주도 iOS 애플리케이션 개발 2장 정리

January 28, 2014

테스트 주도 iOS 애플리케이션 개발 2장 정리

테스트 주도 개발용 기법

개발자는 코드를 테스트할 수 있고 개발 방향이 옳은 방향으로 가고 있는지 컴퓨터가 자동으로 테스트를 계속해서 실행하게 만들 수 있다. 이 장은 개발자가 효율을 향상시키려고 단위 테스트를 사용하는 기법을 설명한다.

첫 테스트

테스트 주도 개발의 배경이 되는 생각은 설계할 동안 작성 중인 코드가 무엇을 해야 할지를 생각하게 하는 것이다. 특정 문제를 해결하는 모듈이나 클래스를 작성해 앱에 넣으려고 하기보다는 앱이 가진 문제를 생각하고 해당 문제를 해결하려고 코드를 작성하라는 것이다. 더욱이 요구사항을 담은 테스트를 통과한 것을 보여주면 실제로 코드가 이런 문제를 해결한다고 발표할 수 있다. 실제로 테스트를 먼저 작성하는 것은 문제를 발견하는 데 도움이 될 수도 있다. 코드를 추가로 작성하지 않아도 통과할 수 있는 테스트를 작성한다면 해당 앱이 이미 테스트가 식별하려는 문제를 해결했거나 테스트 자체에 문제가 있는 것이다.

일반적인 테스트 주도 작업 접근법은 테스트를 하나 만들고 실행해서 실패하는지 확인한 후 이 테스트를 통과할 코드를 작성하는 것이다. 통과하면 다음 테스트를 작성하는 것을 반복한다. 이는 테스트 주도 개발의 사상에 익숙해지는 좋은 방법이다.

테스트를 사용해서 코드가 올바르게 동작하는지 볼 수도 있고 테스트는 디버거를 사용한 따라가기가 없어도 코드의 동작을 더 쉽게 이해할 수 있다. 사실 디버거를 사용하는 주요한 이유는 일부 유스 케이스가 동작하지 않는 것을 발견했지만 문제가 어디서 발생한 지 알 수 없을 때다. 단위 테스트는 애플리케이션의 코드를 독립적이고 세세한 부분으로 잘게 나누어 테스트해서 오류를 정확하게 찾아내기 쉽게 해서 문제를 추적하는 데 이미 도움을 줬을 것이다.

적색, 녹색, 리팩토링

적색 단계 : 필요하지만 아직 작성하지 않은 동작을 캡슐화하여 실패하는 테스트를 작성하는 과정

녹색 단계 : 실패하는 테스트를 통과하거나 방금 작성을 마친 테스트를 통과하는 코드를 작성하는 과정

리팩토링 단계 : 애플리케이션의 행동에 영향을 주지 않으면서 구현을 바꾸고 해당 애플리케이션을 정리하는 과정

테스트 주도 앱 설계

그래서 적어도 애플리케이션의 전체 구조를 폭넓게 생각해 테스트 주도 프로젝트를 하는 것이 가장 좋다. 구현할 클래스와 메소드의 목록을 전부 나열한 자세한 모델은 필요 없다. 작은 단위의 설계는 테스트에서 나온다. 필요한 것은 기능이 무엇인지와 해당 기능을 어떻게 함께 맞추어 갈 것인지다.

시스템 메타포(익스트림 프로그래밍), 도메인 모델(객체지향 프로그래밍)은 애플리케이션에서 사용자가 서비스를 사용해 객체에 무엇을 시도하려는지를 바라보는 관점이다.

이 정보를 사용해 앱의 동작뿐만 아니라 앱이 설계 기획에 따르고 있음을 점검하는 테스트를 기획할 수 있다.

리팩토링

  • 코드는 필요한 동작을 하지만 이 동작이 마음에 들지 않는 코드라면 리팩토링이 필요하다.
  • 더 이상 나빠 보이지 않거나 나쁜 냄새가 나지 않을 때 리팩토링을 그만 둔다.
  • 리팩토링 과정은 나쁜 코드를 나쁘지 않은 코드로 바꾼다.

다양한 상황에 적용할 수 있는 코드에 쓸 일반적인 청사진인 객체지향 설계 양식을 따른다면 코드는 읽기 좋고 이해하기 쉬워질 것이다. (코코아 디자인 패턴, GOF의 디자인 패턴)

리팩토링을 수행할 때 코드에 대한 특정 변환을 종종 이용한다. 코드를 더 깨끗하게 만드는 다양한 상황에서 적용할 수 있기 때문이다.

예를 들어 두 클래스가 동일한 메소드를 가진다면 공통의 조상 클래스를 만들고 해당 클래스 안에 메소드 구현을 할 수 있다. 많은 클래스에서 반드시 제공해야 하는 메소드가 있다면 프로토콜을 만들 수 있다.

YAGNI

몇 번 지나가면서 언급했던 테스트 주도 개발의 한 가지 특징은 장담할 만하다는 것이다. 앱 코드 중 필요한 것을 설명한 테스트를 작성하고 테스트를 통과하는 코드를 작성하기만 하면 필요로 하지 않는 코드를 작성할 필요가 없다.

이처럼 불필요한 추가적인 노력은 일반적으로 안에서부터 밖으로 애플리케이션을 작성할 때 발생한다. 테스트 주도 개발은 밖에서부터 안으로 애플리케이션을 만드는 것을 권장한다. (일반적인 처리를 하는 클래스를 작성하지 않게 만들어 준다.)

익스트림 프로그래밍 개발자는 불필요하며 추가적인 노력이 필요한 일반적인 프레임워크 클래스를 YAGNI(지금 당장 필요 없으면 앞으로를 위해 준비할 필요가 없다, Ya Ain’t Gonna Need It)라고 줄여서 부른다.

YAGNI하면 불필요한 코드 작성을 피하게 해서 시간을 아낄 수 있다. 기본적으로 사용하지 않을 코드를 작성하지 않는다.

테스트 주도 앱은 불필요한 코드가 전혀 없고 테스트하지 않은 코드도 없다.

코드 작성 전, 작성 중, 작성 후 테스트

테스트 주도 개발을 하려고 적색, 녹색, 리팩토링 접근 방식을 따른다면 코드를 작성하기 전에 테스트가 실패함을 증명하려고 테스트를 실행할 것이다. 이는 테스트를 해서 명세한 행동을 구현할 필요가 있다고 말한다. 코드를 만들면서 녹색 막대로 향하는 작업을 하는 동안에도 이외의 기능에 영향을 미치는지 확인하려고 테스트를 계속 수행할 것이다. 기능을 모두 구현한 이후 리팩토링 단계에서도 코드를 정리하는 작업이 부정적인 영향을 끼치지 않는지 확인하려고 테스트를 계속할 것이다. 이것은 소프트웨어를 모든 단계에서 테스트해야 한다고 1장에서 한 제안을 반영하는 작은 단위 방법이다.

개발 주기 동안 테스트를 자동으로 실행하게 해서 테스트하는 것을 잊는다 해도 알아서 테스트를 수행할 수 있게 하는 것은 정말 좋은 생각이다.

다른 중요한 방어벽은 제품의 배포 후보 버전을 준비할 때마다 테스트를 수행한다고 보장하는 것이다. 이 시점에서 테스트가 실패하면 해당 빌드를 테스터나 고객에게 전달할 이유가 없다. 뭔가 잘못됐고 잘못을 수정할 필요가 있다.

일반적으로 일하는 것보다 테스트하는 시간이 더 길다고 느껴지지 않는 한 가능할 때마다 자동으로 테스트하게 하는 것을 목표로 해야 한다. 테스트를 하면 다음에 해야 할 일과 진행 상황을 바로 피드백해서 알 수 있기 때문이다.