테스트 우선 프로그래밍의 단점은 무엇입니까?


47

요즘 모든 분노입니다. "모두"가 권장합니다. 그 자체로 나를 의심하게 만듭니다.

테스트 우선 (테스트 중심) 개발을 수행 할 때 어떤 단점이 있습니까? 나는 지식이 풍부한 실무자들의 개인적인 경험을 찾고 있습니다. 인터넷의 다른 곳에서 백 명의 지망생의 가설적인 생각을 읽을 수 있습니다.

나는 TDD를 싫어하기 때문에 묻지 않고 소프트웨어 개발 프로세스를 개선하는 것이 나의 일이기 때문에 사람들이 직면 한 문제에 대해 더 많이 배울수록 프로세스를 개선 할 가능성이 높아집니다.

답변:


41

몇 가지가 있지만 장점 은 단점보다 훨씬 큽니다.

가파른 학습 곡선이 있습니다.

많은 개발자들은 처음부터 테스트 우선 프로그래밍을 효율적으로 수행 할 수있을 것으로 기대합니다. 불행히도 이전과 같은 속도로 경험과 프로그램을 얻는 데 많은 시간이 걸립니다. 당신은 그것을 둘러 볼 수 없습니다.

더 구체적으로 말하면, 잘못되기가 매우 쉽습니다. 당신은 아주 좋은 의도로 아주 쉽게 잘못된 테스트를 유지하거나 테스트하기 어려운 많은 테스트를 작성할 수 있습니다. 여기에 예를 제시하기는 어렵습니다. 이러한 종류의 문제는 단순히 해결하는 데 경험이 필요합니다. 우려 사항을 분리하고 테스트 할 수 있도록 디자인해야합니다. 여기서 가장 좋은 조언은 TDD를 잘 아는 사람과 쌍으로 프로그래밍하는 것입니다.

더 많은 코드를 미리 작성하십시오.

테스트 우선은 테스트를 건너 뛸 수 없다는 것을 의미하며 더 많은 코드를 미리 작성해야합니다. 이것은 더 많은 시간을 의미합니다. 다시, 당신은 그것을 둘러 볼 수 없습니다. 유지 관리, 확장 및 버그가 적은 코드로 보상을받을 수 있지만 시간이 걸립니다.

관리자에게 힘든 판매가 될 수 있습니다.

소프트웨어 관리자는 일반적으로 타임 라인에만 관심이 있습니다. 테스트 우선 프로그래밍으로 전환하고 기능 대신 기능을 완료하는 데 갑자기 2 주가 걸리면 마음에 들지 않습니다. 이것은 확실히 싸울만한 가치가있는 전투이며 많은 관리자들이이를 얻을 수있을만큼 깨달았습니다.

동료 개발자에게 힘든 판매가 될 수 있습니다.

가파른 학습 곡선이 있기 때문에 모든 개발자가 테스트 우선 프로그래밍을 좋아하는 것은 아닙니다. 사실, 나는 대부분의 개발자들이 처음에는 그것을 좋아하지 않는다고 생각합니다 . 페어 프로그래밍과 같은 작업을 수행하여 속도를 높이는 데 도움이 될 수 있지만 판매가 어려울 수 있습니다.

결국, 장점은 단점보다 중요하지만 단점을 무시해도 도움이되지 않습니다. 당신이 처음부터 올바르게 다루고있는 것을 아는 것은 전부는 아니지만 단점의 일부를 협상하는 데 도움이됩니다.


이것들은 좋은 답변이지만 # 1에 대해 더 구체적 일 수 있습니까? 특히 프로그래밍 속도를 어떻게 회복 할 수 있었는지에 대해 관심이 있습니다. TDD를 언제 시작했는지 알지 못했습니까?
Alex Feinman

설명을 추가하기 위해 업데이트
Jaco Pretorius

7
지금 테스트를 수행하는 경우 개발에 소요 된 시간이 크게 바뀌지 않아야합니다. 단위 테스트를 작성하고 유지하는 데 시간이 걸리기 때문에 시간이 오래 걸리는 것 같습니다.
ChrisF

1
@JeffO는 "나는 미니 밴을 쓸거야!" 코딩 학교?
Alex Feinman

1
@tvanfosson-테스트 시작과 TDD 두 가지를 한 번에 변경하려고하기 때문에 문제가 될 수 있습니다. 또한 시간 추정치를 상당히 정확하게 추가하므로 관리자와 고객은 전체 시간이 실제로 알려져 있고 한 번도 줄어들지 않고 선불 증가 만 볼 수 있습니다. 그들이 몇 가지 테스트를하고 있다면이 증가는 적을 것입니다.
ChrisF

