TDD를 수행 할 때 한 번에 모든 테스트를 작성하지 않는 이유는 무엇입니까?


54

TDD에 대한 빨강-녹색-리 팩터 사이클이 잘 설정되어 승인되었습니다. 우리는 하나의 실패한 단위 테스트를 작성하여 가능한 한 간단하게 통과시킵니다. 클래스에 대해 많은 실패한 단위 테스트를 작성 하고 한 번에 모두 통과하게 만드는 것보다이 방법의 이점은 무엇입니까?

테스트 스위트는 리팩토링 단계에서 잘못된 코드를 작성하거나 실수하는 것을 방지합니다. 때로는 클래스 (또는 모듈)에 대한 모든 테스트를 먼저 '브레인 덤프 (brain dump)'의 형태로 작성하여 모든 예상되는 동작을 한 번에 빠르게 기록하는 것이 더 쉽습니다.


20
(실험 후) 자신에게 가장 잘 맞는 것을하십시오. 맹목적으로 교리를 따르는 것은 결코 좋은 일이 아닙니다.
Michael Borgwardt

6
나는 쓰는 것을 아마 ... 일 것 모두 한 번에 모든 응용 프로그램 코드를 작성하는 것처럼 한 번 정도에서 테스트를.
Michael Haren

1
@MichaelHaren 클래스 (또는 기능 모듈)에 대한 모든 테스트, 혼란에 대해 죄송합니다
RichK

