테스트를 시작하기 위해 디자인이 필요한 경우 TDD가 좋은 디자인을 얻는 데 어떻게 도움이되는지 모르겠습니다. 많은 책들이 마술 토끼를 모자에서

TDD를 중심으로 머리를 감싸려고합니다. 특히 개발 부분입니다. 몇 가지 책을 보았지만 주로 찾은 책은 주로 테스트 부분-NUnit의 역사, 테스트가 좋은 이유, 빨강 / 녹색 / 리 팩터 및 문자열 계산기를 만드는 방법을 다룹니다.

좋은 점이지만 TDD가 아니라 “단지”단위 테스트입니다. 특히, 테스트를 시작하기 위해 디자인이 필요한 경우 TDD가 어떻게 좋은 디자인을 얻는 지 이해하지 못합니다.

설명하기 위해 다음 세 가지 요구 사항을 상상해보십시오.

  • 카탈로그에는 제품 목록이 있어야합니다.
  • 카탈로그는 사용자가 본 제품을 기억해야합니다
  • 사용자는 제품을 검색 할 수 있어야합니다

이 시점에서 많은 책들이 마술 토끼를 모자에서 꺼내어 “Testing the ProductService”로 뛰어 들지만, 처음에는 ProductService가 있다는 결론을 내린 방법에 대해서는 설명하지 않습니다. 그것이 제가 이해하려고하는 TDD의 “개발”부분입니다.

기존 디자인이 필요하지만 엔터티 서비스 외부의 항목 (즉, 제품이 있으므로 ProductService가 있어야 함)을 찾을 수 없습니다 (예 : 두 번째 요구 사항을 충족하려면 사용자, 그러나 어디에서 상기 기능을 상기시킬 것인가? 검색은 ProductService의 기능입니까 아니면 별도의 SearchService입니까? 어떻게 선택해야하는지 어떻게 알 수 있습니까?)

SOLID 에 따르면 UserService가 필요하지만 TDD가없는 시스템을 설계하면 수많은 단일 메소드 서비스가 생길 수 있습니다. TDD가 처음에 내 디자인을 발견하게하려는 것이 아닙니까?

저는 .net 개발자이지만 Java 리소스도 작동합니다. 실제 업무용 응용 프로그램을 다루는 실제 샘플 응용 프로그램이나 책이없는 것 같습니다. 누군가가 TDD를 사용하여 디자인을 만드는 과정을 보여주는 명확한 예를 제공 할 수 있습니까?



답변

TDD의 아이디어는 테스트로 시작하여 그로부터 작업하는 것입니다. 따라서 “카탈로그에 제품 목록이 있어야 함”의 예를 들어 보면 “카탈로그의 제품 확인”테스트가있는 것으로 볼 수 있으므로 이것이 첫 번째 테스트입니다. 이제 카탈로그는 무엇입니까? 제품은 무엇입니까? 이것들은 다음 조각이며 아이디어는 첫 번째 테스트를 통과하여 생성되는 ProductService와 같은 비트와 조각을 모으는 것입니다.

TDD의 아이디어는 테스트로 시작한 다음 테스트를 첫 번째 포인트로 통과시키는 코드를 작성하는 것입니다. 단위 테스트는이 부분의 일부이지만 테스트로 시작한 다음 코드를 작성하여 코드가 없기 때문에이 시점에서 사각 지대가 없도록 형성된 전체 그림을 보지 않습니다.


슬라이드 20-22가 핵심적인 테스트 중심 개발 튜토리얼 . 아이디어는 결과적으로 기능이 무엇을해야하는지 알고 테스트를 작성한 다음 솔루션을 구축하는 것입니다. 디자인 부분은 필요한 것이 무엇인지, 그렇지 않은지에 따라 달라집니다. 핵심은 프로젝트에 늦게 소개하지 않고 처음부터 TDD를 사용하는 것입니다. 테스트를 먼저 시작하면 도움이 될 수 있으며 의미가 있습니다. 나중에 테스트를 추가하려고 시도하면 연기되거나 지연 될 수 있습니다. 이후 슬라이드도 유용 할 수 있습니다.


TDD의 주요 이점은 테스트를 시작하여 처음에 설계에 구속되지 않는다는 것입니다. 따라서 아이디어는 테스트를 빌드하고 해당 테스트를 개발 방법론으로 통과시키는 코드를 작성하는 것입니다. 큰 디자인까지 전면 이 결국 덜 민첩로 구축되는 시스템을 만드는 장소로 물건을 잠금의 아이디어를 제공으로 문제가 발생할 수 있습니다.


Robert Harvey는 답변에 진술 할 가치가있는 의견에 이것을 추가했습니다.

