테스트 중심 설계를 채택하면 무엇을 잃게됩니까?
네거티브 만 나열하십시오. 부정적인 형태로 작성된 혜택은 열거하지 마십시오.
테스트 중심 설계를 채택하면 무엇을 잃게됩니까?
네거티브 만 나열하십시오. 부정적인 형태로 작성된 혜택은 열거하지 마십시오.
답변:
몇 가지 단점 (그리고 특히 프로젝트의 기초를 작성할 때 이점이 없다고 주장하지는 않습니다. 결국 많은 시간을 절약 할 수 있습니다) :
"실제"TDD (읽기 : 먼저 빨간색, 녹색, 리 팩터 단계로 테스트)를 수행하려는 경우 통합 지점을 테스트 할 때 모의 / 스텁을 사용해야합니다.
모의 사용을 시작하면 잠시 후 DI (Dependency Injection) 및 IoC (Inversion of Control) 컨테이너 사용을 시작하려고합니다. 그러기 위해서는 모든 것 (함정 자체가 많은)에 대한 인터페이스를 사용해야합니다.
하루가 끝나면 "일반적인 방식으로"수행하는 것보다 훨씬 더 많은 코드를 작성해야합니다. 고객 클래스 대신 인터페이스, 모의 클래스, 일부 IoC 구성 및 몇 가지 테스트를 작성해야합니다.
또한 테스트 코드도 유지 관리해야합니다. 테스트는 다른 모든 것만 큼 읽을 수 있어야하며 좋은 코드를 작성하는 데 시간이 걸립니다.
많은 개발자들은 이러한 "올바른 방법"을 모두 수행하는 방법을 잘 이해하지 못합니다. 그러나 모두가 TDD가 소프트웨어를 개발할 수있는 유일한 방법이라고 말해 주므로 최선을 다해 노력하면됩니다.
생각보다 훨씬 어렵습니다. 종종 TDD로 수행 된 프로젝트는 아무도 모르는 많은 코드로 끝납니다. 단위 테스트는 종종 잘못된 것을 잘못 테스트합니다. 그리고 아무도 소위 전문가가 아닌 좋은 시험이 어떻게 생겼는지에 동의하지 않습니다.
이러한 모든 테스트를 통해 시스템 동작을 "변경"(리팩토링과 반대로)하기가 훨씬 어려워지고 간단한 변경만으로 너무 힘들고 시간이 많이 걸립니다.
TDD 서적을 읽으면 항상 좋은 예가 있지만 실제 응용 프로그램에는 종종 사용자 인터페이스와 데이터베이스가 있어야합니다. 이것은 TDD가 정말로 어려워지는 곳이며 대부분의 출처는 좋은 답변을 제공하지 않습니다. 그리고 그렇게한다면 항상 모의 객체, 인터페이스 프로그래밍, MVC / MVP 패턴 등과 같은 더 많은 추상화가 필요합니다. 다시 많은 지식이 필요하며 더 많은 코드를 작성해야합니다.
열성적인 팀이없고 좋은 테스트를 작성하는 방법을 알고 있고 훌륭한 아키텍처에 대한 몇 가지를 알고있는 경험이 풍부한 개발자가 없다면 TDD 길을 가기 전에 두 번 생각해야합니다. .
테스트 횟수가 많은 지점에 도달하면 시스템을 변경하면 변경으로 인해 무효화 된 테스트에 따라 일부 또는 모든 테스트를 다시 작성해야 할 수 있습니다. 이것은 비교적 빠른 수정을 매우 시간 소모적 인 수정으로 바꿀 수 있습니다.
또한 실제로 우수한 설계 원칙보다 TDD를 기반으로 설계 결정을 내릴 수 있습니다. TDD가 요구하는 방식을 테스트 할 수없는 매우 간단하고 쉬운 솔루션이 있었지만 실제로는 실수가 발생하기 훨씬 더 복잡한 시스템이 생겼습니다.
if part of the system is covered by tests and they pass, then everything is fine (including design)
.
제게 가장 큰 문제는 "시간이 걸리는"거대한 시간 손실이라고 생각합니다. 나는 아직도 TDD로 여행을 시작할 때 매우 많이 (내 관심이 있다면 테스트 모험에 대한 내 블로그 를 참조하십시오 ) 문자 그대로 몇 시간을 보냈습니다 시작 을 .
두뇌를 "테스트 모드"로 만드는 데 오랜 시간이 걸리며 "테스트 가능한 코드"를 작성하는 것은 그 자체의 기술입니다.
TBH, 저는 개인적 방법을 공개하는 것에 대한 Jason Cohen의 의견 에 정중하게 동의하지 않습니다. 나는 이전보다 새로운 방식으로 더 이상 공개적인 방법을 만들지 않았다 . 그러나 여기에는 아키텍처 변경이 포함되어 있으며 코드 모듈을 "핫 플러그"하여 다른 모든 것을 쉽게 테스트 할 수 있습니다. 당신은해서는 안됩니다이 작업을 수행하기 위해 코드 내부를보다 쉽게 액세스 할 수있게 . 그렇지 않으면 우리는 모든 것이 공개되는 사각형으로 돌아갑니다. 캡슐화는 어디에 있습니까?
간단히 말해서 (IMO) :
추신 : 긍정적 인 링크를 원한다면 몇 가지 질문을하고 대답했습니다 . 내 프로필을 확인하십시오 .
몇 년 동안 테스트 중심 개발을 수행해 왔지만 가장 큰 단점은 다음과 같습니다.
TDD는 쌍으로 수행하는 것이 가장 좋습니다. 예를 들어 if / else 문 을 작성하는 방법을 알고 있을 때 구현을 작성하려는 충동에 저항하기가 어렵습니다 . 그러나 당신이 그를 계속 임무로 유지하기 때문에 한 쌍은 당신을 임무에 계속합니다. 안타깝게도 많은 회사 / 관리자는 이것이 리소스를 잘 사용한다고 생각하지 않습니다. 동시에 수행해야하는 두 가지 기능이있을 때 두 사람이 하나의 기능을 작성하도록 비용을 지불해야하는 이유는 무엇입니까?
일부 사람들은 단위 테스트 작성에 대한 인내심이 없습니다. 일부는 그들의 일을 매우 자랑스럽게 생각합니다. 또는 복잡한 방법 / 기능이 화면 끝에서 번지는 것을 보는 것과 같습니다. TDD는 모든 사람을위한 것이 아니지만 실제로 그렇게 되었으면합니다. 코드를 물려받은 불쌍한 영혼을 위해 물건을 훨씬 쉽게 유지 관리 할 수 있습니다.
이상적으로 코드를 잘못 판단 할 때만 테스트가 중단됩니다. 즉, 시스템이 한 방향으로 작동한다고 생각했지만 그렇지 않은 것으로 나타났습니다. 테스트 또는 (작은) 테스트를 중단하면 실제로 좋은 소식입니다. 새 코드가 시스템에 어떤 영향을 미치는지 정확히 알고 있습니다. 그러나 테스트가 제대로 작성되지 않았거나 밀접하게 결합되어 있거나 더 심하게 생성 된 경우 ( 기침 VS 테스트) 테스트를 유지하면 합창이 빠르게 이루어질 수 있습니다. 그리고 충분한 테스트로 인해 생성 된 인식 된 값보다 더 많은 작업이 시작된 후에는 스케줄이 압축 될 때 테스트가 먼저 삭제됩니다 (예 : 시간이 많이 소요됨)
이상적으로, 방법론을 준수하면 기본적으로 코드가 100 % 테스트됩니다. 일반적으로 코드 적용 범위는 90 % 이상입니다. 이것은 일반적으로 템플릿 스타일 아키텍처가 있고베이스가 테스트되고 코너를 자르고 템플릿 사용자 정의를 테스트하지 않을 때 발생합니다. 또한, 이전에 경험하지 못했던 새로운 장벽에 직면했을 때이를 테스트 할 때 학습 곡선이 있음을 알게되었습니다. 나는 오래된 skool 방식으로 몇 줄의 코드를 작성하는 것을 인정하지만 실제로는 100 %를 갖고 싶습니다. (나는 학교에서 큰 성과를 거두었다고 생각한다).
그러나 TDD의 장점은 응용 프로그램을 다루는 좋은 테스트 세트를 얻을 수 있지만 한 번의 변경으로 인해 깨지기 쉽지 않은 간단한 아이디어에 대한 단점을 훨씬 능가한다고 말할 수 있습니다. 1 일과 마찬가지로 프로젝트의 300 일째에 새로운 기능을 계속 추가 할 수 있어야합니다. 이는 TDD를 시도하는 모든 사람들이 버그를 타는 모든 코드에 마법의 총알이라고 생각하는 모든 사람들에게는 해당되지 않습니다. 작동하지 않습니다.
개인적으로 TDD를 사용하면 더 간단한 코드를 작성하고 특정 코드 솔루션이 작동하는지 여부에 대해 토론하는 데 시간이 덜 걸리며 다음 기준에 부합하지 않는 코드 줄을 변경할 염려가 없다는 것을 알았습니다. 팀.
TDD는 마스터하기 힘든 학문이며 몇 년 동안 사용해 왔으며 여전히 새로운 테스트 기술을 계속 배웁니다. 초기에는 막대한 시간을 투자하지만 장기적으로는 자동화 된 단위 테스트가없는 경우보다 지속 가능성이 훨씬 큽니다. 이제 내 상사 만 알아낼 수 있다면
첫 번째 TDD 프로젝트에는 시간과 개인의 자유라는 두 가지 큰 손실이 있습니다.
다음과 같은 이유로 시간이 손실됩니다.
다음과 같은 이유로 개인의 자유를 잃습니다.
도움이 되었기를 바랍니다
TDD는 테스트를 통과하기위한 코드를 작성하기 전에 클래스 작동 방식을 계획해야합니다. 이것은 플러스와 마이너스입니다.
코드를 작성하기 전에 "진공"으로 테스트를 작성하는 것이 어렵다는 것을 알게되었습니다. 내 경험상 필자는 초기 테스트를 작성하는 동안 잊어 버린 클래스를 작성하는 동안 필연적으로 무언가를 생각할 때마다 테스트를 넘어가는 경향이 있습니다. 그런 다음 클래스를 리팩터링 할뿐만 아니라 테스트도해야합니다. 이 과정을 3-4 회 반복하면 실망 스러울 수 있습니다.
먼저 수업 초안을 작성한 다음 단위 테스트 배터리를 작성하고 유지하는 것을 선호합니다. 초안을받은 후에 TDD가 제대로 작동합니다. 예를 들어 버그가보고되면 해당 버그를 악용하는 테스트를 작성한 다음 테스트가 통과하도록 코드를 수정합니다.
글쎄, 그리고이 스트레칭, 당신은 테스트를 디버깅해야합니다. 또한 테스트를 작성하는 데 특정 시간이 소요되지만, 대부분의 사람들은 시간을 절약 한 디버깅과 안정성 모두에서 애플리케이션 수명 기간 동안 지불하는 선행 투자라는 데 동의합니다.
그래도 개인적으로 가장 큰 문제는 실제로 시험을 작성하는 훈련을받는 것입니다. 팀, 특히 기존 팀에서는 보낸 시간이 가치 있다고 확신시키기가 어려울 수 있습니다.
TDD의 단점은 일반적으로 시스템의 문서화에 중요 하지 않은 '애자일 (Agile)'방법론과 밀접하게 연관되어 있다는 것입니다 . 테스트가 왜 '어떻게'특정 값을 다른 값이 아닌 하나의 특정 값으로 반환해야하는지에 대한 이해는 개발자의 머리.
개발자가 테스트에서 특정 값이 아닌 다른 값을 반환하는 이유를 떠나거나 잊어 버리면 망하게됩니다. TDD는 세계가 변하고 앱이 필요할 때 5 년 내에 참조 할 수있는 사람이 읽을 수있는 (즉, 뾰족한 머리 관리자) 문서로 적절하게 문서화되고 둘러싸여 있으면 좋습니다.
내가 문서를 말할 때, 이것은 코드의 허풍이 아니며, 이것은 관리자, 변호사 및 업데이트 해야하는 가난한 수액이 참조 할 수있는 유스 케이스 및 배경 정보와 같이 응용 프로그램 외부에 존재하는 공식 글입니다. 2011 년 코드
TDD가 나를 미치게 만드는 몇 가지 상황이 발생했습니다. 일부 이름을 지정하려면 :
테스트 케이스 유지 보수성 :
대기업 인 경우 테스트 사례를 직접 작성하지 않아도되거나 회사에 들어올 때 다른 사람이 작성하는 경우가 많습니다. 응용 프로그램의 기능은 수시로 변경되며 HP Quality Center와 같은 시스템을 추적 할 수있는 시스템이 없으면 즉시 열광 할 것입니다.
이는 또한 새로운 팀 구성원이 테스트 사례와 관련된 상황을 파악하는 데 상당한 시간이 걸린다는 것을 의미합니다. 차례로, 이것은 더 많은 돈이 필요한 돈으로 번역 될 수 있습니다.
테스트 자동화 복잡성 :
테스트 사례 중 일부 또는 전부를 시스템에서 실행 가능한 테스트 스크립트로 자동화하는 경우 이러한 테스트 스크립트가 해당 수동 테스트 사례와 동기화되고 응용 프로그램 변경 사항과 일치하는지 확인해야합니다.
또한 버그를 잡는 데 도움이되는 코드를 디버깅하는 데 시간이 걸립니다. 제 생각에는 이러한 버그의 대부분은 테스트 팀이 자동화 테스트 스크립트의 응용 프로그램 변경 사항을 반영하지 못했기 때문에 발생합니다. 비즈니스 로직, GUI 및 기타 내부 항목의 변경으로 인해 스크립트 실행이 불안정 해집니다. 때로는 변경 사항이 매우 미묘하고 감지하기 어렵습니다. 일단 모든 스크립트가 테이블 1의 정보를 기반으로 계산을 기반으로하여 실패를보고하면 (테이블 1은 이제 테이블 2 임) (누군가 애플리케이션 코드에서 테이블 오브젝트의 이름을 바꿨 기 때문에)
가장 큰 문제는 적절한 단위 테스트를 작성하는 방법을 모르는 사람들입니다. 그들은 서로 의존하는 테스트를 작성합니다 (그리고 Ant와 함께 잘 작동하지만 다른 순서로 실행되기 때문에 Eclipse에서 실행할 때 갑자기 실패합니다). 특별히 테스트하지 않는 테스트를 작성합니다. 코드를 디버그하고 결과를 확인한 다음 테스트로 변경하여 "test1"이라고합니다. 그것들은 단위 테스트를 작성하는 것이 더 쉬울 것이기 때문에 클래스와 메소드의 범위를 넓 힙니다. 단위 테스트 코드는 모든 고전적인 프로그래밍 문제 (무거운 커플 링, 500 줄 길이의 메소드, 하드 코딩 된 값, 코드 복제)와 함께 끔찍하며 유지 관리하기가 어렵습니다. 이상한 이유로 사람들은 단위 테스트를 "실제"코드보다 열등한 것으로 취급합니다. 품질에 전혀 신경 쓰지 않습니다. :-(
모든 코드를 테스트하기 전에 "완료"되었다고 말할 수 없습니다.
코드를 실행하기 전에 수백 또는 수천 줄의 코드를 작성하는 기능이 손실됩니다.
디버깅을 통해 배울 기회가 없습니다.
확실하지 않은 코드를 제공 할 수있는 유연성을 잃게됩니다.
모듈을 단단히 연결할 수있는 자유를 잃게됩니다.
저수준 디자인 문서 작성을 건너 뛰는 옵션을 잃게됩니다.
모든 사람이 변경하기를 두려워하는 코드와 함께 제공되는 안정성을 잃게됩니다.
어렵고 예측할 수없는 요구 사항에 다시 초점을 맞추는 것은 프로그래머의 끊임없는 실패입니다. 테스트 중심 개발을 통해 이미 알려진 평범한 요구 사항에 집중하고 개발을 이미 상상했던 것으로 제한합니다.
생각해보십시오. 특정 테스트 사례에 맞게 설계 될 가능성이 있으므로 창의적이지 않고 "사용자가 X, Y 및 Z를 할 수 있다면 멋질 것"이라고 생각하기 시작합니다. 따라서 사용자가 잠재적 인 쿨 요구 사항 X, Y 및 Z에 대해 모든 흥분을 느끼기 시작하면 디자인이 이미 지정된 테스트 사례에 너무 집중되어 조정하기가 어려울 수 있습니다.
물론 이것은 양날의 칼입니다. 사용자가 원했던 상상할 수 있고 상상할 수있는 모든 X, Y 및 Z를 설계하는 데 모든 시간을 할애하는 경우 필연적으로 아무것도 완성되지 않습니다. 무언가를 완성하면 자신을 포함한 모든 사람이 코드 / 디자인에서 무엇을하고 있는지 전혀 알 수 없습니다.
XML 피드 및 데이터베이스와 같은 "무작위"데이터에 대한 쓰기 테스트는 어렵고 시간 소모적 일 수 있습니다 (매우 어렵지는 않음). 최근 날씨 데이터 피드 작업에 시간을 보냈습니다. 적어도 TDD에 대한 경험이 많지 않기 때문에 쓰기 테스트가 혼란 스럽습니다.
여러 가지 책임이있는 큰 수업을 잃게됩니다. 당신은 또한 여러 책임을 가진 큰 방법을 잃을 것입니다. 리팩토링 할 수있는 능력을 잃을 수도 있지만, 리팩토링해야 할 필요성도 잃게됩니다.
Jason Cohen은 다음과 같이 말했습니다. TDD에는 코드에 대한 특정 조직이 필요합니다. 이것은 구조적으로 잘못되었을 수 있습니다. 예를 들어 개인 메서드는 클래스 외부에서 호출 할 수 없으므로 메서드를 테스트 할 수 있도록 개인용이 아닌 메서드로 만들어야합니다.
나는 이것이 누락 된 추상화를 나타냅니다. 비공개 코드를 실제로 테스트 해야하는 경우 별도의 클래스에 있어야합니다.
데이브 만
테스트 할 수있는 다른 방법으로 응용 프로그램을 작성해야합니다. 처음에는 이것이 얼마나 어려운지 놀랄 것입니다.
어떤 사람들은 너무 열심히 쓰기 전에 무엇을 쓸 것인지 생각하는 개념을 발견합니다. 조롱과 같은 개념도 일부에게는 어려울 수 있습니다. 레거시 앱의 TDD는 테스트 용으로 설계되지 않은 경우 매우 어려울 수 있습니다. TDD 친화적이지 않은 프레임 워크 주변의 TDD도 어려움이 될 수 있습니다.
TDD는 주니어 개발자들이 처음에는 어려움을 겪을 수있는 기술입니다 (주로 이런 방식으로 작동하도록 교육을받지 않았기 때문에).
전반적으로 사람들이 숙련되고 사용자가 '취약한'코드를 추상화하고 더 안정적인 시스템을 갖추게되면 단점이 해결됩니다.
모두 좋은 답변입니다. TDD의 어두운면을 피하는 몇 가지 방법을 추가합니다.
무작위 자체 테스트를 수행하는 앱을 작성했습니다. 특정 테스트 작성의 문제점은 많은 테스트를 작성하더라도 생각하는 경우에만 적용됩니다. 랜덤 테스트 생성기는 생각하지 못한 문제를 찾습니다.
많은 단위 테스트의 전체 개념은 복잡한 데이터 구조와 같이 유효하지 않은 상태로 들어갈 수있는 구성 요소가 있음을 의미합니다. 복잡한 데이터 구조에서 멀리 떨어져 있으면 테스트 할 것이 훨씬 적습니다.
응용 프로그램이 허용하는 한도 내에서 알림, 이벤트 및 부작용의 올바른 순서에 의존하는 디자인을 부끄러워하십시오. 그것들은 쉽게 떨어지거나 뒤섞 일 수 있으므로 많은 테스트가 필요합니다.
TDD에는 코드에 대한 특정 조직이 필요합니다. 비효율적이거나 읽기 어려울 수 있습니다. 또는 건축 적으로 잘못된 것; 예를 들어, private
메소드는 클래스 외부에서 호출 할 수 없으므로 메소드를 테스트 할 수 있도록 개인용이 아닌 메소드로 만들어야합니다.
코드가 변경되면 테스트도 변경해야합니다. 리팩토링을 사용하면 많은 추가 작업이 필요할 수 있습니다.
BDD 원칙을 TDD 프로젝트에 적용하면 여기에 나열된 몇 가지 주요 단점 (혼동, 오해 등)을 완화 할 수 있다고 덧붙입니다. BDD에 익숙하지 않다면 Dan North의 소개를 읽어보십시오. 그는 직장에서 TDD를 적용함으로써 발생하는 몇 가지 문제에 대한 답변으로 개념을 제시했습니다. Dan의 BDD 소개는 여기 에서 찾을 수 있습니다. .
나는 BDD가 이러한 부정적인 것들 중 일부를 다루고 갭 스톱 역할을하기 때문에이 제안 만한다. 피드백을 수집 할 때이 점을 고려해야합니다.
개발 시간이 증가합니다. 모든 방법에는 테스트가 필요하며 종속성이있는 대규모 응용 프로그램이있는 경우 테스트를 위해 데이터를 준비하고 정리해야합니다.