왜 개발 중심 테스트 (DDT)가 아닌 테스트 중심 개발 (TDD)에 대해 민첩한가?


74

따라서 민첩한 것은 아니지만 테스트 중심의 개발은 아닙니다 . 대학의 교수님들은 모두 테스트 아이디어와 코드 테스트에 관한 것이 었습니다. 왜 그런지 잘 모르겠습니다. 내 관점에서 볼 때 코드가 발전함에 따라 변경 될 가능성이 높은 초기 비용이 많이 듭니다.

이것이 내가 TDD를 상상하는 방법과 그것이 나를 혼란스럽게하는 이유입니다. 내가 TDD 계약자로서 집을 지었다면.

  1. 모든 사양 (스토리)을 알려주십시오.

  2. 사양에 대한 승인을 받으십시오.

  3. 필요한 모든 사양을 검사로 분류하십시오 (향후 참조).

  4. 검사관에게 연락하여 그 요점을보고 검사에 실패했다고 말하십시오 (gee 감사합니다).

  5. 집을 짓기 시작하십시오.

  6. 검사관에게 매일 다시 전화하십시오 (2/100 통과).

  7. 오 쏴, 내 이해에 문제가 있었고 지금은 9 개 더 검사를 추가하고 27 개를 변경해야합니다.

  8. 1/109를 통과하는 관리자에게 전화하십시오.

  9. 젠장 인스펙터가 왜 이런 것을 좋아하지 않습니까?

  10. 좀 더 빌드하십시오.

  11. UGGGGHHHHH MORE CHANGES로 망할 인스펙터를 업데이트하겠습니다. 오, 난 실패하지 않아.

  12. 아직 끝났어요?

좋아, 그것은 엉망이 될 수 있지만, 나는 모든 방법을 알아야하는 방법과 코드가있을 때까지 어떻게 작동하는지 알지 못합니다. 99 %의 시간으로 되돌아 가서 단위 테스트를 업데이트하고 어떤 방법 으로든 추가해야합니다. 그냥 거꾸로 보인다.

보다 적절한 것은 DDT 또는 개발 중심 테스트로, 커뮤니티가 잊어 버린 것 같습니다.

집에 대한 DDT 이해는 다음과 같습니다.

  1. 모든 사양 (스토리)을 알려주십시오.

  2. 사양에 대한 승인을 얻어 분리하십시오.

  3. 유닛 (기초)을 시작하십시오.

  4. 까다로운 논리에 대한 메모 (의견)를 작성하십시오.

  5. 다음 장치를 시작하기 전에 마지막에 검사를 받으십시오 (테스트 작성).

  6. 발견 된 문제를 해결하고 다시 검사하십시오.

  7. 본 기기가 다음 기기로 이동하도록 승인했습니다.

우리 모두가 정직하다면 개발자와 비즈니스를 중심으로하는 것이 인간적이지 않습니까? 변경이 더 빨라질 수 있고 오버 헤드없이 TDD가 생성하는 것처럼 보입니다.


60
저에게있어 눈에 띄지 않는 연결 끊김은 통과하기 시작하는 코드를 작성하기 전에 100 회 이상의 테스트를 통과 할 수 있다는 아이디어입니다. @Telastyn이 말했듯이 한 번에 몇 가지 실패한 테스트가 있어야합니다. "Tests then Code then Test"는 코드를 작성 하기 전에 앱의 모든 테스트를 작성하는 것을 의미하지는 않습니다 .
Eric King

33
은유는 반 패턴입니다! 사람들은 당신의 은유가 왜 당신의 실제 관심사를 다루기보다는 주제에 맞지 않는지 설명하는 데 더 많은 시간을 할애 할 것입니다. 이 경우 실제 문제는 모든 테스트 를 미리 작성해야한다고 생각하는 것 같습니다 .
JacquesB

21
여기서 부수적으로 TDD는 민첩한 프로젝트에서 일반적으로 사용되지만 민첩한 프로젝트 관리와 민첩한 개발 관행을 구별하는 것이 중요하다고 생각합니다. 둘 사이에는 매우 강한 관계가 없습니다. 프로젝트 방법론에 관계없이 대부분의 민첩한 개발 방법을 사용할 수 있습니다. 애자일 (핵심)은 실제로해야 할 규범적인 목록이 아니라 최상의 결과를 달성하기 위해 필요에 따라 접근 방식을 조정하는 것입니다. 즉, Agile! = Scrum + TDD입니다.
JimmyJames

35
기록적으로 소프트웨어 개발을 집을 짓는 것과 비교하는 것은 의미가 없습니다. 연구가 완료되었습니다. 결과가 나왔습니다. 정답은 분명합니다. 집을 지을 때와 같은 방식으로 소프트웨어를 만들지 않아도됩니다. 그만큼. 두. 아르. 다른.
riwalk

14
애자일은 빠른 피드백 루프에 관한 것입니다. TDD는 단지 하나의 특정 유형의 피드백 루프
jk입니다.

답변:


83

TDD 접근 방식의 장점 중 하나는 새로운 디자인을 수행 할 때만 실현됩니다.

따라서 첫 번째 비유에서는 소프트웨어의 모양을 알 수있는 방법이 없기 때문에 100 가지 테스트를 작성하지 않습니다.

