답변:
몇 가지가 있지만 장점 은 단점보다 훨씬 큽니다.
가파른 학습 곡선이 있습니다.
많은 개발자들은 처음부터 테스트 우선 프로그래밍을 효율적으로 수행 할 수있을 것으로 기대합니다. 불행히도 이전과 같은 속도로 경험과 프로그램을 얻는 데 많은 시간이 걸립니다. 당신은 그것을 둘러 볼 수 없습니다.
더 구체적으로 말하면, 잘못되기가 매우 쉽습니다. 당신은 아주 좋은 의도로 아주 쉽게 잘못된 테스트를 유지하거나 테스트하기 어려운 많은 테스트를 작성할 수 있습니다. 여기에 예를 제시하기는 어렵습니다. 이러한 종류의 문제는 단순히 해결하는 데 경험이 필요합니다. 우려 사항을 분리하고 테스트 할 수 있도록 디자인해야합니다. 여기서 가장 좋은 조언은 TDD를 잘 아는 사람과 쌍으로 프로그래밍하는 것입니다.
더 많은 코드를 미리 작성하십시오.
테스트 우선은 테스트를 건너 뛸 수 없다는 것을 의미하며 더 많은 코드를 미리 작성해야합니다. 이것은 더 많은 시간을 의미합니다. 다시, 당신은 그것을 둘러 볼 수 없습니다. 유지 관리, 확장 및 버그가 적은 코드로 보상을받을 수 있지만 시간이 걸립니다.
관리자에게 힘든 판매가 될 수 있습니다.
소프트웨어 관리자는 일반적으로 타임 라인에만 관심이 있습니다. 테스트 우선 프로그래밍으로 전환하고 기능 대신 기능을 완료하는 데 갑자기 2 주가 걸리면 마음에 들지 않습니다. 이것은 확실히 싸울만한 가치가있는 전투이며 많은 관리자들이이를 얻을 수있을만큼 깨달았습니다.
동료 개발자에게 힘든 판매가 될 수 있습니다.
가파른 학습 곡선이 있기 때문에 모든 개발자가 테스트 우선 프로그래밍을 좋아하는 것은 아닙니다. 사실, 나는 대부분의 개발자들이 처음에는 그것을 좋아하지 않는다고 생각합니다 . 페어 프로그래밍과 같은 작업을 수행하여 속도를 높이는 데 도움이 될 수 있지만 판매가 어려울 수 있습니다.
결국, 장점은 단점보다 중요하지만 단점을 무시해도 도움이되지 않습니다. 당신이 처음부터 올바르게 다루고있는 것을 아는 것은 전부는 아니지만 단점의 일부를 협상하는 데 도움이됩니다.
Test-first는 다음과 같은 코드를 작성한다고 가정합니다.
프로젝트가 이러한 요구 사항을 충족하지 않으면 어려움을 겪게됩니다. TDD의 발기인은이 라인에 더 잘 들어가도록 제품을 재 설계하도록 제안하기 위해 다른 것에 대한 해답이 없습니다. 불가능하거나 바람직하지 않은 상황이 있습니다.
실제로 테스트 우선 테스트가 실제로 프로그램의 올바른 기능에 대해 무엇인가를 증명한다고 생각하는 사람들에게는 커다란 문제가 있습니다. 많은 경우에 이것은 사실이 아니지만, 사실 인 경우에도 정확성의 완전한 그림과는 거리가 멀다. 사람들은 수백 건의 통과 테스트를보고 TDD 이전에 수백 건의 테스트 사례 만 수행 한 이후로 더 적은 테스트를하는 것이 안전하다고 가정합니다. 필자의 경험에 따르면 TDD는 개발자가 잘못된 보안을 유지하고 큰 테스트를 수행하기 위해 모든 테스트를 변경해야하기 때문에 더 많은 통합 테스트가 필요하다는 것을 의미합니다.
예 :
개인적으로 가장 좋은 예는 asp.net의 보안 코드를 작성할 때입니다. 그것들이 머신 설정에서 적대적인 환경에서 실행되어야한다면, 그것들은 당황하고 서명되고 봉인되며 IIS 신 객체에 대해 실행되기 때문에 매우 정확하게 조롱하기가 매우 어렵습니다. 성능 및 메모리 사용에 대한 제약 조건을 추가하면 나머지 영역에서 자리 표시 자 개체를 사용할 수있는 유연성을 매우 빠르게 잃게됩니다.
추상화가 최적화되지 않고 리소스 제한이 낮기 때문에 모든 종류의 마이크로 컨트롤러 또는 기타 낮은 리소스 환경 코드는 진정한 OO 스타일 디자인을 수행 할 수 없습니다. 많은 경우에도 고성능 루틴에 대해서도 마찬가지입니다.
내가 본 가장 큰 단점은 TDD 자체가 아니라 실무자입니다. 그들은 모든 것을 테스트해야하는 교의적이고 열성적인 접근법을 취 합니다 . 때때로 (다수의 시간), 그것은 필요하지 않습니다. 또한 실용적이지 않을 수도 있습니다 (예 : 조직을 TDD에 소개).
훌륭한 엔지니어는 트레이드 오프를 찾고 테스트 우선 적용시기 / 장소 / 방법의 적절한 균형을 적용합니다. 또한 실제 코드 대신 테스트 개발에 더 많은 시간을 지속적으로 소비한다면 (2-3 배 이상) 문제가 생길 수 있습니다.
다시 말해, TDD (또는 그 문제에 대한 소프트웨어 개발의 모든 것)에 대해 실용적이고 합리적이어야합니다.
2009 년 8 월 초에 TDD를 시작했으며 2009 년 9 월 -10 월에 회사 전체가 TDD로 전환 할 것을 확신했습니다. 현재 전체 개발 팀이 완전히 전환되었으며 테스트되지 않은 코드를 리포지토리에 커밋하는 것은 나쁜 일로 간주됩니다. 그것은 우리를 위해 훌륭하게 작동했으며 카우보이 코딩으로 다시 전환하는 것을 상상할 수 없습니다.
그러나 꽤 눈에 띄는 두 가지 문제가 있습니다.
테스트 스위트를 유지해야합니다
TDD에 대해 진지하게 생각하면 많은 테스트를 작성하게 됩니다. 또한 테스트 의 올바른 세분성이 무엇인지 인식하는 데 약간의 시간과 경험이 필요합니다. 이러한 테스트는 코드 이며 비 트롯에 취약합니다. 즉, 의존하는 라이브러리를 업그레이드 할 때 업데이트하고 수시로 리팩터링해야합니다. 코드를 크게 변경하면 많은 테스트가 갑자기 만료되거나 심지어 명백한 잘못. 운이 좋으면 간단히 삭제할 수 있지만 많은 경우 유용한 비트를 추출하여 새로운 아키텍처에 적용하게됩니다.
때때로 누출 테스트
우리는 꽤 훌륭한 테스트 프레임 워크를 가진 Django를 사용하고 있습니다. 그러나 때로는 현실과 약간 상충되는 가정을합니다. 예를 들어, 일부 미들웨어가 테스트를 중단 할 수 있습니다. 또는 일부 테스트는 캐싱 백엔드에 대한 가정을합니다. 또한 "실제"db (SQLite3 아님)를 사용하는 경우 테스트를 위해 db를 준비하는 데 많은 시간이 걸립니다. 물론 로컬에서 수행하는 테스트에는 SQLite3 및 메모리 내 db를 사용할 수 있으며 사용해야하지만 일부 코드는 사용하는 데이터베이스에 따라 다르게 동작합니다. 현실적인 설정으로 실행되는 지속적인 통합 서버를 설정해야합니다.
(어떤 사람들은 데이터베이스와 같은 모든 것을 조롱해야한다고 말하거나 테스트가 "순수한"것이 아니라 단지 이데올로기라고 말할 것입니다. 조롱 코드에 오류가있을 경우 테스트 슈트는 쓸모가 없습니다.)
이 모든 것은 내가 설명한 문제는 TDD로 상당히 발전했을 때만 눈에 띄기 시작합니다 ... TDD로 시작하거나 소규모 프로젝트에서 작업 할 때 테스트 리팩토링은 문제가되지 않습니다.
저에게는 TDD에서와 같이 광범위하게 적용하려고 할 때마다 테스트에 심리적 문제가 있습니다. 테스트가 있으면 문제가 발생할 것이라고 믿기 때문에 느리게 코딩합니다. 그러나 안전망을 제공하는 테스트가 없다면 신중하게 코딩해야하며 결과는 테스트보다 항상 좋습니다.
어쩌면 나일지도 몰라 그러나 나는 또한 모든 종류의 안전 벨과 휘파람이 달린 자동차가 운전자가 안전 기능이 있다는 것을 알고 있기 때문에 더 충돌하는 경향이 있다는 것을 어딘가 읽었습니다. TDD는 일부 개인과 호환되지 않을 수 있습니다.
테스트 우선이 실제로 방해가되는 한 가지 상황은 아이디어를 신속하게 시도하고 적절한 구현을 작성하기 전에 아이디어가 효과가 있는지 확인하려는 경우입니다.
내 접근 방식은 일반적으로 다음과 같습니다.
때때로 나는 2 단계에 도달하지 않습니다.
이 경우 TDD를 사용하면 나에게 장점보다 단점이 더 많습니다.
따라서 새로운 아이디어를 탐색해야 할 때 TDD를 사용하지 않고 새 코드가 어딘가에 있다는 느낌이들 때 단위 테스트 만 소개합니다.
참고 : 다양한 종류의 TDD가 있습니다. 단위, BDD, ATDD 또는 기타 변형에 관계없이 많은 어려움이 남아 있습니다.
부작용
조롱, 고정물 또는 기능 테스트이든 외부 상태 또는 시스템에 대한 종속성은 종종 테스트에서 가장 복잡한 문제, 테스트 방법의 혼란 및 잘못된 오류의 가장 큰 위험의 원인입니다. 내가 본 몇 가지 문제 :
코딩에 대한 접근 방식을 변경해야합니다. 일부는 급격한 변경이 될 것입니다.
다른 사람들은 매우 다른 방식으로 코딩합니다. TDD에서는 특정 동작을 나타내는 테스트로 시작한 다음 테스트가 통과되도록 구현해야합니다. 나는 TDD에 도움이되지 않는 프로그래밍을 보았고 프로그래머였습니다. 처음에 개발 방식을 바꾸는 데 익숙해지기까지 약 2 개월이 걸렸습니다.
테스트에 관심이있는 것과 테스트에 관심이없는 것을 이해하는 데 시간이 걸립니다.
모든 팀은 테스트에서 라인을 그릴 위치를 명시 적으로 결정해야합니다. 그들이 테스트하고 싶어하는 것과 가치가없는 것. 좋은 테스트를 작성하는 방법과 실제로 테스트에 관심을 갖는 것을 배우는 것은 종종 고통스러운 과정입니다. 한편 코드는 스타일과 접근 방식의 일관성이 유지 될 때까지 계속해서 유동 상태에있게됩니다.
단위 테스트 특정 : 큰 리 팩터
수만 건의 단위 테스트가 포함 된 중요한 코드베이스의 대규모 또는 기본 리 팩터는 모든 테스트를 업데이트하기 위해 막대한 비용이 발생합니다. 이것은 단순히 리팩토링을 수행하는 것과 관련된 비용 때문에 단순히 리팩터링을 수행하는 것에 대한 푸시 백으로 나타납니다.
TDD의 장점은 코드를 이해하지 못하는 사람들로부터 코드를 보호해야한다는 것입니다. 예, 여기에는 종종 본인이 포함됩니다. 그러나 코드를 보호 할 가치가없는 경우 어떻게됩니까? 처음에는 없어야 할 코드가 많이 있습니다! 따라서 TDD의 문제점은 잘못된 코드를 작성하는 개발자에게 있습니다. TDD는 아마도 좋은 코드를 작성하는 데 도움이되지 않을 것이며, 끔찍한 테스트도 작성할 가능성이 훨씬 높습니다. 따라서 그들의 경우에 TDD는 혼란에 추가 할 것이다; 잘못 작성된 테스트 및 / 또는 중복 테스트는 다른 형태의 잘못된 코드보다 재미 있지 않습니다.