[TDD] TDD란 무엇인가

Updated:

애플리케이션에 있어서 테스트의 의미

모든 애플리케이션은 출시를 하기전에 테스트 과정을 반드시 거친다. 그렇지 않은 애플리케이션이 있다면 뭐 그건,, 최악이다.. 테스트라는게 얼마나 중요한지는 굳이 설명하지 않아도 알 것이라 생각한다. 그렇다면 우리가 궁금한 것은 바로 테스트를 어떤 방식으로 하고 있느냐라고 할 수 있다.

우리는 애플리케이션을 개발하면서 테스트를 어떻게 진행하고 있을까? 어떤 사람은 한 기능을 구현한 후에 그 기능을 매번 테스트 할 것이고, 다른 어떤 사람은 모든 기능을 구현하고 나서 그 기능들 전체를 한번에 테스트 하는 사람도 있을 것이다. 어떤게 효율적인지는 현재 개발 중인 애플리케이션의 서비스, 개발 기간, 기능의 로직 복잡도에 따라 달라진다. 오늘은 좀 다른 테스트 방식에 대해 소개하고자 한다. TDD를 대해서.

TDD 란

TDD는 Test-Driven-Development의 약자를 가지며, 테스트 주도 개발을 뜻한다. 반복적으로 작은 단위의 테스트 코드를 작성하고 통과 시키는 과정을 반복하는 테스트 중심 개발 방식이다. 장기적인 개발 관점에서 봤을 때 애플리케이션이 정상적으로 작동되고 유지보수 되는 것을 보장한다.

더욱 간단히 말하자면 “테스트 코드를 먼저 작성하고, 그 테스트 코드가 통과할 수 있도록 프로덕션 코드를 작성해 나가는 개발 방식” 이라고 할 수 있다. 여기서 말하는 ‘프로덕션 코드’란 실제 애플리케이션을 구현하는데 사용되는 코드로서 테스트 코드와는 구분된다.

보통 무언가를 테스트 한다고 하면 개발을 하고 나서 테스트를 해왔던 것이 일반적이었지만, 그것을 뒤집어 버린 개발 방식인 것이다.

TDD 과정

TDD 는 총 세 과정이 존재하고 매 기능이 추가될 때마다 이를 반복한다.

TDD Process

  1. 특정 기능에 대해 실패하는 테스트 코드를 작성한다. 프로덕션 코드보다 테스트 코드가 먼저 작성되었기 때문에 반드시 실패할 수 밖에 없다.
  2. 이제 1번에서 작성했던 테스트 코드가 성공할 수 있도록 프로덕션 코드를 작성한다.
  3. 마지막으로 테스트 코드와 프로덕션 코드를 Refectoring 한다. 즉, 코드를 정돈하는 단계를 거친다.
  4. 기능이 추가되면 1번부터 반복한다.

TDD 테스트 코드 작성 방법론

TDD 에서도 마찬가지로 좋은 테스트 코드를 작성하기 위한 규칙들이 존재한다.

  • 첫 번째로, 실패하는 단위 테스트 코드를 작성한다. 아직 작성되지 않은 프로덕션 코드에 대해 테스트 코드를 먼저 작성하기 때문에 너무나도 당연하게 테스트는 실패하게 된다. 유의 해야 할 것은 이때 발생하는 “프로덕션 코드의 부재로 인해 발생하는 컴파일 에러 역시 실패하는 테스트코드의 결과로 포함된다” 라는 것이다.

  • 두 번째로, 새로운 단위 테스트 코드를 작성하기 전에 이전에 작성했던 모든 단위 테스트가 통과되어야만 한다. 그렇지 않고 하나라도 통과되지 않았다면 그건 TDD의 과정에 어긋나게 된다. 새로운 기능에 대한 테스트를 할 때마다 모든 테스트 케이스역시 테스트를 해야한다.

  • 세 번째로, 모든 테스트를 진행할 때 테스트의 속도가 빠르도록 코드를 작성해야 한다. 애플리케이션의 개발되면 점점 테스트를 해야할 규모가 커지기 때문에 이러한 테스트 속도를 줄여야할 필요가 있다.

  • 네 번재로, 코드 Refectoring을 진행 할때에 테스트 코드와 프로덕션 코드 모두 업데이트한다. 이 과정을 통해 애플리케이션 코드 전체가 유지보수 관점에서 더욱더 효율성을 가지게 된다.

  • 다섯 번째로, 모든 기능에 대한 프로덕션 코드 작성을 마치고 나서 테스트 코드를 작성하는 것이 아닌, 특정 기능에 대한 테스트 코드를 먼저 작성하고 프로덕션 코드를 작성하는 과정을 반복해야 한다. 이건 너무 많이 말했다,,