당신은 하나의 테스트를 작성합니다. 당신은 그것을 실행합니다. 실패합니다. 테스트를 통과시키기 위해 가장 작은 코드 단위를 작성합니다. 그런 다음 테스트를 다시 실행하십시오. 통과합니다.

이제 위의 과정을 반복하여 다음 테스트를 작성하십시오.

이것은 코드가 무엇을 의미하는지 분명 할 때 처음에는 낭비 적 인 접근법처럼 보일 수 있지만,이 접근법의 가장 큰 장점은 테스트 범위가 항상 높고 코드 디자인이 이렇게 깨끗하다는 것입니다.

방법으로, 그것은 쌍 프로그래밍과 함께 진행됩니다. 한 쌍은 테스트를 작성하고, 다음 쌍은 코드를 작성하여 통과시킨 후 다음 테스트를 작성합니다.

새 수업을 작성할 때도이 방법을 사용합니다. 첫 번째 테스트는 클래스 생성자를 시작하는 호출입니다. 그러나 아직 수업을 작성하지 않았으므로 실패합니다. 다음으로 단순하고 빈 클래스를 작성하고 첫 번째 테스트를 통과합니다.

일단 당신의 사고 방식에 들어 서면, 그 속에 있지 않고 "구식"방식으로 코딩하는 것은 매우 어렵다.

좋은 애자일 환경에서 일하면서 이것을 배우거나 더 나은 이해를 위해 좋은 애자일 책 몇 권 (클린 코드와 클린 코더는 모두 훌륭함)을 읽는 것이 좋습니다.


46
"Emergent Design"이라는 용어는 테스트를 통과하여 소프트웨어 디자인을 확장 할 수있는 것처럼 들립니다. 당신은 할 수 없습니다.
Robert Harvey

28
@nerdlyist : 디자인을 잊지 마십시오. 여전히 소프트웨어를 설계해야합니다. 좋은 디자인은 빨강-녹색 리 팩터에서 자연스럽게 나오지 않습니다. TDD는 훌륭한 디자인을 장려하지만 만들지는 않습니다.
Robert Harvey

19
@RobertHarvey, 저는 "Emergent Design"이라는 용어에 완전히 동의하지 않습니다. 테스트를 통과하여 소프트웨어 디자인을 확장 할 수있는 것처럼 들립니다 . 여러 번 그 일을 한 후에는 할 수 있다고 확신 할 수 있습니다.
David Arno

12
@DavidArno : 요구 사항 스펙을 가지고 시작합니까? 해당 사양을 합리적인 아키텍처로 어떻게 변환합니까? 매번 테스트 할 때마다 재창조합니까, 아니면 이전의 건축 원칙을 염두에두고 있습니까? 아무도 장님에서 이것을하지 않습니다. 코드를 더 테스트 가능하게 만드는 것 외에는 테스트를 먼저 작성하는 것에 대한 마술이 전혀 없습니다.
Robert Harvey

45
@DavidArno 귀하의 이의 제기는 숙련 된 개발자 / 건축가로서 충분한 신용을 얻지 못했기 때문이라고 생각합니다. 모듈 X가 직관적으로 어떤 모습인지 이미 알고 있기 때문에 테스트를 통해 개발 방향을 개선 할 수 있습니다. 테스트 작성 하기 전에 모듈이 어떻게 보일지에 대한 직관적 인 개념이 거의 없거나 전혀없는 경험이없는 개발자 는 잘 테스트 된 엉터리 모듈을 만들 것입니다.
svidgen

86

소프트웨어는 집이 아닙니다. 직감은 좋지만 항상 정확한 것은 아닙니다.

필요한 모든 사양을 검사로 분류하십시오 (향후 참조).

정확하지 않습니다. TDD에서는 코드 사용 방법을 설명합니다. 스펙은 "집에 들어갈 방법이있는 집이 있어야한다"고 말합니다. 그런 다음 테스트는 "이봐, 손잡이가있는 정문을 갖고 싶다"고 말합니다. 이것은 도어 프레임, 노브, 키록 등을 구현하는 것부터 시작하는 것보다 미래에 대한 시각 이 훨씬 적습니다.

검사관에게 매일 다시 전화하십시오 (2/100 통과).

이것은 정확하지 않습니다. 당신은 집에 대한 테스트를 작성하지 않습니다. 전면 도어 프레임에 대한 테스트를 작성하고 녹색으로 만듭니다. 그런 다음 문이 단단한 지 테스트하여 녹색으로 만듭니다. 당신은해야 어쩌면 주어진 시간에 깨진 최대 다스 정도의 테스트를. 일반적으로 2-4에 가깝습니다.

또한, "검사관을 불러 내라"유추는 그 사람이 나와서 일을하는 데 어느 정도의 시간이 걸린다는 것을 의미합니다. TDD 반복에 대한 단위 테스트 실행은 문자 그대로 몇 초가 걸립니다.

변경이 더 빨라질 수 있고 오버 헤드없이 TDD가 생성하는 것처럼 보입니다.

당신이 생각하는 것보다 오버 헤드가 적습니다. 테스트를 실행하는 데 몇 초가 걸리는 경우는 전체 개발 시간과 다르지 않을 수도 있습니다.