35

Test-first는 다음과 같은 코드를 작성한다고 가정합니다.

  • 단위 테스트 방식으로 테스트 가능
  • 개발중인 제품에는 명확한 접근 방식이 있으며 광범위한 프로토 타이핑 또는 실험이 필요하지 않습니다.
  • 너무 많이 리팩토링 할 필요가 없거나 수백 또는 수천 개의 테스트 사례를 반복해서 다시 작성할 시간이 있어야합니다.
  • 아무것도 봉인되지 않았습니다
  • 모든 것이 모듈 식입니다
  • 모든 것이 주사 가능하거나 조롱 가능
  • 조직에서 결함을 충분히 고려하여 리소스 싱크를 정당화합니다.
  • 단위 테스트 수준에서 테스트하면 이점이 있다는 것

프로젝트가 이러한 요구 사항을 충족하지 않으면 어려움을 겪게됩니다. TDD의 발기인은이 라인에 더 잘 들어가도록 제품을 재 설계하도록 제안하기 위해 다른 것에 대한 해답이 없습니다. 불가능하거나 바람직하지 않은 상황이 있습니다.

실제로 테스트 우선 테스트가 실제로 프로그램의 올바른 기능에 대해 무엇인가를 증명한다고 생각하는 사람들에게는 커다란 문제가 있습니다. 많은 경우에 이것은 사실이 아니지만, 사실 인 경우에도 정확성의 완전한 그림과는 거리가 멀다. 사람들은 수백 건의 통과 테스트를보고 TDD 이전에 수백 건의 테스트 사례 만 수행 한 이후로 더 적은 테스트를하는 것이 안전하다고 가정합니다. 필자의 경험에 따르면 TDD는 개발자가 잘못된 보안을 유지하고 큰 테스트를 수행하기 위해 모든 테스트를 변경해야하기 때문에 더 많은 통합 테스트가 필요하다는 것을 의미합니다.

예 :

개인적으로 가장 좋은 예는 asp.net의 보안 코드를 작성할 때입니다. 그것들이 머신 설정에서 적대적인 환경에서 실행되어야한다면, 그것들은 당황하고 서명되고 봉인되며 IIS 신 객체에 대해 실행되기 때문에 매우 정확하게 조롱하기가 매우 어렵습니다. 성능 및 메모리 사용에 대한 제약 조건을 추가하면 나머지 영역에서 자리 표시 자 개체를 사용할 수있는 유연성을 매우 빠르게 잃게됩니다.

추상화가 최적화되지 않고 리소스 제한이 낮기 때문에 모든 종류의 마이크로 컨트롤러 또는 기타 낮은 리소스 환경 코드는 진정한 OO 스타일 디자인을 수행 할 수 없습니다. 많은 경우에도 고성능 루틴에 대해서도 마찬가지입니다.


당신은 몇 가지 반례를 줄 수 있습니까? 단위 테스트 방식으로 테스트 가능한 것을 작성하지 않을 때는 언제입니까? 왜 모의 코드 나 주사 가능한 코드를 작성하지 않는 이유는 무엇입니까 (레거시 코드 이외의 주제).
Alex Feinman

예제 섹션을 추가하기 위해 편집 됨
Bill

4
동의했다. TDD 작업은 작업중인 기계에 대한 일련의 가정에 의존하는 것 같습니다. 내 프로젝트의 약 50 %에 대해서는 사실이 아닌 것 같습니다.
Paul Nathan

전적으로 동의합니다 ... 훌륭한 답변
Khelben

2
그것은 많은 상황에 적합하고 다른 사람들에게는 부적합한이 게임의 어떤 것과 같습니다. 의 진정한 경로 옹호하는 사람을 조심 어떤 소프트웨어 개발의 영역을.
Alan B

25

내가 본 가장 큰 단점은 TDD 자체가 아니라 실무자입니다. 그들은 모든 것을 테스트해야하는 교의적이고 열성적인 접근법을 취 합니다 . 때때로 (다수의 시간), 그것은 필요하지 않습니다. 또한 실용적이지 않을 수도 있습니다 (예 : 조직을 TDD에 소개).

훌륭한 엔지니어는 트레이드 오프를 찾고 테스트 우선 적용시기 / 장소 / 방법의 적절한 균형을 적용합니다. 또한 실제 코드 대신 테스트 개발에 더 많은 시간을 지속적으로 소비한다면 (2-3 배 이상) 문제가 생길 수 있습니다.

다시 말해, TDD (또는 그 문제에 대한 소프트웨어 개발의 모든 것)에 대해 실용적이고 합리적이어야합니다.