3
"두뇌 덤프 (brain dump)"문제 해결 : 때때로 여러 가지 다른 특정 입력 테스트가 필요하다는 사실을 깨닫고 테스트 / 코딩에 문제가있을 수 있습니다. 코딩의 축소. 나는 보통 별도의 목록 (예 : Mylyn)을 유지하거나 테스트 클래스에서 주석으로 기억해야 할 다른 것들의 주석 목록 (예 : // null 경우 테스트)을 유지하여 관리합니다. 그러나 나는 여전히 한 번에 하나의 테스트 만 코딩하고 대신 체계적으로 목록을 작성합니다.
Sam Goldberg

1
글쎄, 나는 왜 아무도 이것을 언급하지 않았는지 모르지만 모든 테스트를 한 번에 작성할 수는 없습니다 . 미리 모든 테스트를 작성하는 것은 BDUF 를 수행하는 것과 정확히 동일 합니다. 그리고 BDUF에 대한 역사는 우리에게 무엇을 가르쳐 주었습니까? 그것은 거의 결코 작동하지 않습니다.
Songo

답변:


49

테스트 중심 디자인은 코드가 아닌 API를 올바르게 구현하는 것입니다.

가장 간단한 실패한 테스트를 먼저 작성하면 가능한 한 간단하게 API (기본적으로 설계 중임)를 얻을 수 있다는 이점이 있습니다. 앞.

향후 사용 (다음에 작성하는 테스트)은보다 복잡한 경우에 대처하는 차선책이 아닌 초기 단순 설계에서 시작됩니다.


훌륭한 포인트! 우리는 때때로 코드 테스트에 몰두하여 첫 테스트를 작성하기 전에 API 및 도메인 모델이 얼마나 중요한지 때때로 무시합니다.
maple_shaft

실제로 테스트 주도 개발 의 의도를 해결하기 위해 +1 .
Joshua Drake

76

하나의 테스트 를 작성할 때 가지에 집중합니다 .
많은 테스트를 통해 많은 작업에주의를 기울이는 것은 좋지 않습니다.


8
누가 이것을 공감할 것인가?!
CaffGeek

6
@ 채드 나는 다운 투표가 아니었지만이 답변이 명백한 것을 놓치고 있다고 생각합니다. 테스트 주도 개발은 코드를 디자인하기 위해 테스트를 사용하는 것입니다. 테스트 가능성뿐만 아니라 디자인을 발전시키기 위해 테스트를 개별적으로 작성합니다. 테스트 아티팩트에만 관한 것이면 이것이 정답 일 수 있지만 중요한 정보가 빠져 있습니다.
Joshua Drake

7
나는 이것을 downvote하지 않았다; 나는 그것에 대해 생각했다. 복잡한 질문에 대한 답변이 너무 짧습니다.
Mark Weston

2
한 번에 한 가지에 집중하면 +1하여 멀티 태스킹 능력이 과대 평가됩니다.
cctan

가능한 가장 간단한 대답입니다.
DNA

26

단위 테스트를 작성할 때 어려움 중 하나는 코드를 작성하고 있으며 그 자체로 오류가 발생하기 쉽다는 것입니다. 구현 코드를 작성할 때 리팩토링 노력의 결과로 나중에 테스트를 변경해야 할 수도 있습니다. TDD를 사용하면 잠재적으로 테스트에 약간의 어려움을 겪을 수 있으며 프로젝트 과정에서 구현이 성숙함에 따라 본질적으로 "비평가 된"테스트 코드를 많이 작성해야 할 필요성을 발견 할 수 있습니다. 이런 종류의 문제를 피하는 한 가지 방법은 한 번에 하나의 일을하는 데 집중하는 것입니다. 이렇게하면 변경 사항이 테스트에 미치는 영향을 최소화 할 수 있습니다.

물론 이것은 테스트 코드 작성 방법에 따라 크게 달라집니다. 모든 개별 방법에 대해 단위 테스트를 작성 중입니까? 아니면 기능 / 요구 사항 / 행동에 중점을 둔 테스트를 작성 중입니까? 또 다른 접근법은 적절한 프레임 워크와 함께 행동 주도 방식을 사용하고 마치 테스트를 마치 사양처럼 작성하는 데 집중할 수 있습니다. 이것은 BDD 방법을 채택하거나 TDD를 공식적으로 고수하려는 경우 BDD 테스트를 적용하는 것을 의미합니다. 또는 TDD 패러다임을 완전히 고수 할 수 있지만 테스트 방법을 변경하여 개별적으로 테스트 방법에 중점을 두는 대신 구현하는 요구 사항 기능의 세부 사항을 충족시키는 수단으로 동작을보다 일반적으로 테스트 할 수 있습니다.

당신이 취한 특정 접근 방식에 관계없이, 위에서 설명한 모든 경우에 테스트 우선 접근 방식을 사용하고 있으므로 뇌를 멋진 테스트 스위트로 다운로드하는 것이 유혹적 일 수도 있습니다. 절대적으로 필요한 것 이상을 유혹하십시오. 새로운 테스트 스위트를 시작하려고 할 때마다 YAGNI를 반복해서 시작하고 때로는 코드에 주석을 달아 즉시 중요한 것에 집중하고 나에게 만족하는 데 필요한 최소한의 것만 강조합니다. 구현하려는 기능의 요구 사항. Red-Green-Refactor를 고수하면이를 수행 할 수 있습니다.


테스트 코드를 작성하는 방법의 차이점을 지적하게되어 기쁩니다. 일부는 단일 함수 또는 방법에 대한 입력의 모든 현실적인 가능성을 다루는 단일 마스터 유닛 테스트를 작성하는 것을 좋아합니다. 다른 사람들은 단위 테스트를 통해 더 많은 BDD 접근 방식을 취합니다. 전체 테스트 모음을 작성하는 것이 중요한지 여부를 판단 할 때이 구별이 중요합니다. 대단한 통찰력!
maple_shaft

17

이 작업을 수행하면 TDD 프로세스 를 놓칠 수 있습니다. 처음에 모든 테스트를 작성하면 실제로 TDD를 사용하여 개발하는 과정을 거치지 않습니다. 필요한 테스트를 미리 추측 할 수 있습니다. 이것은 코드를 개발할 때 한 번에 하나씩 수행하면 작성하는 테스트와는 매우 다른 테스트 세트입니다. (당신의 프로그램이 본질적으로 사소한 것이 아니라면)


1
대부분의 비즈니스 및 엔터프라이즈 응용 프로그램은 기술적으로 사소한 것이며 대부분의 응용 프로그램이 비즈니스 및 엔터프라이즈 인 방식으로 간주되므로 대부분의 응용 프로그램도 본질적으로 사소합니다.
maple_shaft

5
@maple_shaft-기술은 사소한 것이지만 비즈니스 규칙은 아닙니다. 요구 사항이 서로 다른 5 명의 관리자를 위해 앱을 만들어보고 단순하고 우아하며 덜 단순한 미니멀리즘 디자인에 대한 BS의 의견을 거부하십시오.
JeffO

5
@JeffO 1) BS가 아닙니다. 2) 우아한 미니멀리스트 디자인에는 우수한 소프트웨어 개발 기술이 필요합니다. 3) 일주일에 5 분 이상 시간을 허비하지 않고 미니멀리스트 디자인을 시작하는 5 명의 다른 관리자의 요구 사항을 완화하려면 우수한 소프트웨어 개발자 가 필요합니다 . 전문가 팁 : 소프트웨어 개발은 ​​단순한 코딩 기술 그 이상이며, 협상, 대화 및 소유권 취득입니다. 당신은 알파 개가되어야하고 가끔 물러서야합니다.
maple_shaft