dev의 문제는 때때로 테스트를받을 때 문제 가 있음을 알게됩니다 . 당신이 화장실 옆에 침대를 놓고 아무도 그런 종류의 문제에 살고 싶어하지 않는 것처럼. 어떤 종류의 TDD 오버 헤드보다 수정하는 데 시간이 오래 걸리는 것. TDD가 처음부터 코드를 사용하고 인터페이스와 인터페이스하는 방법에 대해 생각하기 때문에 TDD가 포착 한 것.

대학의 교수님들은 모두 Tests와 Code, Test의 아이디어에 관한 것이 었습니다.

그러나 TDD는 어디에나있는 것이 아닙니다. 많은 곳이 여전히 먼저 개발을하고 있으며 TDD의 많은 장점이 과장되어 있습니다. 중요한 것은 당신이 시험을하고 그것을 잘 만드는 것입니다. 작업을 수행하는 순서는 덜 중요합니다.


18
마지막 단락에 대해서만 +1 당신의 집 사례는 실제로 "religiousTDD"가 얼마나 어리석은지를 강조합니다.
Robert Harvey

23
"중요한 것은 시험을 만들고 좋은 결과를 얻는 것입니다. 업무 수행 순서는 덜 중요합니다. "저는 TDD (Test-Driven-Development)의 열렬한 팬이며 자주 옹호합니다. 그러나 코드를 작성하는 것은 지저분합니다. 더 어렵고 잘 정의되지 않은 문제의 경우 요구 사항을 이해하기 전에 먼저 코드를 먼저 작성해야합니다. 그런 다음 요구 사항을 작성한 다음 테스트를 작성할 수 있습니다.
Trevor Boyd Smith

1
@TrevorBoydSmith는 그 시점에서 요구 사항이 아닌 문서를 작성하지 않을 것입니다.
머저리

8
TDD 는 코드 사용자 의 관점을 고려하기 때문에 최상의 경우 더 나은 인터페이스를 장려합니다. 예를 들어, 내가 전화 할 때에 open_door대한 플래그를 전달할 필요는 없습니다 toilet_flushed. 따라서 테스트를 그런 식으로 쓰지 않으므로 코드에 이러한 "거친 가장자리"가 없습니다. 어떻게 호출되는지에 대해 충분히 고려하지 않고 작성된 코드는 종종 이상한 인터페이스 또는 가정 / 전제 조건이 있습니다.
brian_o

3
@TrevorBoydSmith에 이름을 붙이기 위해 "Spike & Stabilize"라는 말을 들었습니다. 그렇습니다. 아직 어떻게 해야할지 모르는 것을 발견 할 때 유용한 기술입니다.
RubberDuck

13

물리적 인 물건을 만드는 것과 소프트웨어를 쓰는 것의 유사점은 아주 적습니다.

즉, 지적 할 가치가있는 한 가지 큰 차이점이 있습니다.

"테스트 작성"과 "테스트 실행"에는 차이가 있습니다.

집을 짓는 예에서 요구 사항과 테스트 물리적 건물 보다 우선합니다. 또한 테스트 스위트의 일부는 여러 에이전트에 의해 지속적으로 실행 됩니다 ! 건축업자가 2x4를 집어 들자 마자 그는 "2x4 소리가 어떻게 생겼는지"라는 개념에 대해 즉시 자동으로 장치를 "테스트"합니다. 요구 사항을 집어 들고 나서 요구 사항을 작성하지 않습니다. 그는 기존 검사를 실행합니다.

조립 된 벽, 전기 박스, 배관 등-시험 / 요구 사항은 이미 존재한다. 그들은 지속적으로 직장에있는 모든 사람의 훈련 된 눈에 의해 암시 적으로 자동으로 실행 됩니다 . 검사자가 방문 할 때 기존의 다른 테스트 세트가 실행됩니다. 장치가 기존 테스트 를 통과하도록 구축되지 않은 경우 실패합니다.

마찬가지로 전체 구조도 마찬가지입니다. 계획은 이미 존재합니다. 모든 단계에서 엔지니어는 기존의 조건 세트를 향해 노력하고 있으며 , 빌드 아웃이 완료되면 구조를 테스트 합니다.

즉, 모든 실제 프로젝트가 거대한 테스트 모음을 선행 할 필요는 없습니다. 작업장에 가서 장난감 상자 등으로 나무를 조립하고 직관과 창의력이 당신을 인도하게한다면, 그것은 엄격한 TDD 목공이 아닙니다. 이 경우 기본적으로 매체의 물리적 법칙과 작업의 유효성을 검사하려는 대략적인 기대에 의존합니다 (예 : "컴파일하고 작동하면 좋습니다!").

그리고 괜찮습니다. 모든 것이 엄격한 테스트를 선행 할 필요는 없습니다.

tl; dr

Construction! = 소프트웨어 작성 : 건설은 테스트 중심 방식으로 작동합니다. 모든 장치에 대한 "통과"조건이 어떻게 자신의 buildout 앞에.

"실행 테스트"와 "쓰기 테스트"를 혼동하지 마십시오.

모든 것이 TDD 일 필요는 없습니다.


나는 코드를 얻는다! = 물리적 인 비유. 그러나 이것은 실제로 나를 위해 조금 더 정리합니다. 내 다른 의견에서 지적했듯이 이것이 테스트를 먼저 작성하여 지금 돌아가서 더 큰 변화를 원한다는 것을 궁금해하고 있습니까?
nerdlyist