아마도, 레거시 코드에 대한 Michael Feathers의 "새로운"정의 (예 : "테스트없는 코드")는 어디에서 왔습니까?
Phill W.

그 정의는 나를 위해 작동하지 않습니다 :) 나에게, 프로덕션에서 실행되고 변경의 대상이되는 모든 코드는 코드 또는 테스트 품질과 독립적으로 레거시 코드입니다. 실제로 실제 코드와 개발 코드가 프로덕션 환경에서 아직 사용되지 않은 코드에 이미 존재하는 경우 일반적으로 "레거시 코드"와 "불량 코드"또는 "사용되지 않는 코드"를 연결합니다. 우리의 목표는 코드가 시작부터 유산이되고 앞으로 몇 년, 수십 년 동안 사용되는 품질과 유용성을 유지하는 것이어야합니다.
luis.espinal

6

2009 년 8 월 초에 TDD를 시작했으며 2009 년 9 월 -10 월에 회사 전체가 TDD로 전환 할 것을 확신했습니다. 현재 전체 개발 팀이 완전히 전환되었으며 테스트되지 않은 코드를 리포지토리에 커밋하는 것은 나쁜 일로 간주됩니다. 그것은 우리를 위해 훌륭하게 작동했으며 카우보이 코딩으로 다시 전환하는 것을 상상할 수 없습니다.

그러나 꽤 눈에 띄는 두 가지 문제가 있습니다.

테스트 스위트를 유지해야합니다

TDD에 대해 진지하게 생각하면 많은 테스트를 작성하게 됩니다. 또한 테스트 의 올바른 세분성이 무엇인지 인식하는 데 약간의 시간과 경험이 필요합니다. 이러한 테스트는 코드 이며 비 트롯에 취약합니다. 즉, 의존하는 라이브러리를 업그레이드 할 때 업데이트하고 수시로 리팩터링해야합니다. 코드를 크게 변경하면 많은 테스트가 갑자기 만료되거나 심지어 명백한 잘못. 운이 좋으면 간단히 삭제할 수 있지만 많은 경우 유용한 비트를 추출하여 새로운 아키텍처에 적용하게됩니다.

때때로 누출 테스트

우리는 꽤 훌륭한 테스트 프레임 워크를 가진 Django를 사용하고 있습니다. 그러나 때로는 현실과 약간 상충되는 가정을합니다. 예를 들어, 일부 미들웨어가 테스트를 중단 할 수 있습니다. 또는 일부 테스트는 캐싱 백엔드에 대한 가정을합니다. 또한 "실제"db (SQLite3 아님)를 사용하는 경우 테스트를 위해 db를 준비하는 데 많은 시간이 걸립니다. 물론 로컬에서 수행하는 테스트에는 SQLite3 및 메모리 내 db를 사용할 수 있으며 사용해야하지만 일부 코드는 사용하는 데이터베이스에 따라 다르게 동작합니다. 현실적인 설정으로 실행되는 지속적인 통합 서버를 설정해야합니다.

(어떤 사람들은 데이터베이스와 같은 모든 것을 조롱해야한다고 말하거나 테스트가 "순수한"것이 아니라 단지 이데올로기라고 말할 것입니다. 조롱 코드에 오류가있을 경우 테스트 슈트는 쓸모가 없습니다.)

이 모든 것은 내가 설명한 문제는 TDD로 상당히 발전했을 때만 눈에 띄기 시작합니다 ... TDD로 시작하거나 소규모 프로젝트에서 작업 할 때 테스트 리팩토링은 문제가되지 않습니다.


3
+1. "유지되어야한다": 인터페이스와 동작이 일반적으로 안정적이어야하기 때문에 재사용 가능한 코드를 테스트 할 때 문제가 훨씬 적다. 이러한 이유로 저는 보통 재사용 가능한 라이브러리에 대해서만 TDD를 수행합니다.
Dimitri C.

4

저에게는 TDD에서와 같이 광범위하게 적용하려고 할 때마다 테스트에 심리적 문제가 있습니다. 테스트가 있으면 문제가 발생할 것이라고 믿기 때문에 느리게 코딩합니다. 그러나 안전망을 제공하는 테스트가 없다면 신중하게 코딩해야하며 결과는 테스트보다 항상 좋습니다.

어쩌면 나일지도 몰라 그러나 나는 또한 모든 종류의 안전 벨과 휘파람이 달린 자동차가 운전자가 안전 기능이 있다는 것을 알고 있기 때문에 더 충돌하는 경향이 있다는 것을 어딘가 읽었습니다. TDD는 일부 개인과 호환되지 않을 수 있습니다.