1
내가 올바르게 이해하면이 대답은 질문을 구걸하고 있습니다.
Konrad Rudolph

1
@maple_shaft Jeff O가 자신의 의견으로 얻은 것 같아요?
ZweiBlumen

10

나는 "두뇌 폭풍우"동안 내가 생각할 수있는 모든 테스트를 "쓰기"하지만, 각 테스트 는 테스트를 설명 하는 단일 의견으로 작성합니다.

그런 다음 하나의 테스트를 코드로 변환하고 컴파일하여 전달 합니다. 필자가 생각한 모든 테스트가 필요하지 않거나 다른 테스트가 필요한 경우가 종종 있습니다.이 정보는 테스트를 통과하기 위해 코드를 작성하는 경우에만 제공됩니다.

문제는 테스트하는 메소드와 클래스를 만들 때까지 코드로 테스트를 작성할 수 없다는 것입니다. 그렇지 않으면 한 번에 단일 테스트를 수행하는 방식을 얻는 많은 컴파일러 오류가 발생합니다.

테스트가 "영어"로 작성 될 때 사양 흐름과 같은 시스템을 사용하는 경우 단일 테스트 만 작성하는 것이 아니라 고객이 시간이있는 동안 테스트 세트에 동의하도록 할 수 있습니다.


1
예, 먼저 모든 테스트를 코딩하는 데 문제가 있음을 지적하는 위의 답변에 동의하지만 현재 방법이 코드없이 테스트 설명 세트로 작동하는 방법에 대한 전반적인 이해를 덤프하는 것이 매우 도움이됩니다. 이것을 작성하는 과정은 내가 작성하려는 코드에 필요한 것을 완전히 이해하는지, 그리고 내가 생각하지 않은 경우가 있는지를 명확히하는 경향이 있습니다. 첫 번째 테스트를 코딩하고 메소드 작동 방식에 대한 "개요"를 요약 한 후 통과하기가 훨씬 편해졌습니다.
Mark Weston

10

TDD의 기본 개념은 빠른 반복입니다.

코드를 작성하기 전에 작성해야하는 대규모 테스트가있는 경우 코드를 반복적으로 리팩터링하기가 어렵습니다.

쉬운 코드 리팩토링이 없으면 TDD의 많은 이점을 잃게됩니다.


5

TDD 내 (제한적) 경험에서, 나는 당신을 말할 수있는 모든 내가 한 번에 하나 개의 테스트를 작성하는 분야를 세분화 한 시간이, 일이 잘못 갔다. 넘어지기 쉬운 함정입니다. "오, 그 방법은 사소한 일입니다. 따라서 저는이 두 가지 관련 테스트를 중단하고 계속 진행하겠습니다." 뭐라고 생각해? 보이는 것만 큼 사소한 것은 없습니다. 이 함정에 빠질 때마다 내가 생각 하기 쉬운 것을 디버깅 했지만 이상한 코너 케이스가 나타났습니다. 그리고 한 번에 여러 가지 테스트를 작성 했으므로 버그의 위치를 ​​추적하는 것은 많은 작업이었습니다.

정보의 두뇌 덤프가 필요한 경우 많은 옵션이 있습니다.

  • 희고 매끄러운 칠판
  • 사용자 스토리
  • 코멘트
  • 좋은 ol '펜과 종이

이 목록의 어느 곳에도 컴파일러가 없습니다. :-)


5

코드를 작성하기 전에 코드의 모양을 알고 있다고 가정합니다. TDD / BDD는 QA 프로세스만큼이나 설계 / 발견 프로세스입니다. 특정 기능에 대해 기능이 만족되는지 확인하는 가장 간단한 테스트를 작성합니다 (때로는 기능의 복잡성으로 인해 몇 가지가 필요할 수 있음). 작성한 첫 번째 테스트에는 작업 코드의 모양에 대한 가정이로드됩니다. 이를 지원하기 위해 첫 번째 코드 행을 작성하기 전에 전체 테스트 스위트를 작성하면 검증되지 않은 가정이 많이 생깁니다. 대신, 하나의 가정을 작성하고 확인하십시오. 그리고 다음을 쓰십시오. 다음 가정을 확인하는 과정에서 이전 가정을 깨뜨릴 수 있으므로 돌아가서 첫 번째 가정을 현실과 일치하도록 변경하거나 현실을 변경하여 첫 번째 가정이 여전히 적용되도록해야합니다.