@nerdlyist 예, 그렇습니다. 그러나 테스트에서 "올바른"사항을 확인하는 경우 원하는 "지배" 입니다.
svidgen

4
집으로 돌아가는 비유 : 고객이 갑자기 다른 스타일의 문으로 교체하려고하는데 크기가 같지 않으면 문 주위의 치수와 개구부 치수가 변경되며 작업에서 "테스트"를 변경해야합니다. "는 구현 변경에 필요한 작업을 반영해야합니다. 그러나, 변하지 않는 많은 테스트가 있습니다 : 문을 열 때 닫히거나, 잠그고, P % 밀폐 상태 여야합니다. 등 ... "뒤로"변경되지 않는 많은 테스트 적절한 물리적 변화 .
svidgen

1
다시 +1 할 수 있다면 마지막 비트를 고려하는 것이 도움이됩니다. 모든 것이 테스트를 필요로하는 것은 아닙니다. 또한 다시 읽으면 통합 및 회귀 테스트와 함께 TDD 단위 테스트를 융합하고 있다고 생각하게되었습니다. 작업자 자동 테스트는 관리자가 통합 단위이며 회귀 테스트는 더 큰 변경을 수행 할 때 수행됩니다.
머저리

1
@nerdlyist 통합 및 회귀 테스트도 테스트 우선 수행 할 수 있습니다. 이렇게하면하지 않는 매우 은 "TDD의 독단"개발주기에 맞게,하지만 결과는 거의 동일합니다 : 당신은 테스트 할 최소한의 외부 코드와 코드, 실제로 그들이 주장하는 것을 검증 테스트를 끝낸다. 코드를 작성한 테스트 하면 이러한 것들 중 일부 또는 전부를 조금 더 어렵게 만들 수 있습니다. 전혀 불가능하지는 않지만 잠재적으로 더 어려울 수 있습니다.
svidgen

11

소프트웨어 작성이 집을 짓는 것과 유사하다는 넌센스 아이디어를 믿는 함정에 빠졌습니다. 그렇지 않습니다. 건축가 도면과 구조 엔지니어 계산을 만드는 것과 더 유사합니다.

이제 실제 주택으로 건축가는 이러한 계획을 미리 만듭니다. 그런 다음 건물을 시작하고 문제를 겪고 물건을 수정하고 건물을 통제하고 변경을 원하는 사람 등을 작성하는 건축업자를 불러야합니다. 그런 다음 건축가가 돌아와서 도면을 업데이트하도록 추가 비용을 청구합니다. 어떻게 된 거예요. 이것은 엉뚱한 일이지만 집을 짓는 데 시간이 오래 걸리고 비싸므로 유일한 방법입니다.

소프트웨어 엔지니어링에 더 좋습니다. 집을 짓는 것과 동등한 것은 컴파일러가 코드를 일종의 컴파일 된 단위 (라이브러리, 앱, 웹 앱 등)로 바꾸는 것입니다. 하루에 수백 번하는 것이 매우 빠르고 저렴합니다. 결과적으로 기능을 추가 할 때 집을 반복적으로 재건하는 것은 말이되지 않으며 테스트를 위해 마지막에 검사자 (QA)에게만 문의하십시오. 대신 해당 검사를 자동화하면 다시 빌드 할 때마다 검사관이 모든 것을 다시 검사하도록 할 수 있습니다.

엄격한 TDD를 따르는 지 또는 일부 코드를 작성하는 테스트 중심의 접근 방식 을 따르는 지 여부 는 실제로 중요하지 않습니다. 나는 첫 번째 접근법을 선호하고 다른 접근법은 후자를 선호합니다. 자신에게 맞는 것을 선택하십시오. 중요한 것은 당신이 따라갈 때 수표를 작성한다는 것입니다. 나중에 변경하면 다른 곳에서 기능이 중단되었다는 경고를 보내 코드를 변경하려는 경우 나중에 도움이됩니다.


1
난 당신이 :) ... 다음 건축과 처리 한 볼

5
"이것은 끔찍한 일이지만 집을 짓는 데 시간이 오래 걸리고 비용이 많이 들기 때문에 유일하게 실용적인 방법입니다." 처음에 결정하면 나중에 큰 재 작성이 필요할 수 있습니다. 증분 디자인이 항상 이런 종류의 문제를 잡는 것은 아닙니다. 당신은 막 다른 골목에서 자신을 발견하고 다시 가야 할 때까지 작은 단계로 움직입니다. 총알이 없습니다.
Giorgio

2
@Giorgio-단일 의사 결정이 코드의 여러 위치에 반영되므로 큰 재 작성이 발생합니다. 결정이 변경되면 코드가 많은 곳에서 변경됩니다. 지속적인 리팩토링은 중복을 제거하고 단일 결정을 반영하는 코드의 양을 제한함으로써이 문제를 완화합니다. 우수한 테스트 범위는 지속적인 리팩토링을 지원합니다.
케빈 클라인

7

우선 선결제 비용은 생각보다 높지 않습니다 . 예, 테스트를하지 않는 것보다 테스트에 더 많은 시간을 할애합니다. 그러나 "테스트 후"방법을 사용하면 실제로 무엇을 낭비하고 있습니까? TDD에는 10 시간이 걸리고 DDT에는 6 시간이 걸립니다. "추가"선결제 비용은 4 시간입니다. 이제 90 % 적용 범위와 같은 코드 메트릭 또는 요구 사항을 적용하면 TDD 및 DDT가 훨씬 더 비용이 많이 듭니다.