테스트 가능한 코드를 작성하면 일반적으로 속도가 느려지고 코딩 대상에 대해 더 많이 생각하기 때문에 이상하게 보입니다. 실제로 요즘 테스트없이 약간 긴장된 코딩을 얻습니다.
Matt H

1
그것은 다른 사람들이 실제로 다르게 반응한다는 것을 보여줍니다. 나는 TDD를 강타하지 않는다. 분명히 많은 사람들이 유용하다고 생각하지만 사실은 모든 사람에게 해당되지 않는다는 것이다.
Joonas Pulakka

2
100 % 동의합니다. 자동화 된 테스트없이 코드를 더 좋고 빠르게 작성합니다 . 물론 테스트하지 않는 것이 어리석은 일이지만 자동화는 나쁜 선택이라고 생각합니다 (적어도 나에게는). 수동 테스트는 테스트 스위트를 유지하는 것보다 빠르고 안전합니다. 그러나 숙련 된 개발자이기도하므로 테스트 대상과 위치 및 이유를 잘 알고 있으므로 코드 추가 및 리 팩터가 회귀 무료.
Ben Lee

1
내가 작업하는 팀과 프로젝트가 모두 규모가 작거나 대규모 프로젝트에서 전체 아키텍처를 이해하기에 충분히 작다는 점을 지적해야하지만 자동화 된 테스트가 더 유용하다고 볼 수 있습니다. 그런 다음 단일 개발자가 회귀를 피하기 위해 테스트해야 할 곳에서 냄새를 맡을 수는 없습니다.
Ben Lee

리팩토링 단계를 생략하고 있습니까?
rjnilsson

2

테스트 우선이 실제로 방해가되는 한 가지 상황은 아이디어를 신속하게 시도하고 적절한 구현을 작성하기 전에 아이디어가 효과가 있는지 확인하려는 경우입니다.

내 접근 방식은 일반적으로 다음과 같습니다.

  1. 실행되는 개념을 구현하십시오 (개념 증명).
  2. 작동하면 테스트를 추가하고 디자인을 개선하고 리팩토링하여 통합하십시오.

때때로 나는 2 단계에 도달하지 않습니다.

이 경우 TDD를 사용하면 나에게 장점보다 단점이 더 많습니다.

  • 개념 증명을 구현하는 동안 테스트를 작성하면 속도가 느려지고 생각의 흐름이 중단됩니다. 아이디어를 이해하고 첫 번째 거친 구현에 대한 세부적인 테스트 시간을 낭비하고 싶지 않습니다.
  • 내 아이디어가 가치가 있는지 알아내는 데 시간이 더 걸릴 수 있습니다.
  • 아이디어가 쓸모가 없다는 것이 밝혀지면 코드와 멋지게 작성된 단위 테스트를 모두 버려야합니다.

따라서 새로운 아이디어를 탐색해야 할 때 TDD를 사용하지 않고 새 코드가 어딘가에 있다는 느낌이들 때 단위 테스트 만 소개합니다.


1
프로토 타입 코드와 사용 가능한 코드를 혼동하는 것 같습니다. 프로토 타입 코드 는 테스트 코드 입니다. 테스트 할 필요가 없으며 테스트를 수행하지 않아야합니다. 누락 된 단계는 1과 2 사이입니다. "테스트를 작성하여 통합"이라고 말합니다. 문제는 통합 할 것이 아니라 작성할 것이 있다는 것입니다. 계획 을 재사용 할 계획이없는, 프로토 타입 코드를 다시 작성합니다. 그것을 재사용하면 타협의 여지가 많이 남습니다. 재 작성은 탐색 단계와 "품질 코드"단계 사이의 분할을 공식화합니다.
utnapistim

3
@utnapistim : 프로토 타입 코드와 사용 가능한 코드를 혼동하지 않습니다 .TDD 열광 자들은 혼동을 일으키며 프로토 타입 코드에도 TDD를 사용해야한다고 제안합니다. 또는 프로토 타입 코드가 전혀 없다고 가정합니다. 또한 프로토 타입에서 실제 구현으로 이동할 때 종종 다시 작성해야한다는 점에 동의합니다. 때로는 프로토 타입 코드의 일부를 재사용 할 수 있지만 다시 작성할 준비가되어 있어야합니다. 당신은 정말로 사건마다 결정해야합니다.
Giorgio

3
@utnapistim : luis.espinal의 답변 참조 : "내가 본 가장 큰 단점은 TDD 자체가 아니라 실무자에게 있습니다. 모든 것을 테스트해야하는 독단적이고 열광적 인 접근 방식을 취합니다.".
Giorgio