불행히도 이것이 TDD에 대한 일반적인 오해라고 생각합니다.
단위 테스트를 작성하고 통과시켜 소프트웨어 아키텍처를 성장시킬 수는 없습니다. 단위 테스트를 작성하는 것은 디자인에 영향을 미칠 않지만, 그것은하지 않습니다 만드는 디자인. 그렇게해야합니다.


답변

그 가치에 대해 TDD는 TDD를 하지 않는 것보다 최고의 디자인을 더 빨리 만들 수 있도록 도와줍니다 . 나는 그것이 있거나없는 최고의 디자인에 올 것입니다. 그러나 그 생각을하고 코드에서 몇 가지 찌르기를하는 데 드는 시간은 대신 테스트를 작성하는 데 소비되었습니다. 그리고 더 적은 시간입니다. 나를 위해. 모두를위한 것은 아닙니다. 그리고 같은 시간이 걸리더라도 일련의 테스트가 필요하므로 리팩토링이 더 안전하여 더 나은 코드로 연결됩니다.

어떻게합니까?

먼저 모든 클래스를 클라이언트 코드에 대한 서비스로 생각하도록 장려합니다. 더 나은 코드는 코드 자체의 모양에 대해 걱정하기보다는 호출 코드가 API를 사용하기를 원하는 방식에 대한 생각에서 비롯됩니다.

둘째, 너무 많은 순환 적 복잡성을 하나의 방법으로 쓰는 것을 멈추고 생각합니다. 방법을 통한 각 추가 경로는 수행해야 할 테스트 수를 두 배로 늘리는 경향이 있습니다. 엄청나게 게으름은 너무 많은 논리를 추가 한 후 하나의 조건을 추가하기 위해 16 가지 테스트를 작성해야한다는 것을 나타냅니다. 이제 일부를 다른 메소드 / 클래스로 가져 와서 별도로 테스트해야합니다.

정말 간단합니다. 마법의 디자인 도구가 아닙니다.


답변

TDD 주위에 머리를 감 으려고 노력 중입니다 … 설명하기 위해 다음 세 가지 요구 사항을 상상해보십시오.

  • 카탈로그에는 제품 목록이 있어야합니다.
  • 카탈로그는 사용자가 본 제품을 기억해야합니다

이러한 요구 사항은 인간의 관점에서 재조정되어야합니다. 사용자가 이전에 본 제품을 누가 알고 싶어합니까? 사용자? 영업 사원?

  • 사용자는 제품을 검색 할 수 있어야합니다

어떻게? 이름으로? 브랜드별로? 테스트 중심 개발의 첫 단계는 다음과 같이 테스트를 정의하는 것입니다.

browse to http://ourcompany.com
enter "cookie" in the product search box
page should show "chocolate-chip cookies" and "oatmeal cookies"

>

이 시점에서 많은 책들이 마술 토끼를 모자에서 꺼내어 “Testing the ProductService”로 뛰어 들지만, 처음에는 ProductService가 있다는 결론을 내린 방법에 대해서는 설명하지 않습니다.

이것이 유일한 요구 사항이라면 확실히 ProductService를 만들지 않을 것입니다. 정적 제품 목록으로 매우 간단한 웹 페이지를 만들 수 있습니다. 제품 추가 및 삭제 요구 사항에 도달 할 때까지 완벽하게 작동합니다. 이 시점에서 관계형 데이터베이스와 ORM을 사용하는 것이 가장 간단하다고 판단하고 단일 테이블에 매핑 된 Product 클래스를 만들 수 있습니다. 여전히 ProductService가 없습니다. 필요할 때 언제 필요한지 ProductService와 같은 클래스가 작성됩니다. 동일한 쿼리 또는 업데이트를 수행해야하는 웹 요청이 여러 개있을 수 있습니다. 그런 다음 코드 복제를 방지하기 위해 ProductService 클래스가 작성됩니다.

요약하면 TDD는 코드를 작성합니다. 구현을 선택할 때 디자인이 발생하고 코드를 클래스로 리팩토링하여 중복 및 제어 종속성을 제거합니다. 코드를 추가 할 때 코드 SOLID를 유지하려면 새 클래스를 작성해야합니다. 그러나 Product 클래스와 ProductService 클래스가 필요하다는 것을 미리 결정할 필요는 없습니다. Product 클래스만으로도 인생은 완벽하게 훌륭하다는 것을 알 수 있습니다.


답변

다른 사람들은 동의하지 않을 수도 있지만, 나에게 많은 새로운 방법론은 개발자가 습관이나 개인적인 자부심으로 구식 방법론에서 설명한 대부분의 작업을 개발자가 수행한다는 가정에 의존합니다. 그들에게 작업이 포함되어 있으며, 작업은 깨끗한 언어 또는 다소 지저분한 언어의 깨끗한 부분으로 캡슐화되어 있으므로 모든 테스트 비즈니스를 수행 할 수 있습니다.