TDD로 버그가 적은 코드를 작성합니다. 테스트 요구 사항을 설명했기 때문에 하루 종일 코드가 원하는 작업을 정확하게 수행하고 있음을 증명할 수 있습니다. 아마도 당신은 그것이 잘못된 일을하기를 원했지만 변경 요청 인 버그는 아닙니다. 이것은 중요합니다. 작동하는 제품을 "판매"하는 것이 더 쉽지만 다르게 작동하거나 더 잘 작동 할 수 있으며 작동하지 않는 것으로 인식되는 제품을 판매하는 것입니다. TDD를 사용하면 테스트를 통과하고 작동하지 않는 코드를 작성하는 것이 사실상 불가능합니다. 요구 사항을 이해하지 못하고 잘못되었지만 작동하는 코드를 작성했을 수 있습니다.

코드 기반이 오래 될수록 TDD가 더 좋습니다. 테스트 스위트가 없거나 제대로 구현되지 않은 리팩토링을 시도하십시오. 간단한 변경만으로도 버그가 발생할 수 있습니다. 적용 범위가 좋은 테스트 스위트를 사용하면 제품이 진화함에 따라 제품이 계속 정상적으로 작동 할 수 있습니다. 또한 장기적으로 발생하는 상충되는 비즈니스 규칙을 강조하는 데 도움이됩니다.

당신은 그것이 작동하지 않는 것을 모른다. 테스트 스위트가 없으면 코드가 생각한대로 작동하는지 또는 작동하는 것처럼 보이는지 알 수 없습니다.

var foo = function(in) {
    if(in == 0) {
      return true
    }
}

이제 응용 프로그램 전체에 전화 if(foo()){ doStuff() }하십시오. foo를 수정하면 어떻게됩니까?

var foo = function(in) {
    if(in === 0) {
      return true
    }
}

테스트를 리팩토링하고 건조 해야합니다. 좋은 테스트 스위트는 유지하기 어렵지 않습니다. 잘 쓰여진 원자력 테스트를 통해 한 번에 1-2 개 이상 변경하지 않아도됩니다. 테스트 스위트에 더 큰 변화가 있었을 때, 뭔가 잘못되었다는 것은 큰 위험입니다.

나는 내 모든 방법을 알아야하고 코드가있을 때까지 어떻게 작동하는지 알지 못합니다.

글쎄, 당신은하지 않아야합니다. 일부 작업 단위가 완료되었는지 테스트하는 테스트를 작성해야합니다. 알 수없는 것을 테스트하고 있다고 생각되면 너무 크게 생각하거나 테스트가 너무 작습니다.

예를 들어, 문이 닫히고 잠겨 있다는 것을 알아야합니다. door.close () 및 door.lock ()을 테스트하고 문이 잠겨 있으면 door.open ()이 false를 반환합니다. 그게 다야. 테스트가 door.lock () 인 경우 데이터베이스에서 플래그를 설정합니다. 그런 다음 테스트가 너무 작습니다. 테스트는 door.lock ()의 ​​작동 방식을 알 필요가 없습니다.

이제 문과 창문이 잠겨 있으면 house.isSecure ()는 true를 반환하는 테스트를 작성하고 있습니다. 문이나 창문을 먼저 보지 않으면 너무 큰 생각입니다.

마지막으로, 당신은 너무 큰 작업 단위를보고있을 수 있습니다 . 요구 사항 목록을 받으면 가장 작은 단위로 작업 할 수 있도록 요구 사항을 구성해야합니다. 해당 장치에 대한 테스트를 작성한 다음 코드를 작성하고 헹구고 반복하십시오.

본질적으로, TDD의 작동 방식에 대한 이해 (목록)는 벗어났습니다. 2/100 통과해서는 안됩니다. 1/1 통과, 2/2 통과, 3/3 통과, 4/4 통과 등이 있어야합니다.

당신을 위해 수정 된 목록

  1. 모든 사양을 얻으십시오
  2. 하나의 사양을 선택하십시오
  3. 그것을 테스트
  4. 그것을 코딩
  5. 그것을 테스트
  6. 테스트가 7로 넘어 가면 4로 넘어갑니다.
  7. 모든 스펙을 다 수행했다면 8로 가십시오. 그렇지 않으면 2로 가십시오.
  8. 소비자와 함께 사양을 검토하고 필요한 경우 새 사양을 추가하십시오. 올바르게 수행하면 테스트를 전혀 변경할 필요가 없습니다. 새로운 것을 추가하십시오. 요구 사항 수집이 분리 될 수 있으며 이전 테스트와 충돌하는 테스트를 추가해야하지만 테스트를 거의 변경하지 않아도됩니다.

