TDD를 사용하여 초기 API를 얻는 방법?


12

내가 TDD를 처음 시도 할 때 이것은 다소 어리석은 질문 일 수 있습니다. 나는 그것이 가져 오는 자신감과 일반적으로 내 코드의 더 나은 구조를 좋아했지만 한 클래스 장난감 예제보다 큰 것에 적용하기 시작했을 때 어려움에 빠졌습니다.

일종의 라이브러리를 작성한다고 가정하십시오. 해야 할 일을 알고 있으며, 구현 방식에 대한 일반적인 방법을 알고 있지만 (아키텍처 방식), 코딩 할 때 공개 API를 변경해야한다는 것을 "발견"합니다. 아마도이 개인 메소드를 전략 패턴으로 변환해야하고 (이제 테스트에서 모의 ​​전략을 전달해야 함) 아마도 여기저기서 책임을 놓치고 기존 클래스를 분할했을 것입니다.

기존 코드를 개선 할 때는 TDD가 적합하지만, 처음부터 모든 것을 작성할 때 테스트를 작성하는 API는 큰 디자인을하지 않으면 약간 "흐리게"나타납니다. 서명 (및 해당 부분의 동작)이 변경된 메소드에 대해 이미 30 개의 테스트를 수행 한 경우 어떻게합니까? 그것이 합쳐지면 많은 테스트가 필요합니다.


3
한 가지 방법으로 30 번의 테스트? 그 방법은 너무 복잡하거나 너무 많은 테스트를 작성하고 있습니다.
Minthos

글쎄, 내 요점을 표현하기 위해 조금 과장했을 수도 있습니다. 코드를 확인한 후에는 일반적으로 테스트 당 10 개 미만의 메서드를 사용합니다. 대부분의 메서드는 5 미만입니다. 그러나 "돌아가고 수동으로 변경"하는 부분은 상당히 실망 스러웠습니다.
Vytautas Mackonis

6
@ Minthos : 문자열을 사용하는 모든 메소드가 첫 번째 초안 쓰기에서 실패하거나 성능이 저하된다고 생각하는 6 가지 테스트를 생각할 수 있습니다 (널, 비어 있거나 너무 길거나 제대로 현지화되지 않았거나 성능이 좋지 않습니다) . 컬렉션을 가져 오는 메소드와 유사합니다. 사소하지 않은 방법의 경우 30은 큰 소리로 들리지만 너무 비현실적인 것은 아닙니다.
Steven Evers

답변:


13

당신은 무엇을 호출 "앞까지 큰 디자인" 내가 전화 "클래스 구조의 합리적인 계획을."

단위 테스트에서 아키텍처를 확장 할 수 없습니다. 밥 아저씨 도 그렇게 말합니다.

건축을 생각하지 않는다면 건축을 무시하고 테스트를 함께 던지고 통과시키는 것이 건물에 집중되어 있기 때문에 건물을 유지할 수있는 것을 파괴하는 것입니다. 시스템의 구조 및 시스템의 구조적 무결성을 유지하는 데 도움이되는 견고한 설계 결정.

http://s3.amazonaws.com/hanselminutes/hanselminutes_0171.pdf , 페이지 4

구조 설계 를 검증 한다는 관점에서 TDD에 접근하는 것이 더 합리적이라고 생각합니다 . 테스트하지 않으면 디자인이 잘못되었다는 것을 어떻게 알 수 있습니까? 원래 테스트도 변경하지 않고 변경 사항이 올바른지 어떻게 확인합니까?

소프트웨어는 변경 될 수 있으므로 정확하게 "부드럽습니다". 변경 에 대해 불편한 경우 아키텍처 설계에 대한 경험을 계속 얻으십시오. 따라서 애플리케이션 아키텍처에 대한 변경 횟수는 시간이 지남에 따라 줄어 듭니다.


중요한 것은 "현명한 계획"이라하더라도 계획이 많이 변경 될 것으로 예상한다는 것입니다. 나는 보통 초기 아키텍처의 약 80 %를 약간의 변화로 그대로 둡니다. 그 20 %가 나를 괴롭히는 것입니다.
Vytautas Mackonis

2
소프트웨어 개발의 본질이라고 생각합니다. 첫 번째 시도에서 전체 아키텍처를 얻을 수는 없습니다.
Robert Harvey

2
+1이며 TDD에 대응하지 않습니다. TDD는 코드 작성을 시작할 때, 디자인이 끝나면 정확하게 시작됩니다. TDD를 사용하면 설계에서 누락 된 사항을 파악하여 설계 및 구현을 리팩터링하고 계속 진행할 수 있습니다.
Steven Evers