1

TDD의 단점 또는 비용

참고 : 다양한 종류의 TDD가 있습니다. 단위, BDD, ATDD 또는 기타 변형에 관계없이 많은 어려움이 남아 있습니다.

부작용

조롱, 고정물 또는 기능 테스트이든 외부 상태 또는 시스템에 대한 종속성은 종종 테스트에서 가장 복잡한 문제, 테스트 방법의 혼란 및 잘못된 오류의 가장 큰 위험의 원인입니다. 내가 본 몇 가지 문제 :

  • 조롱 : 전화 순서를 주장하는 것을 잊지
  • 조롱 : 모의가 실제 전화 또는 응답과 일치하지 않습니다.
  • Fixture : 테스트는 비현실적인 데이터에 의존하여 다른 문제를 숨 깁니다.
  • 정착물 : 생산에서 불가능한 상태 테스트
  • 기능 : 종속 시스템을 일시적으로 사용할 수 없기 때문에 잘못된 빌드 중단
  • 기능 : 테스트 속도가 매우 느림

코딩에 대한 접근 방식을 변경해야합니다. 일부는 급격한 변경이 될 것입니다.

다른 사람들은 매우 다른 방식으로 코딩합니다. TDD에서는 특정 동작을 나타내는 테스트로 시작한 다음 테스트가 통과되도록 구현해야합니다. 나는 TDD에 도움이되지 않는 프로그래밍을 보았고 프로그래머였습니다. 처음에 개발 방식을 바꾸는 데 익숙해지기까지 약 2 개월이 걸렸습니다.

테스트에 관심이있는 것과 테스트에 관심이없는 것을 이해하는 데 시간이 걸립니다.

모든 팀은 테스트에서 라인을 그릴 위치를 명시 적으로 결정해야합니다. 그들이 테스트하고 싶어하는 것과 가치가없는 것. 좋은 테스트를 작성하는 방법과 실제로 테스트에 관심을 갖는 것을 배우는 것은 종종 고통스러운 과정입니다. 한편 코드는 스타일과 접근 방식의 일관성이 유지 될 때까지 계속해서 유동 상태에있게됩니다.

단위 테스트 특정 : 큰 리 팩터

수만 건의 단위 테스트가 포함 된 중요한 코드베이스의 대규모 또는 기본 리 팩터는 모든 테스트를 업데이트하기 위해 막대한 비용이 발생합니다. 이것은 단순히 리팩토링을 수행하는 것과 관련된 비용 때문에 단순히 리팩터링을 수행하는 것에 대한 푸시 백으로 나타납니다.


0

내 비유는 Scalextric 트랙의 장벽입니다. 그것들을 입으면 훨씬 덜 조심스러워집니다.

사람들은 또한 테스트에 대해 약간의 공간 지식을 얻습니다. 잘 작동하기 때문에 코드가 완전히 테스트되었지만 코드는 테스트 프로세스의 시작일뿐입니다.

내 마음에 TDD는 BDD의 디딤돌입니다. 실행되는 테스트 뗏목은 테스트의 기능을 모르면 개발자를 지원하는 데 실제로 도움이되지 않습니다. BDD를 사용하면 테스트 출력이 영어로되어 테스트를 문서화하여 시스템에 대한 이해를 돕습니다.


-1

TDD의 장점은 코드를 이해하지 못하는 사람들로부터 코드를 보호해야한다는 것입니다. 예, 여기에는 종종 본인이 포함됩니다. 그러나 코드를 보호 할 가치가없는 경우 어떻게됩니까? 처음에는 없어야 할 코드가 많이 있습니다! 따라서 TDD의 문제점은 잘못된 코드를 작성하는 개발자에게 있습니다. TDD는 아마도 좋은 코드를 작성하는 데 도움이되지 않을 것이며, 끔찍한 테스트도 작성할 가능성이 훨씬 높습니다. 따라서 그들의 경우에 TDD는 혼란에 추가 할 것이다; 잘못 작성된 테스트 및 / 또는 중복 테스트는 다른 형태의 잘못된 코드보다 재미 있지 않습니다.


1
자신의 코드를 이해하지 못하면 수십억 개의 가능한 테스트 사례 중 코드가 잘못되는 것을 어떻게 막을 수 있습니까?
Michael Shaw

2
당신이 그것을 쓸 때 이해했지만 길을 따라 잊었 기 때문에?
Johan

+1 TDD는 비즈니스 요구 사항을 오해 한 개발자로부터 보호하지 않습니다. 이것은 BDD가 들어오는 곳입니다.
Robbie Dee
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.