2
이 답변은 TDD의 실제 장점을 강조하여 레거시 코드베이스를 관리하기 쉽기 때문에 좋아합니다. 프로젝트의 그린 필드 단계에서만 작업 한 많은 사람들은 TDD가 추가 작업 인 것처럼 보이기 때문에 TDD의 이점을 보지 못합니다. 기존 코드베이스를 업그레이드하고 유지 관리해야 할 때 실제로 비용을 지불합니다. 나는 학교에서 그들이 당신에게 프로젝트를 제공하기를 원합니다. 그리고 당신이 그것을 작동시키는 즉시 많은 기능 변경을 요청하십시오. 그것은 현실을 더 가깝게 반영하고 TDD의 가치를 보여줄 것입니다.
thomij

1
이 답변도 마음에 듭니다. 실제로 수동으로 테스트를 실행하는 데 소요되는 시간 (편집, 컴파일, 단계별 수동 디버그, 반복)을 잊어 버리는 경향이 있습니다. TDD는이 대부분을 자동화합니다.
Technophile

여기서 나에게 눈에 띄는 것은 TDD에서 단위 테스트를 작성할 때 클라이언트 기능 사양에 대한 테스트를 작성하지 않고 동작의 동작에 대한 테스트를 작성한다는 점에 유의하는 것이 중요합니다 unit-당신은 프로그래머로서-당신의 두뇌에 그것을 정의했습니다. 즉, "이 클래스는 X가 발생할 때 이벤트를 발생시켜야합니다. 테스트를 작성하겠습니다." 이 모호한 "테스트는 당신의 스펙입니다!" 수사학은 이미 TDD를 받았을 때 훌륭하지만 반복되는 사람에게는 대답보다 더 많은 질문을 제기합니다.
Ant P

4

다른 답변이 누락되었다고 생각되는 키가 있습니다.

세 가지 장점

첫째, 오류 비용과 변경 비용은 소프트웨어와 주택간에 매우 다르기 때문에 일부 규칙이 적용되지 않을 수 있습니다. 예를 들어, 물리적 구조를 테스트하는 데 드는 비용이 너무 커서 테스트를 낭비하지 않도록 작동에 대한 높은 신뢰도가 필요합니다. 소프트웨어를 사용하여 1 ~ 5 초 안에 일련의 단위 테스트를 실행할 수 있다면 다른 옵션을 사용할 수 있습니다.

둘째, 테스트 대상 코드를 작성하기 전에 실패 할 것으로 예상되는 테스트를 실행하는 목적은 테스트 자체를 확인하는 것입니다. 물론 어리 석거나 낭비가 될 수 있습니다. 그러나 테스트중인 코드가 깨져도 항상 통과하는 방식으로 작성된 단위 테스트가 충분했습니다. 테스트 할 코드를 작성하고 수동으로 테스트 한 다음 단위 테스트를 작성할 때 쉽게 발생할 수 있습니다. 단위 테스트를 작성하면 실패를 확인한 다음 통과하는 데 필요한 코드를 작성하고 통과하면 테스트가 제대로 된 것입니다. 테스트중인 코드가 회귀하면 단위 테스트에서이를 잡을 수있는 적절한 기회가 있습니다.

종종 언급되지 않은 TDD의 세 번째 장점은 결과 코드 크기와 복잡성이 종종 10 배 더 작다는 것입니다. 나는 항상 단순하고 간결한 코드를 선호한다는 자부심을 가지고 있습니다. 내가 TDD 연습을 시작할 때까지. TDD는 이전에 수행했던 작업이 과도한 코드라는 것을 보여주었습니다. 왜 이런 일이 발생합니까? 테스트를 작성 했으므로 테스트를 통과시키기위한 코드를 작성하십시오. 시험에 합격하면 시험이 끝난 것입니다. 이 사고 방식에 있다면 실수로 "추가"코드를 작성하기가 어렵습니다.

(추가 코드는 내가 작업했던 제품에서 관찰 한 문제였습니다. 아무도 요청하지 않은 코드에서 발생하는 심각한 문제가 있지만 일부 개발자는 멋질 것이라고 생각했습니다.)

비용 분석

어떤면에서는 당신이 옳습니다. 우리는 집을 지을 때이 전략을 벗어날 수 없었습니다. 너무 비쌀 것입니다. 그러나 소프트웨어는 집이 아닙니다. 소프트웨어가 싸다.

집과의 유추는 집과 소프트웨어 컴파일러를 조립하는 노동입니다.

비 TDD 세계에서 개발자는 여전히 반복합니다. 코드-> 컴파일-> 실행-> 테스트주기를 따릅니다. 우리는 이미 집을 짓는 것과 실질적으로 다른 모델에 있습니다. 건축 직원이 문틀을 만든 다음 문을 짓고 문이 너무 커서 문틀을 다시 만들어야하는 경우 비용 문제가 발생합니다. 따라서 모든 것을 완벽하게 갖추기 위해 더 많은 시간을 선행해야합니다. 프로그래밍에서 대부분의 프로젝트는 몇 초 또는 몇 분 안에 컴파일 될 수 있으므로 초기에 무언가가 불완전한 경우에는 중요하지 않습니다. 사소한 문제를 미리 생각하는 비용은 일반적으로 재 컴파일 비용을 능가합니다. 따라서 우리는 항상 다시 컴파일합니다.

TDD는 동일한 원리이며 방금 회전하여 테스트를 시작합니다. 테스트를 매우 저렴하게 수행 할 수 있다면 (초 단위로 모두 실행), 단일 빅뱅 코딩 반복의 완벽한 전체 솔루션 인 큰 그림을 통한 사고 비용이 리팩토링 비용을 능가합니다.