과학 노트에서 여러분이 작성한 각 단위 테스트를 이론으로 생각하십시오. 공책을 작성할 때 당신은 당신의 이론을 증명하고 새로운 것을 형성합니다. 때때로 새로운 이론을 증명하는 것은 이전 이론을 반증하므로 수정해야합니다. 한 번에 20 개라고 말하지 않고 한 번에 하나의 이론을 증명하는 것이 더 쉽습니다.


TDD는 코드를 작성하기 전에 작은 조각으로 코드가 어떻게 생겼는지 알고 있다고 가정합니다.
Michael Shaw

4

TDD는 고도로 반복적 인 접근 방식으로 (제 경험상 실제 개발 방식에 더 적합합니다). 일반적으로이 프로세스 중에 구현이 점차 구체화되며 각 단계에서 테스트에 대한 추가 질문, 통찰력 및 아이디어를 얻을 수 있습니다. 이것은 내 생각이 실제 작업에 집중되도록하는 데 이상적이며, 특정 시점에 단기 메모리에 제한된 수의 항목 만 유지하면되기 때문에 매우 효율적입니다. 이것은 실수의 가능성을 줄입니다.

귀하의 아이디어는 기본적으로 Big Test Up Front 방식이며, IMHO는 다루기가 더 어려워지고 더 낭비 될 수 있습니다. 작업 중 중간에 접근 방식이 좋지 않다는 것을 인식하고 API에 결함이있어 전체를 다시 시작하거나 타사 라이브러리를 대신 사용해야하는 경우는 어떻게됩니까? 그런 다음 테스트를 미리 작성하는 데 많은 노력이 낭비됩니다.

즉, 이것이 당신에게 효과적이라면 괜찮습니다. 고정적이고 상세한 기술 사양, 친밀한 경험이있는 도메인 및 / 또는 상당히 작은 작업을 수행하는 경우 필요한 테스트 사례가 대부분 또는 모두 준비되어 있고 구현이 명확하게 시작될 수 있습니다. 시작. 그런 다음 모든 테스트를 한 번에 작성하여 시작하는 것이 좋습니다. 당신의 경험이 장기적으로 생산성을 향상 시킨다면 규칙 집에 대해 너무 걱정할 필요가 없습니다 :-)


4

TDD의 한 가지 패러다임은 단지 한 가지를 생각하는 것 외에도 테스트를 통과 할 수있는 최소 코드를 작성하는 것입니다. 한 번에 하나의 테스트를 작성하면 테스트를 통과하기에 충분한 코드를 작성하는 경로를 훨씬 쉽게 확인할 수 있습니다. 전체 테스트 세트를 통과하면 코드를 조금만 거치지 않고 한 번에 모두 통과 할 수 있도록 크게 도약해야합니다.

이제 코드를 모두 작성하여 "한 번에"전달하도록 제한하지 않고 한 번에 한 번의 테스트를 통과하기에 충분한 코드 만 작성해도 여전히 작동 할 수 있습니다. 그래도 필요한 것보다 더 많은 코드를 작성하는 것이 아니라 더 많은 훈련이 필요합니다. 당신이 그 길을 시작하면, 당신은 테스트 할 수있는 기술보다 더 많은 코드를 작성 개방 자신을두고 검증되지 않은 이상이 시험에 의해 아마 필요하지 않은 것을 의미에서 구동되지 않는 의미에서, 모든 테스트에 의해 (또는 운동).

주석, 스토리, 기능 사양 등 방법이 수행해야 할 작업을 완전히 이해하는 것은 허용됩니다. 그래도 한 번에 하나씩 테스트로 번역하기를 기다릴 것입니다.

한 번에 테스트를 작성하여 놓칠 수있는 또 다른 사항은 테스트를 통과하면 다른 테스트 사례를 생각하게하는 사고 과정입니다. 기존 테스트 뱅크가 없으면 마지막 테스트의 맥락에서 다음 테스트 사례를 고려해야합니다. 내가 말했듯이, 방법이 무엇을 해야하는지에 대한 좋은 아이디어를 얻는 것은 매우 좋지만, 여러 번 내가 선험적으로 고려하지 않았지만 글을 쓰는 과정에서만 발생했던 새로운 가능성을 발견했습니다. 테스트. 내가 아직 가지고 있지 않은 새로운 테스트를 작성할 수있는 습관을 가지지 않으면 이러한 것들을 놓칠 위험이 있습니다.


3