과거에 이것을 경험 한 몇 가지 예 :

  • 많은 스펙 작업 계약자를 가지고 팀이 민첩하고 테스트 우선이라고 말합니다. 그들은 종종 사양 작업 이외의 습관이 없으며 프로젝트를 완료하기에 오래 지속되는 한 작업의 품질에 대해 걱정하지 않습니다.

  • 새로운 테스트를 먼저 시도하고 수행하십시오. 다양한 접근 방식과 인터페이스가 잘못되어 테스트를 추출하는 데 많은 시간을 소비하십시오.

  • 낮은 수준의 코드를 작성하고 적용 범위가 부족하여 엉망이되거나 묶는 기본 동작을 조롱 할 수 없기 때문에 많은 가치가없는 많은 테스트를 작성하십시오.

  • 디스크 하위 시스템이나 tcpip 레벨 통신 인터페이스와 같이 테스트 할 수없는 여러 가지 비트를 먼저 작성하지 않고 테스트 가능한 기능을 추가 할 시간이 충분하지 않은 상황입니다.

당신이 TDD를하고 있고 당신을 위해 일하고 있다면, 당신에게 좋지만, 단순히 가치를 추가하지 않는 많은 일 (전체 작업 또는 프로젝트 단계)이 있습니다.

귀하의 예제는 아직 설계를하고 있지 않은 것처럼 들리므로 아키텍처 대화가 필요하거나 프로토 타이핑 중입니다. 내 의견으로는 먼저 그 중 일부를 통과해야합니다.


답변

나는 TDD가 시스템 의 세부적인 디자인, 즉 API와 객체 모델에 매우 귀중한 접근법이라고 확신한다 . 그러나 TDD를 사용하기 시작하는 프로젝트에서 요점을 찾으려면 디자인의 큰 그림이 어떤 방식으로 이미 모델링되어 있어야하고 아키텍처의 큰 그림이 이미 어떤 방식으로 모델링되어 있어야합니다. 로버트 마틴 (Robert Martin)은 @ user414076의 말을 디자인 아이디어를 염두에두고 결혼하지는 않았다. 바로 그거죠. 결론-TDD는 진행중인 유일한 디자인 활동이 아니라 디자인의 세부 사항이 완성되는 방식입니다. TDD에는 다른 설계 활동이 선행되어야하며 전체 설계가 생성되고 발전되는 방식을 다루는 전체 접근 방식 (예 : 애자일)에 적합해야합니다.

참고로-실용적이고 현실적인 예를 제공하는 주제에 대해 추천하는 두 권의 책 :

테스트 가이드에 따라 성장하는 객체 지향 소프트웨어 -전체 프로젝트 예제를 설명하고 제공합니다. 이 책은 테스트가 아니라 디자인에 관한 책 입니다. 테스트는 디자인 활동 중 예상되는 동작을 지정하는 수단으로 사용됩니다.

테스트 중심 개발 실용 가이드 -비록 작지만 완전한 앱을 개발하는 단계를 천천히 그리고 단계별로 안내 합니다.


답변

TTD는 성공이 아닌 테스트 실패로 설계 발견을 주도합니다. 따라서 미지의 요소가 노출 될 때 미지의 요소를 테스트하고 반복적으로 다시 테스트 할 수 있습니다. 코드 작성 / 해제 후 개조

예를 들어, 입력이 몇 가지 다른 형식 일 수 있지만 모든 것이 아직 알려진 것은 아니라는 요구 사항이있을 수 있습니다. 먼저 적절한 출력이 제공되어 공급되는 검증 테스트 작성합니다 TDD를 사용하여 모든 입력 형식을. 분명히이 테스트는 실패하므로 알려진 형식을 처리하고 다시 테스트하는 코드를 작성하십시오. 알 수없는 형식은 요구 사항 수집을 통해 노출 되므로 코드를 작성 하기 전에 새로운 테스트가 작성 되므로 실패해야합니다. 그런 다음 새 형식을 지원하기 위해 새 코드가 작성되고 모든 테스트가 다시 실행되어 회귀 가능성이 줄어 듭니다.

또한 장치 고장을 “깨진”코드 대신 “완료되지 않은”코드로 생각하면 도움이됩니다. TDD는 완료되지 않은 장치 (예상 실패)를 허용하지만 깨진 장치 (예기치 않은 실패)의 발생을 줄입니다.


답변

질문에는 다음과 같이 명시되어 있습니다.

… 많은 책들이 마술 토끼를 모자에서 꺼내어 “Testing the ProductService”로 뛰어 들지만, 처음에는 ProductService가 있다는 결론에 도달 한 방법을 설명하지 않습니다.

그들은이 제품을 어떻게 테스트 할 것인지 생각함으로써 결론에 도달했습니다. “어떤 종류의 제품입니까?” “우리는 서비스를 만들 수 있습니다.” “좋아, 그런 서비스에 대한 테스트를 작성하자”