외...

프로그래밍에서 이러한 주장이지지되지 않는 부분이 있습니다. 이것이 건축의 목적입니다. 나중에 변경하는 데 비용이 많이 드는 선행 문제를 식별하고 계획하십시오. 예를 들어, 필요에 대해 생각하지 않고 즉시 데이터베이스를 선택하지 않고 구축을 시작한 후 나중에 변경할 수 있다고 주장하기 만합니다. 당신은 그것을 통해 생각해야합니다.


1
테스트 확인에 대한 좋은 지적! 또한 : 집을 지을 때 벽을 움직이는 것이 어렵습니다 (그리고 흉터가 남습니다). 소프트웨어를 사용하면 의도하지 않은 변경 사항을 자동으로 테스트 할 수 있으므로 코드를 쉽게 이동할 수 있습니다.
Technophile

4

나는 TDD 프로젝트를 몇 번 할 때까지 이것에 대해 많이 궁금해했다. 내가 이것을하는 동안 나에게 매우 간결하고 포괄적 인 설명이 있습니다.

코드를 작성할 때 코드가 의미있는 작업을 수행 할 수있는 방법이 있어야합니다. 따라서 코드를 테스트하십시오. 임시 테스트를 수행 할 수 있습니다. 그러나 작업을 시작하기 전에 테스트하는 방법에 대해 생각하면 테스트가 더 효과적입니다. 따라서 테스트를 시작하기 전에 테스트 전략을 설계하십시오.

테스트 전략에 대해 생각하고 있으므로 적어도 일부는 자동화 할 수 있습니다. 테스트를 통과 할 때까지 코드를 작성한다는 사실은 정상입니다. 어쨌든 당신이하는 일입니다. 작동 할 때까지 코드를 작성하십시오. 이제 테스트를 시작하기가 쉬워졌습니다.

범위를 벗어난 이유로 전체 내용을 한 번에 쓰지 않습니다. 따라서 테스트를 한 번에 디자인하지 않아도됩니다. 그러나 기본적으로 그것이 바로 그런 것입니다. 테스트 계획을 개선하기 위해 항상 테스트를 미리 작성하지는 않습니다. 때때로 진행하면서 더 많은 것을 추가하고 예상하지 않았거나 나중에 테스트를 더 강력하게 만드는 버그를 찾습니다. 때로는 테스트를 설계하지는 않지만 수동 테스트를 힘들게 수행하여 나중에 테스트를 수행 할 수도 있습니다.

따라서 TDD는 작업을 검증하는 방법을 보는 극단적 인 방법입니다.


4

이 질문에는 이미 받아 들여진 대답이 있지만 작성하지 않은 테스트 스타일의 디자인 (테스트 절차에 따라 "테스터"가 수동으로 수행 한 모든 테스트)에서 TDD로 추가 할 것이 있다고 생각합니다. 비록 그것들이 상당히 보편적이라고 믿지만 이것들은 단지 개인적인 관찰입니다.

이전에 해본 적이없는 새로운 것을 작성할 때 TDD와 TDD를하지 않는 것 사이에는 큰 차이가 없습니다.

일반적으로 당신이하는 일은 아이디어를 탐색하기 위해 작은 코드를 작성하고 "테스트"를 위해 하드 코딩 된 비트를 추가 한 다음 컴파일 및 / 또는 실행하는 것입니다. 작동하면 하드 코딩 된 항목을 삭제하고 매개 변수, 인스턴스 변수 등을 추가하여 코드를 일반화하십시오.

생각 해봐 그것은 TDD와 정확히 같은 양의 일입니다. 유일한 차이점은 TDD에서 "테스트"비트를 다른 파일에 별도로 쓰고 마지막에 삭제하지는 않는다는 것입니다. TDD에서는 테스트 코드를 유지합니다 .

물론 TDD가 약간 더 체계적이라는 것은 코드의 테스트 비트를 실제 코드와 분리하는 방법을 알아내는 작업이 조금 더 있다는 것을 의미합니다. 그러나 단위 테스트를 작성하기 전에 테스트를 위해 코드를 모듈화하는 방법을 배우게됩니다.


2

왜 개발 중심 테스트 (DDT)가 아닌 테스트 중심 개발 (TDD)에 대해 민첩한가?

이 질문에 내가 이의를 제기 할 수있는 사실 ( "민첩은 모든 TDD에 관한 것")을 암시한다는 사실을 알게 되었기 때문에 여기서 chi 소리를냅니다. 모든 대답은이 사실을 당연한 것으로 생각합니다. 민첩성이 주로 TDD (일명 단위 레벨 테스트)에 관한 것이라고 가정하면 좋은 답변입니다.

https://en.wikipedia.org/wiki/Agile_software_development#Agile_methods 에는 수십 가지 이상의 다양한 개발 모델이 나와 있습니다.

나는 특히 행동 주도 개발과 기능 중심 개발을 생각의 음식으로 제공 할 것입니다. 완전히 다른 짐승들 기본적인 TDD의 모든 이점을 이끌어 낼 수 있지만 단순한 빨강-녹색 리 팩터 사이클과는 거리가 멀다.

