왜 개발 중심 테스트 (DDT)가 아닌 테스트 중심 개발 (TDD)에 대해 민첩한가? 변경 될 가능성이 높은 초기 비용이 많이

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

이것이 내가 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가 생성하는 것처럼 보입니다.



답변

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

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

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

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

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

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

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

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

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


답변

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

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

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

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

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

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

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

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

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

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

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


답변

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

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

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

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

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

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

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

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

tl; dr

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

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

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


답변

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

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

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

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


답변

우선 선결제 비용은 생각보다 높지 않습니다 . 예, 테스트를하지 않는 것보다 테스트에 더 많은 시간을 할애합니다. 그러나 “테스트 후”방법을 사용하면 실제로 무엇을 낭비하고 있습니까? 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. 소비자와 함께 사양을 검토하고 필요한 경우 새 사양을 추가하십시오. 올바르게 수행하면 테스트를 전혀 변경할 필요가 없습니다. 새로운 것을 추가하십시오. 요구 사항 수집이 분리 될 수 있으며 이전 테스트와 충돌하는 테스트를 추가해야하지만 테스트를 거의 변경하지 않아도됩니다.

답변

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

세 가지 장점

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

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

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

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

비용 분석

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

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

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

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

외…

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


답변

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

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

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

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

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