TDD 테스트 To-Do, Not To-Do

누군가가 그랬다 특정 이성의 마음에 들기 위해서는 그 이성이 좋아하는 것에 신경쓰는 것보다 싫어하는 것을 하지 않는 것이 더 중요하다고. 이 개념은 TDD에도 그대로 적용된다. 쓸데 없는 단위 테스트는 오히려 개발의 진행을 방해하기 때문이다. 위에서 대략적으로 TDD가 무엇인지는 알았는데 그럼 무엇을 테스트 해야하고 무엇을 테스트 하지 말아야 할까?

To-Do

TDD 에서는 직접 작성한 코드를 테스트한다. 직접 만든 클래스나 구조체의 메서드나 getter와 setter 같은 코드들을 테스트 하면 된다. 예를 들어, 특정 클래스의 프로퍼티 값이 특정 메서드를 실행하고 나서 결과값이 어떻게 변했는지 테스트를 할 수가 있다.

Not To-Do

  • Generated Code: generated code 에 대해서는 설명하기가 조금 모호한데 “본인이 직접 만든 코드가 아닌, 프로그램에 의해 자동 생성되는 코드”를 뜻한다. 대표적인 예가 getter와 setter라고 할 수 있는데 우리가 굳이 직접 만들어주지 않아도 Swift는 자체적으로 변수에 대해 getter와 setter를 만들어준다. 그렇기 때문에 “getter와 setter가 잘 호출이 되나?? 시험해보자” 이러한 테스트는 지양하도록 하자. 테스트를 해야한다면 getter와 setter의 내용이지 호출 여부가 아니기 때문!

  • 컴파일 에러: 컴파일러에 의해 잡히는 에러 이슈를 테스트하는 코드는 테스트 하지 않는다. 뭐좀 극단적이지만 swift 문법 테스트같은 것들,, 이러한 컴파일 에러는 XCode가 알아서 처리해주기 때문에 개발자가 직접 테스트 할 필요가 없다.

  • 프레임 워크: 프레임 워크에 대한 테스트도 하지 않는다. 프레임워크는 누가 개발했다? 다른 사람이 개발했다. 내가 개발하지 않았다. 그렇기 때문에 해당 프레임워크의 내부적인 동작에 대한 테스트 책임은 온전히 그 프레임워크를 개발한 사람에게 있다. 우리가 아니다. 예를 들어 UIKit의 특정 클래스를 테스트하지 말아야한다. 다만 UIKit의 클래스를 상속하는 custom 클래스는 테스트를 해야한다.

TDD를 사용해야 하는 상황

TDD는 개발기간이 최소 몇달이 예상되거나, 다수의 릴리즈를 가지거나, 복잡한 로직을 포함하고 있을 때 사용하는 것이 좋다. TDD는 초반에 많은 개발 비용이 발생하지만 개발이 장기적으로 진행될 경우, 새로운 기능을 추가할 때나, 이미 작성된 코드를 수정할 때 그리고 버그를 해결할 때에 있어서 TDD를 적용했을 때가 그렇지 않을때 보다 더 적은 비용이 든다.

Leave a comment