그래서 내 대답은 :

  • "DDT"(일명, 구현 후 또는 위에 테스트 작성)는 실제 사유로 작동하지 않습니다. 시간이나 돈이 가해지면 테스트가 중단됩니다. 어쨌든 시험을하는 것의 이점에 대한 시험을하는 것은 오히려 아무래도 IMO입니다.
  • 애자일은 그 용어가 기본적으로 "모든 빌딩 블록 / 클래스에 대한 단위 테스트"(적어도 위키 ​​백과에 따르면)를 의미하는 것으로 해석한다면 테스트 중심 개발 (TDD)에 관한 것이 아닙니다 . TDD는 민첩한 개발을 수행 할 수있는 가능성 중 하나 일뿐입니다.
  • 풀 스택 방식을 수행하는 BDD 또는 FDD와 같은 다른 방법이 있습니다. 여전히 시나리오를 미리 작성하고, 빨강-녹색 리 팩터주기가 있으며, 시나리오가 녹색이 될 때까지만 구현하지만 정의에 따라 "테스트"는 전체 소프트웨어를 사용자 정의하여 (사용자 상호 작용처럼 작동) 절대로 하나의 단일 장치.

오히려 완전한 BDD / FDD 적용 범위를 가지고 있고 전체 단위 테스트 적용 범위와 전체 스택 테스트가없는 단위 테스트보다 단위 테스트가없는 응용 프로그램을 원합니다.

(TDD는 물론 API와 같은 위치를 가지고 있지만 여기서 이야기하고있는 것은 아닙니다.)

다시 말하지만, 나는 여기에 다른 모든 대답을 내리려고 노력하지 않고 단지 질문이 다소 좁게 공식화되어 있으며 더 많은 것을 제공 할 수 있다고 지적했습니다.


나는 다른 것을 알고 있었지만 당시에는이 ddt를 쓰는 것이 더 의미가있는 것처럼 보였습니다. API에 TDD가 더 좋은 이유에 대해 자세히 알아 볼까요? MVC를 사용하는 웹 클라이언트에서 사용하는 방법이 어떻게 다릅니 까?
머저리

1
API에서는 매우 상세한 계약 을 따르는 것이 매우 중요합니다 . 각 메소드 호출은 사용자 (다른 프로그램)가 올바르게 사용할 수 있도록 매우 예측 가능해야합니다. 이것은 단위 테스트가 실제로 빛나는 곳입니다. OTOH는 응용 프로그램에서 사용자가 의도 한대로 작업해야하는 기능에 가장 중요합니다. 물론 "내부"도 정확하지만 각 개별 방법을 테스트하는 대신 "End to End"기능 (예 : UI에서 DB로 또는 그 뒤로)을 잘 다루는 것이 더 중요합니다. 인간 최종 사용자는 어쨌든 볼 수 없습니다).
AnoE

물론, 여기에는 모두 다른 정도가 있습니다. 어딘가에 매우 복잡한 방법 / 클래스가 있어야하는 경우 (예 : 지 좌표 간의 거리 계산); 그러나 대량 (예 : 비즈니스 애플리케이션)은 전체 워크 플로우입니다.
AnoE

0

이 방법으로 자주 작성되는 것을 보지 못하더라도 민첩한 이유는 코드를 다시 작성하는 것이 처음에 잘 작성하는 것보다 낫다는 것입니다. 코드를 다시 작성할 때마다 코드가 향상되고 자신이 향상됩니다. 처음에 "오른쪽으로"얻는 것은 느리고 취하기 쉬운 경향이 있습니다.

집의 비유가 그다지 나쁘지는 않지만, 우리는 집 건축에 대해 얼마나 오랫동안 알고 있고 소프트웨어 공학에 대해 얼마나 오랫동안 알고 있었는지 고려해야합니다. 또한 소프트웨어 공학의 복잡성은 긴 다리를 짓는 것에 더 가깝습니다. 또는 집보다 20 층짜리 탑. 또한 새로운 언어와 도구가 만들어 짐에 따라 모든 건축업자가 완전히 다른 모양, 크기 및 재료로 건물을 짓고 싶었던 것처럼 생각해야합니다. 혼돈을 완료하십시오.

그러나 검사는 코드 테스트와 유사하지 않습니다. 소프트웨어에서 우리는 괜찮은 감독관을 보유하고있는 시점조차 아닙니다 (다양한 기술 수준의 동료 제외). 또한 대부분의 임의의 "코딩 표준"(페인트의 색상과 잔디밭 레이아웃을 테스트하는 것과 더 유사 함)을 제외하고는 검사 할 규정이 없습니다.

테스트 우선은 벽을 쌓는 것과 비슷합니다. 벽을 들어 올려 집에 놓기 전에 안정성을 확보하기 위해 약간의 압력을가합니다. 창을 배치하기 전에 남은 구멍에 맞도록 창을 측정하는 것과 같습니다.

교량을 짓기 전에 교량이 작동한다는 것을 현재 입증해야 할 수십 년의 이전 건축 지식, 패턴, 규정 및 수학없이 일련의 교량을 건축해야한다면 교량을 시험하고 재건 할 것입니다.

코드의 일부를 다시 작성할 수있을 때마다 소프트웨어를 통해 비 분석 지점으로 코드와 기술을 크게 향상시킵니다. 코드를 다시 작성할 수있는 모든 기회를 가지십시오. TDD는 큰 변명이 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.