필자는 (실패한) 테스트를 작성한 개발자가 테스트를 통과하는 데 필요한 코드를 구현하는 개발자와 다른 프로젝트에서 작업했으며 실제로 효과적이라는 것을 알았습니다.

이 경우 현재 반복과 관련된 테스트 만 한 번 작성되었습니다. 그래서 당신이 제안하는 것은 그런 종류의 시나리오에서 완벽하게 가능합니다.


2
  • 그런 다음 한 번에 너무 많은 일에 집중하려고합니다.
  • 모든 테스트를 통과하도록 구현하는 동안 응용 프로그램의 작동 버전이 없습니다. 많은 것을 구현 해야하는 경우 오랫동안 작동하는 버전이 없습니다.

2

Red-Green-Refactor주기는 TDD를 처음 사용하는 개발자를위한 점검표입니다. 나는이 점검표를 따라야 할 때와 그것을 깨뜨릴 수있을 때까지 (즉, stackoverflow 에서이 질문을 할 필요가 없을 때까지)이 점검표를 따르는 것이 좋습니다.

10 년 가까이 TDD를 해본 결과, 프로덕션 코드를 작성하기 전에 실패한 테스트를 거의 작성하지 않는 경우가 거의 없습니다.


1

일부 외부 이해 관계자가 실행 가능한 스펙을 갖는 BDD를 설명하고 있습니다. 미리 정해진 사전 사양이있는 경우 (예 : 형식 사양, 산업 표준 또는 프로그래머가 도메인 전문가가 아닌 경우) 유용 할 수 있습니다.

그런 다음 일반적인 접근 방식은 점점 더 많은 수용 테스트를 점진적으로 다루는 것인데, 이는 프로젝트 관리자와 고객이 볼 수있는 진행 상황입니다.

일반적으로이 테스트는 Cucumber, Fitnesse 또는 이와 같은 BDD 프레임 워크에서 지정되고 실행됩니다.

그러나 이것은 단위 테스트와 혼합 된 것이 아니며 많은 API 관련 엣지 케이스, 초기화 문제 등 테스트 대상 항목에 중점을 둔 까다로운 구현 세부 사항에 훨씬 가깝습니다 . 이는 구현 아티팩트 입니다.

적녹 리 팩터 분야에는 많은 이점이 있으며, 미리 입력하여 기대할 수있는 유일한 장점은 짝수입니다.


1

한 번에 한 가지 테스트 : 주요 장점은 한 가지에 집중하는 것입니다. 깊이 우선 디자인 : 빠른 피드백 루프를 통해 깊이있게 집중할 수 있습니다. 그래도 전체 문제의 범위를 놓칠 수 있습니다! 리팩토링이 시작되는 순간입니다. 그것 없이는 TDD가 작동하지 않습니다.

모든 테스트 : 분석 및 설계를 통해 문제의 범위가 더 넓어 질 수 있습니다. 너비 우선 디자인을 생각하십시오. 더 많은 각도에서 문제를 분석하고 경험의 입력을 추가합니다. 본질적으로 어렵지만 '충분히'만하면 리팩토링이 적어 흥미로운 이점을 얻을 수 있습니다. 과도하게 분석하기는 쉽지만 마크를 완전히 놓치십시오.

경험 (특히 같은 문제가있는), 도메인 지식과 기술, 리팩토링을위한 코드의 친숙성, 문제의 복잡성 등 여러 요인이 많기 때문에 일반적으로 하나 또는 다른 것을 선호하는 것이 좋습니다.

우리가 일반적인 비즈니스 애플리케이션에 더 좁게 초점을 맞추면 빠른 시도 및 오류 접근 방식을 사용하는 TDD가 일반적으로 효과 측면에서 이길 것입니다.


1

테스트 프레임 워크에서 지원한다고 가정하면, 브레인 덤프하려는 테스트를 구현 하는 대신 나중에 구현할 설명 보류 테스트를 작성해야합니다. 예를 들어, API가 foo 및 bar를 수행하지만 biz는 수행하지 않아야하는 경우 테스트 스위트에 대해 다음 코드 (이 예제는 rspec에 있음)를 추가 한 후 하나씩 공격하십시오. 생각을 빠르게 내리고 모든 문제를 하나씩 해결할 수 있습니다. 모든 테스트를 통과하면 브레인 덤프 중에 발생한 모든 문제를 언제 해결했는지 알 수 있습니다.

describe "Your API" do

  it "should foo" do
    pending "braindump from 4/2"
  end

  it "should bar" do
    pending "braindump from 4/2"
  end

  it "should not biz" do
    pending "braindump from 4/2"
  end

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