2
실제로 Bob에 따르면 (그리고 나는 전적으로 그를 동의합니다) 코드 작성은 디자인입니다. 높은 수준의 아키텍처가 반드시 필요하지만 코드를 작성할 때 디자인이 끝나지 않습니다.
Michael Brown

머리에 못을 치는 정말 좋은 대답입니다. 나는 TDD에 대해 너무나 많은 사람들을 보았습니다. TDD에 대해 반대하는 사람들은 실제로 오래된 폭포 디자인 단계에 맞지 않을 때 "전혀 디자인하지 않고 코드 만 작성"하는 것처럼 보입니다. 디자인은 항상 좋은 시간 투자이며 사소한 프로젝트의 성공에 결정적입니다.
sara

3

당신이 TDD를하는 경우. 테스트로 구동하지 않으면 서명과 동작을 변경할 수 없습니다. 따라서 실패한 30 개의 테스트는 프로세스에서 삭제되거나 코드와 함께 변경 / 리팩토링되었습니다. 또는 이제 쓸모없고 삭제해도 안전합니다.

적색-녹색 리 팩터 사이클에서 30 배 적색을 무시할 수 없습니까?

테스트는 프로덕션 코드와 함께 리팩터링해야합니다. 여유가 있다면 각 변경 후 모든 테스트를 다시 실행하십시오.

TDD 테스트를 삭제하는 것을 두려워하지 마십시오. 일부 테스트는 원하는 결과를 얻기 위해 빌딩 블록을 테스트합니다. 기능적 수준에서 원하는 결과는 중요합니다. 선택 / 발명 한 알고리즘의 중간 단계에 대한 테스트는 결과에 도달 할 수있는 방법이 하나 이상 있거나 처음 막 다른 길에 섰을 때 큰 가치가 있거나 그렇지 않을 수 있습니다.

때로는 적절한 통합 테스트를 작성하고 유지하고 나머지는 삭제할 수 있습니다. 그것은 당신이 밖으로 일하든 아래로 일하든, 얼마나 큰 걸음을 밟는가에 달려 있습니다.


1

Robert Harvey가 방금 말했듯이 다른 개념 도구 ( "디자인"또는 "모델링")로 처리해야하는 대상에 TDD를 사용하려고했을 것입니다.

시스템을 상당히 추상적 인 ( "일반적인", "모호한") 방식으로 디자인 (또는 "모델")하십시오. 예를 들어 자동차를 모델링해야하는 경우 startEngine () 및 int 좌석과 같이 모호한 메서드와 필드가있는 자동차 클래스 만 있으면됩니다. 즉 , 구현하려는 방식이 아니라 대중에게 노출하려는 것을 설명 하십시오. 기본 기능 (읽기, 쓰기, 시작, 중지 등) 만 노출하고 클라이언트 코드를 정교하게 남겨 두십시오 (prepareMyScene (), killTheEnemy () 등).

이 간단한 공용 인터페이스를 가정하여 테스트를 작성하십시오.

필요할 때마다 클래스와 메서드의 내부 동작을 변경하십시오.

공개 인터페이스와 테스트 스위트를 변경해야하는 경우 중지하고 생각하십시오. 이것은 아마도 API와 디자인 / 모델링에 문제가 있음을 나타냅니다.

API를 변경하는 것은 드문 일이 아닙니다. 1.0 버전의 대부분의 시스템은 프로그래머 / 사용자에게 API 변경 가능성에 대해 명시 적으로 경고합니다. 그럼에도 불구하고 지속적으로 통제되지 않은 API 변경 흐름은 잘못된 (또는 완전히 누락 된) 디자인의 명백한 징후입니다.

BTW : 일반적으로 방법 당 몇 가지 테스트 만 수행하면됩니다. 정의에 따라 방법은 어떤 종류의 데이터에 대해 명확하게 정의 된 "조치"를 구현해야합니다. 완벽한 세계에서 이것은 단일 테스트에 해당하는 단일 조치 여야합니다. 현실 세계에서 동일한 행동의 다른 "버전"과 그에 상응하는 다른 테스트가 거의없는 것은 드문 일이 아닙니다. 같은 방법으로 30 번의 테스트를 피해야합니다. 이것은 방법이 너무 많은 것을 시도하고 내부 코드가 제어 할 수 없다는 명확한 신호입니다.


0

나는 그것을 사용자 관점에서 본다. 예를 들어, API를 사용하여 이름과 나이를 사용하여 Person 객체를 만들 수 있다면 이름과 나이에 대한 Person (string name, int age) 생성자 및 접근 자 메서드가 더 좋습니다. 이름과 나이가 있거나없는 새로운 사람에 대한 테스트 사례를 작성하는 것은 간단합니다.

더그

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