단위 테스트가 너무 많습니까?


139

기존 응용 프로그램에 대한 단위 테스트 작성을 맡았습니다. 첫 번째 파일을 완성한 후 419 줄의 원본 코드에 대한 717 줄의 테스트 코드가 있습니다.

코드 범위를 늘리면이 비율을 관리하기 어려워 집니까?

단위 테스트에 대한 나의 이해는 모든 방법이 예상대로 작동하는지 클래스의 각 방법을 테스트하는 것이 었습니다. 그러나 풀 요청에서 기술 책임자는 더 높은 수준의 테스트에 집중해야한다고 언급했습니다. 그는 각 기능을 철저히 테스트하기보다는 문제의 클래스에 가장 일반적으로 사용되는 4-5 개의 사용 사례를 테스트하도록 제안했습니다.

기술 책임자의 의견을 신뢰합니다. 그는 나보다 더 많은 경험을 가지고 있으며, 소프트웨어 설계와 관련하여 본능이 뛰어납니다. 그러나 여러 사람으로 구성된 팀은 그러한 모호한 표준에 대한 테스트를 어떻게 작성합니까? 즉, 동료를 어떻게 알 수 있으며 "가장 일반적인 사용 사례"에 대해 동일한 아이디어를 공유합니까?

나에게 100 % 단위 테스트 범위는 높은 목표이지만, 50 %에 도달하더라도 그 50 %의 100 %가 보장된다는 것을 알게 될 것입니다. 그렇지 않으면, 각 파일의 일부에 대한 테스트를 작성하면 부정 할 여지가 많이 남습니다.


145
따라 다릅니다. 틱택 토 게임을 작성 중입니까, 아니면 원자로 관리를위한 코드를 작성 중입니까?
Bryan Oakley

11
충분히 많은 단위 테스트를 사용하면 펜티엄 FDIV 버그 또는 암호화 기본 요소의 상관 관계 와 같은 이국적인 하드웨어 구현 문제를 감지 할 수 있으므로 더 이상 단위 테스트가 유용하지 않은 하드 한계가없는 것처럼 보입니다. 너무 비싸면 실질적인 한계입니다.
Nat

5
더 높은 수준에서 테스트하면 실제 적용 범위를 더 잘 볼 수 있습니다. 실제 적용 범위에서는 시스템을 정기적으로 사용하는 동안 발생할 가능성이 더 큽니다. 그것이 당신이 먼저 달성하고자하는 종류입니다. 마지막으로 도달 한 50 %에서 YAGNI 또는 데드 코드가 한 번 제거되면 전체 적용 범위도 증가 할 수 있습니다.
Laiv

5
테스트를 너무 많이 받으면 (현재는 보이지 않는 것 같습니다) 가장 큰 문제는 테스트중인 코드가 너무 많은 것입니다. 따라서 단일 책임은 준수되지 않습니다. 코드가 잘 분할되면 테스트에도 많은 부담이 발생하지 않습니다. 수업이 많고 부작용이 많으면 악몽이 될 것입니다.
Luc Franken

12
: SQLite는 시험 문서는 재미를 읽을 sqlite.org/testing.html을 . 인용문 : "SQLite 라이브러리는 약 122.9 KSLOC의 C 코드로 구성되어 있습니다. 비교하면 프로젝트의 테스트 코드 및 테스트 스크립트는 745 배입니다-91596.1 KSLOC."
user60561

답변:


180

예, 100 % 적용 범위를 사용하면 필요하지 않은 테스트를 작성할 수 있습니다. 불행히도, 어떤 테스트가 필요하지 않은지를 결정하는 유일한 확실한 방법은 모든 테스트를 작성한 다음 10 년 정도 기다렸다가 실패하지 않은 테스트를 보는 것입니다.

많은 테스트를 유지하는 것은 일반적으로 문제가되지 않습니다. 많은 팀이 100 % 단위 테스트 범위에서 자동화 된 통합 및 시스템 테스트를 수행했습니다.

그러나 테스트 유지 보수 단계에 있지 않고 따라 잡는 중입니다. 100 % 테스트 범위의 클래스의 50 %보다 50 % 테스트 범위의 클래스를 100 % 보유하는 것이 훨씬 낫습니다. 해당 기준을 설정 한 후 다음 단계는 일반적으로 앞으로 변경되는 파일을 100 % 추진하는 것입니다.


11
답변 주셔서 감사합니다. 그것은 내 질문에 대한 관점을 제시하고 실제 문제, 내 태도를 다루는 데 도움이되었습니다! +1
user2954463

43
@astra 당신의 태도는 그렇게 나쁘지 않습니다. 왜 그런지 질문하는 것이 좋습니다. 당신의 다른 질문에 대한 훌륭한 질문에 대답하기 위해 : "어떻게 동료들을 알 수 있고"가장 일반적인 사용 사례 "에 대해 같은 아이디어를 공유합니까? 테스트를 보도록하십시오. 테스트를 보거나 그들에 대해 이야기하십시오. 배우게 될 것입니다. 테스트를 검토하는 코드는 시간 낭비가 거의되지 않지만 회의실이 아닌 터미널에서 채굴하는 경향이 있지만
candied_orange

18
10 년 동안 실패한 테스트는 그것이 불필요하다고 보장하지도 않고 11
후에

24
실용적으로 반대의 접근 방식을 취할 수 있습니다. 일반적인 경우를 다루는 테스트를 작성하십시오. 그러나 장애가 발생할 때마다 해당 영역을 다루는 테스트를 작성하십시오.
stannius

10
@Pharap이 답변의 유일한 문제는 테스트가 실패 할 때만 가치를 추가 할 수 있다는 암시 적 가정이 있다는 것입니다. 좋은 단위 테스트는 또한 훌륭한 형태의 살아있는 문서를 제공합니다. 또한 테스트를 작성할 때 재사용 성 / 구성 성 / 캡슐화에 대해 생각하도록하여 가치를 추가했습니다. 내 경험에서 테스트되지 않은 코드는 융통성이없는 모 놀리 식 인 경향이 있습니다.
ArTs

66

Test Driven Development를 사용하여 생성 된 대규모 코드 기반에서 작업 한 경우 너무 많은 단위 테스트가있을 수 있다는 것을 이미 알고있을 것입니다. 경우에 따라 대부분의 개발 노력은 런타임에 관련 클래스에서 불변, 사전 조건 및 사후 조건 확인으로 가장 잘 구현되는 저품질 테스트를 업데이트하는 것으로 구성됩니다 (즉, 상위 레벨 테스트의 부작용으로 테스트). ).

또 다른 문제는화물 컬트 기반 설계 기술을 사용하여 테스트 품질이 떨어지는 (디자인, 클래스, 인터페이스 등) 품질이 떨어지는 설계를 만드는 것입니다. 이 경우 부담이 테스트 코드를 업데이트하는 것처럼 보이지만 실제 문제는 품질이 좋지 않은 디자인입니다.


16
사전 조건, 사후 조건 및 불변량을 지적하도록 찬성하여 단위 테스트로 처리해야합니다. 그렇게하면 디버그 코드가 활성화 될 때마다 모든 사용이 단위 테스트입니다.
Persixty

이것은 훌륭한 답변이며 내 경험과 완벽하게 일치합니다.
Tony Ennis

그리고 한 가지 더 문제 : 품질이 낮은 체크인을 처리 한 경우 (실제로해야합니다!) 장기간 실행되는 테스트라도 실질적인 이점을 제공하지 않으면 서 모든 것이 느려질 수 있습니다. 그리고 분명히 수업에서 한 가지를 바꾸고 수백 가지 테스트를 수행하는 재미있는 사실이 실패합니다.
Voo

3
이것은 허용되는 것보다 훨씬 더 나은 대답입니다! "경우에 따라 대부분의 개발 노력은 저품질 테스트 업데이트로 구성됩니다." 어떤면에서 테스트를 전혀하지 않는 것 이상.
벤자민 호지 슨

36

질문에 대한 답변

단위 테스트가 너무 많습니까?

물론 ... 예를 들어 언뜻보기에는 여러 가지 테스트가있을 수 있지만 실제로는 같은 것을 테스트 할 수 있습니다 (논리적으로 테스트중인 동일한 "관심있는"응용 프로그램 코드 행에 따라 다름).

또는 코드 외부에서 절대로 드러나지 않는 (즉, 모든 종류의 인터페이스 계약에 속하지 않는) 코드 내부를 테스트 할 수 있습니다. 예를 들어 내부 로그 메시지의 정확한 표현 등

기존 응용 프로그램에 대한 단위 테스트 작성을 맡았습니다. 첫 번째 파일을 완성한 후 419 줄의 원본 코드에 대한 717 줄의 테스트 코드가 있습니다.

그것은 매우 평범한 일입니다. 테스트는 실제 테스트에서 설정 및 해제에 많은 코드를 사용합니다. 비율은 향상되거나 향상되지 않을 수 있습니다. 나 자신은 꽤 무거운 테스트이며 종종 실제 코드보다 테스트에 더 많은 장소와 시간을 투자합니다.

코드 범위를 늘리면이 비율을 관리하기 어려워 집니까?

비율은 그다지 중요하지 않습니다. 관리 할 수없는 다른 테스트 품질이 있습니다. 코드에서 간단한 변경을 수행 할 때 정기적으로 전체 테스트를 리팩토링해야하는 경우 이유를 잘 살펴 봐야합니다. 그리고 그것들은 몇 줄이 아니라 테스트 코딩에 접근 하는가입니다.

단위 테스트에 대한 나의 이해는 모든 방법이 예상대로 작동하는지 클래스의 각 방법을 테스트하는 것이 었습니다.

엄격한 의미에서 "단위"테스트에 맞습니다. 여기서 "단위"는 메소드 나 클래스와 같은 것입니다. "단위"테스트의 요점은 전체 시스템이 아니라 하나의 특정 코드 단위 만 테스트하는 것입니다. 이상적으로는 시스템의 나머지 부분을 모두 제거합니다 (복식 또는 기타).

그러나 풀 요청에서 기술 책임자는 더 높은 수준의 테스트에 집중해야한다고 언급했습니다.

그럼 당신은 사람들에게 실제로 가정의 함정에 빠진 의미 가 때 단위 테스트를 말했다 단위 테스트. 나는 "단위 테스트"라고 말하는 많은 프로그래머들을 만났지만 상당히 다른 것을 의미합니다.

그는 각 기능을 철저히 테스트하기보다는 문제의 클래스에 가장 일반적으로 사용되는 4-5 개의 사용 사례를 테스트하도록 제안했습니다.

물론, 중요한 코드의 상위 80 %에 집중하면 부하도 줄어 듭니다 ... 당신은 당신의 상사를 높이 평가한다고 생각하지만, 이것이 최선의 선택이라고 생각하지는 않습니다.

나에게 100 % 단위 테스트 범위는 높은 목표이지만, 50 %에 도달하더라도 그 50 %의 100 %가 보장된다는 것을 알게 될 것입니다.

"단위 테스트 범위"가 무엇인지 모르겠습니다. 테스트 코드를 실행 한 후 모든 코드 줄 (= 100 %)이 적어도 한 번 실행 된 "코드 적용 범위"를 의미한다고 가정합니다.

이것은 훌륭한 야구장 측정법이지만, 최고의 표준은 아닙니다. 코드 라인을 실행하는 것이 전체 그림이 아닙니다. 예를 들어 복잡하고 중첩 된 분기를 통한 다른 경로를 설명하지는 않습니다. 너무 적은 테스트를 거친 코드 조각을 손가락으로 향하게하는 것이 더 많은 메트릭스입니다 (분명히 10 % 또는 5 %의 코드 적용 범위 인 클래스는 잘못된 것임). 반면 100 % 적용 범위는 충분히 테스트했는지 또는 올바르게 테스트했는지를 알려주지 않습니다.

통합 테스트

오늘날 사람들이 기본적으로 단위 테스트 에 대해 끊임없이 이야기 할 때 상당히 짜증납니다 . 내 의견으로는 (그리고 경험), 단위 테스팅은 라이브러리 / API에 좋습니다; 보다 비즈니스 지향적 인 영역 (우리가 문제의 사례와 같은 사용 사례에 대해 이야기하는 영역)에서 반드시 최선의 선택은 아닙니다.

일반적인 응용 프로그램 코드 및 일반 비즈니스 (돈을 벌고 마감 시한을 맞추고 고객 만족을 충족시키는 것이 중요하며 주로 사용자의 얼굴에 있거나 실제 재해로 이어질 수있는 버그를 피하려고합니다) NASA 로켓 발사에 대해 이야기하면 통합 또는 기능 테스트가 훨씬 유용합니다.

이들은 행동 주도 개발 또는 기능 주도 개발과 밀접한 관련이 있습니다. 그것들은 정의에 따라 (엄격한) 단위 테스트와 함께 작동하지 않습니다.

이를 짧게 유지하기 위해 통합 / 기능 테스트는 전체 애플리케이션 스택을 연습합니다. 웹 기반 응용 프로그램에서는 응용 프로그램을 클릭하는 브라우저처럼 작동합니다 (물론 간단 하지 않아도 됩니다. 그렇게 할 수있는 매우 강력한 프레임 워크가 있습니다 -http : // cucumber를 확인하십시오) . 예를 들어 io ).

마지막 질문에 대답하기 위해 : 기능 테스트가 구현되고 실패한 후에 만 ​​새 기능이 프로그래밍되도록하여 전체 팀이 높은 테스트 범위를 갖도록합니다. 그리고 네, 그것은 모든 기능 을 의미 합니다. 이 보장 당신에게 100 % (긍정적) 기능의 범위를. 정의에 따르면 응용 프로그램의 기능이 절대로 "이탈"하지 않습니다. 100 % 코드 적용 범위를 보장하지는 않습니다 (예를 들어, 부정적인 기능을 적극적으로 프로그래밍하지 않으면 오류 처리 / 예외 처리를하지 않습니다).

버그가없는 응용 프로그램을 보장하지는 않습니다. 물론 명백하거나 매우 위험한 버그 상황, 잘못된 사용자 입력, 해킹 (예 : 주변 세션 관리, 보안 등)에 대한 기능 테스트를 작성하려고합니다. 그러나 포지티브 테스트를 프로그래밍하는 것만으로도 엄청난 이점이 있으며 현대적이고 강력한 프레임 워크를 통해 실현 가능합니다.

기능 / 통합 테스트에는 분명히 자체 웜 캔이 있습니다 (예 : 성능, 타사 프레임 워크의 중복 테스트; 일반적으로 더블을 사용하지 않기 때문에 내 경험상 쓰기가 더 어려워지는 경향이 있습니다 ...) d 매일 100 % 코드 커버리지 단위 테스트 응용 프로그램 (라이브러리가 아님)에 대해 100 % 긍정적 기능 테스트 응용 프로그램을 가져옵니다.


1
통합 테스트는 훌륭하지만 단위 테스트를 대체하지 않으며 비즈니스 응용 프로그램을 대체하지도 않습니다. a) 정의에 따라 실행하는 데 시간이 오래 걸립니다 (증분 테스트는 거의 쓸모가 없음을 의미합니다). 어떤 변화가 그 원인입니까?)와 c) 동일한 코드 경로를 반복적으로 포괄합니다.
Voo

1
a) 게이트 체크 인에서 테스트를 실행하는 것이 번거롭고 프로그래머가 개발하는 동안 테스트를 반복적으로 실행할 가능성이 낮아지기 때문에 효율성이 떨어지고 버그를 신속하게 진단하는 능력이 떨어집니다. c) 하나의 작은 것을 변경하면 수십 또는 수백 개의 통합 테스트가 쉽게 실패 할 수 있으며이를 수정하는 데 많은 시간을 소비하게됩니다. 이는 통합 테스트가 대부분 행복한 경로 만 테스트한다는 것을 의미합니다. 이러한 테스트를 대상으로 작성하는 것이 번거 롭거나 불가능하기 때문입니다.
Voo

1
@Voo, 당신이 쓴 모든 것은 사실이며, 내가 대답 할 수있는 한, 대답에서 언급 한 모든 문제를 이미 언급했습니다 ...
AnoE

이 요약에 동의하면 단위 테스트보다 통합 테스트를 선호한다는 결론에 도달 할 수 없습니다. 대규모 프로그램의 포괄적 인 통합 테스트 스위트는 실행하는 데 몇 시간 또는 며칠이 걸리지 만 실제로 개발하는 데는 유용하지만 거의 쓸모가 없습니다. 그리고 승인 테스트 (모두가하고있는 것입니까?)는 단위 테스트에서 놓칠 수있는 통합 테스트에서 발견 한 것과 동일한 많은 문제를 포착합니다. 그러나 그 반대는 사실이 아닙니다.
Voo

24

예, 단위 테스트가 너무 많을 수 있습니다. 예를 들어 단위 테스트를 100 % 포함하고 통합 테스트를 수행하지 않으면 명확한 문제가있는 것입니다.

일부 시나리오 :

  1. 테스트를 특정 구현으로 오버 엔지니어링합니다. 그런 다음 리팩토링 할 때 단위 테스트를 포기해야합니다. 구현을 변경할 때는 말할 것도 없습니다 (성능 최적화를 수행 할 때 매우 빈번한 문제점).

    단위 테스트와 통합 테스트 사이의 균형이 좋으면 상당한 적용 범위를 잃지 않으면 서이 문제가 줄어 듭니다.

  2. 보유하고있는 테스트의 20 %로 모든 커밋에 대해 적절한 적용 범위를 가질 수 있으며 나머지 80 %는 통합 또는 적어도 별도의 테스트 패스로 남겨 둡니다. 이 시나리오에서 볼 수있는 주요 부정적인 영향은 테스트 실행을 위해 오랜 시간을 기다려야하는 느린 변경입니다.

  3. 코드를 너무 많이 수정하여 테스트 할 수 없습니다. 예를 들어, 수정이 필요하지 않은 컴포넌트에 대해 IoC를 많이 남용하거나 최소한 일반화하는 데 비용이 많이 들고 우선 순위가 낮지 만 사람들은 단위 테스트를 허용하기 위해 일반화하고 리팩토링하는 데 많은 시간을 투자합니다. .

특히 파일의 50 %에 대한 100 % 적용 대신 100 % 파일에 대한 적용 범위 제안에 동의합니다. 가장 일반적인 긍정적 인 사례와 가장 위험한 부정적인 사례에 초기 노력을 집중하십시오. 오류 처리 및 비정상적인 경로에 너무 많은 투자를하지 마십시오. 중요하지 않은 것이 아니라 제한된 시간과 무한한 테스트 환경이 있기 때문입니다. 모든 경우에 우선 순위를 정해야합니다.


2
이는 단위 테스트에는 문제가 아니지만 다른 수준에서 적절한 테스트를 작성하고 실행하기 위해 자원을 소비하지 않고 단위 테스트 범위에 대해 특정 번호를 요구하여 우선 순위가 잘못된 조직에 문제가 있습니다.
jwenting

2
# 3에 강력히 동의하고 하위 클래스의 인스턴스를 상위 클래스로 수동 전달하도록 확장하십시오. 높은 수준의 일이 무언가를 달성하기 위해 일부 낮은 수준의 일에 의존한다면 괜찮습니다. 발신자의 세부 사항을 숨기면 좋은 디자인이라고 부릅니다. 그러나 높은 수준의 인터페이스의 일부를 낮은 수준의 인터페이스로 만들고 호출자가 테스트를 예쁘게 만들기 때문에 그것을 통과 시키면 꼬리가 개를 흔들고 있습니다. (낮은 수준의 일이 많은 곳에서 재사용되고 많이 바뀌면 상황이 바뀝니다. 제 경험으로는 일반적이지 않은 경험이 있습니다.)
johncip

@johncip의 설명이 마음에 듭니다. 이는 생성자에게 불필요한 필수 매개 변수를 추가하여 멋진 클래스가 얼마나 끔찍한지를 보여주는 빈번한 예입니다.
Bruno Guardia

19

각 테스트에는 비용뿐만 아니라 이점도 있습니다. 단점은 다음과 같습니다.

  • 시험을 작성해야합니다.
  • 테스트는 (보통 아주 소량) 실행하는 데 걸리는 시간
  • 테스트는 코드와 함께 유지되어야합니다. 테스트 할 API가 변경 될 때 테스트가 변경되어야합니다.
  • 테스트를 작성하기 위해 디자인을 변경해야 할 수도 있습니다 (이 변경은 일반적으로 더 낫습니다).

비용이 혜택을 능가하는 경우 테스트를 작성하지 않는 것이 좋습니다. 예를 들어, 기능을 테스트하기가 어렵고 API가 자주 변경되고 정확성이 상대적으로 중요하지 않으며 테스트에서 결함을 발견 할 가능성이 낮 으면 작성하지 않는 것이 좋습니다.

코드 대 테스트의 특정 비율과 관련하여 코드가 충분히 논리 밀도가 높으면 해당 비율을 보증 할 수 있습니다. 그러나 일반적인 응용 프로그램 전체에서 그러한 비율을 유지하는 것은 가치가 없습니다.


12

그렇습니다. 단위 테스트가 너무 많습니다.

테스트는 좋지만 모든 단위 테스트는 다음과 같습니다.

  • API와 밀접한 관련이있는 잠재적 인 유지 보수 부담

  • 다른 것에 쓸 수있는 시간

  • 단위 테스트 제품군의 시간
  • 사실상 다른 테스트가 통과하고이 테스트는 실패 할 가능성이 적은 다른 테스트의 복제본이므로 실제 값을 추가하지 않을 수 있습니다.

100 % 코드 범위를 목표로하는 것이 현명하지만, 특정 테스트 포인트 (함수 / 방법 / 호출 등)에 대해 각각 100 % 코드 범위를 독립적으로 제공하는 일련의 테스트를 의미합니다.

좋은 커버리지를 달성하고 버그를 몰아 낼 수있는 방법이 얼마나 어려울지라도 '너무 많은 단위 테스트'만큼 '잘못된 단위 테스트'와 같은 것이있을 수 있습니다.

대부분의 코드에 대한 실용성은 다음을 나타냅니다.

  1. 진입 점이 100 % 적용되는지 확인하십시오 (모든 방법이 테스트 됨). '비 오류가없는'경로의 100 % 코드 적용 범위에 근접해야합니다.

  2. 관련 최소 / 최대 값 또는 크기 테스트

  3. 재미있는 특수 사례라고 생각되는 것을 특히 '홀수'값으로 테스트하십시오.

  4. 버그를 발견하면 해당 버그를 드러낸 단위 테스트를 추가하고 유사한 사례를 추가해야하는지 생각하십시오.

더 복잡한 알고리즘의 경우 다음도 고려하십시오.

  1. 더 많은 사례에 대한 대량 테스트 수행.
  2. 결과를 '브 루트 포스'구현과 비교하고 불변량을 확인합니다.
  3. 무작위 테스트 사례를 생성하고 불변량을 포함한 무차별 대입 및 사후 조건을 확인하는 몇 가지 방법을 사용합니다.

예를 들어, 임의의 입력이있는 정렬 알고리즘을 확인하고 데이터 유효성 검사는 스캔하여 정렬합니다.

귀하의 기술 책임자가 '최소 베어 엉덩이'테스트를 제안하고 있다고 말하고 싶습니다. 나는 '가장 높은 가치의 품질 테스트'를 제공하고 있으며 그 사이에 스펙트럼이 있습니다.

어쩌면 당신의 선임은 당신이 만들고있는 부품이 더 큰 부품에 내장 될 것이고, 통합 될 때 더 철저하게 테스트 될 것이라는 것을 알고있을 것입니다.

핵심 교훈은 버그가 발견되면 테스트를 추가하는 것입니다. 단위 테스트 개발에 대한 나의 최고의 교훈은 다음과 같습니다.

하위 단위가 아닌 단위에 중점을 둡니다. 하위 유닛으로 유닛을 구축하는 경우 하위 유닛이 타당 해 질 때까지 서브 유닛에 대한 매우 기본적인 테스트를 작성하고 제어 유닛을 통해 서브 유닛을 테스트하여 더 나은 범위를 달성하십시오.

따라서 컴파일러를 작성 중이고 기호 테이블을 작성 해야하는 경우 (예 :). 기본 테스트로 심볼 테이블을 준비하고 테이블을 채우는 선언 파서를 작업하십시오 (예 :). 기호 테이블에서 버그를 발견 한 경우 기호 테이블 '독립형'장치에만 추가 테스트를 추가하십시오. 그렇지 않으면 선언 파서 및 나중에 전체 컴파일러에서 단위 테스트로 적용 범위를 늘립니다.

그것은 벅에 가장 좋은 결과를 얻습니다 (전체의 한 테스트는 여러 구성 요소를 테스트하는 것임). 더 안정적인 경향이있는 테스트에는 '외부'인터페이스 만 사용되므로 재 설계 및 개선을 위해 더 많은 용량을 남겨 둡니다.

디버그 코드 테스트 사전 조건, 모든 수준의 불변 값을 포함한 사후 조건과 결합하여 최소한의 테스트 구현으로 최대 테스트 범위를 얻습니다.


4
100 % 적용 범위가 실용적이라고는 말할 수 없습니다. 100 % 적용 범위는 매우 높은 표준입니다.
Bryan Oakley

불행하게도 무작위 방법조차도 오류를 놓칠 수 있습니다. 비공식적이라하더라도 증거를 대체 할 수는 없습니다.
Frank Hileman 18

@BryanOakley Point이 (가) 촬영되었습니다. 그것은 과장된 진술입니다. 그러나 사람들이 신용을주는 것보다 가까이 다가가는 것이 더 중요합니다. "나는 그것이 쉬운 모든 길을 테스트했다"는 항상 나중에 문제를 일으킬 것입니다.
Persixty

@FrankHileman이 질문은 "소프트웨어를 신중하게 디자인하고 정적 인 검사 로직과 검증 알고리즘을 대체 할 수있는 좋은 대안"이라고 대답하지 않았다. 두 방법 모두 자체적으로 고품질 소프트웨어를 생산하지는 않습니다.
Persixty

3

첫째, 프로덕션 코드보다 더 많은 테스트 라인 을 갖는 것이 반드시 문제가되는 것은 아닙니다 . 테스트 코드는 선형적이고 이해하기 쉬워야합니다. 프로덕션 코드의 유무에 관계없이 필요한 복잡성은 매우 낮습니다. 테스트 의 복잡성 이 프로덕션 코드 의 복잡성 에 접근하기 시작하면 문제가있을 수 있습니다.

예, 너무 많은 단위 테스트가 가능합니다. 간단한 생각 실험에 따르면 추가 가치를 제공하지 않는 테스트를 계속 추가 할 수 있으며 추가 된 모든 테스트는 최소한 일부 리팩토링을 방해 할 수 있습니다.

가장 일반적인 경우 만 테스트하는 충고에는 결함이 있습니다. 시스템 테스트 시간을 절약하기 위해 연기 테스트로 작동 할 수 있지만 실제로 중요한 테스트는 전체 시스템에서 실행하기 어려운 사례를 포착합니다. 예를 들어, 메모리 할당 실패의 제어 된 오류 주입은 완전히 알려지지 않은 품질의 복구 경로를 실행하는 데 사용될 수 있습니다. 또는 제수 (또는 제곱근이 될 음수)로 사용되는 값으로 0을 전달하고 처리되지 않은 예외가 발생하지 않도록하십시오.

다음으로 가장 유용한 테스트는 극한의 한계 또는 경계 지점을 실행하는 테스트입니다. 예를 들어, 한 달의 (1 기반) 개월을 수용하는 함수는 0, 1, 12 및 13으로 테스트되어야합니다. 따라서 유효하지 않은 유효 전이가 올바른 위치에 있음을 알 수 있습니다. 이 테스트에도 2..11을 사용하는 것은 과도한 테스트입니다.

기존 코드에 대한 테스트를 작성해야한다는 점에서 어려운 위치에 있습니다. 코드를 작성할 때 (또는 쓰려고 할 때) 가장 쉬운 경우를 식별하는 것이 더 쉽습니다.


3

단위 테스트에 대한 나의 이해는 모든 방법이 예상대로 작동하는지 클래스의 각 방법을 테스트하는 것이 었습니다.

이 이해가 잘못되었습니다.

단위 테스트는 검증 동작테스트 대상 유닛 .

그런 의미에서 유닛 이 반드시 "클래스의 메소드"인 것은 아닙니다. 나는 단위 테스트의 예술 에서 Roy Osherove에 의해 단위의 정의를 좋아한다 :

단위는 변경해야 할 이유가 동일한 모든 프로덕션 코드입니다.

이를 바탕으로 단위 테스트는 원하는 코드의 모든 동작 을 확인 해야합니다. "욕망"이 어느 정도 요구 사항에서 취해지는 경우.


그러나 풀 요청에서 기술 책임자는 더 높은 수준의 테스트에 집중해야한다고 언급했습니다.

그는 옳지 만 생각과는 다른 방식입니다.

귀하의 질문에서 귀하는 해당 프로젝트의 "전용 테스터"임을 이해합니다.

큰 오해는 "단위 테스트 프레임 워크를 사용한 테스트"와 달리 단위 테스트를 작성해야한다는 것입니다. ynit 테스트를 작성 하는 것은 테스터가 아닌 개발자책임입니다 (이상적인 세계에서는 ...). 반면 에이 질문에 TDD로 태그를 달았습니다.

테스터로서의 임무는 모듈 및 / 또는 응용 프로그램 테스트를 작성 (또는 수동으로 실행)하는 것입니다. 이러한 종류의 테스트는 주로 모든 장치가 원활하게 작동하는지 확인해야합니다. 즉, 각 장치가 한 번 이상 실행 되도록 테스트 사례를 선택해야합니다 . 그리고 그 확인은 실행됩니다. 실제 결과는 향후 요구 사항에 따라 변경 될 수 있으므로 덜 중요합니다.

덤프 자동차 비유를 한 번 더 강조하기 위해 : 조립 라인 끝에서 자동차로 몇 번의 테스트를 수행합니까? 정확히 하나 : 주차장 자체로 운전해야합니다 ...

요점은 다음과 같습니다.

"단위 테스트"와 "단위 테스트 프레임 워크를 사용한 테스트 자동화"의 차이점을 알고 있어야합니다.


나에게 100 % 단위 테스트 범위는 높은 목표이지만, 50 %에 도달하더라도 그 50 %의 100 %가 보장된다는 것을 알게 될 것입니다.

단위 테스트는 안전망입니다. 이미 구현 된 동작을 중단하지 않고 기술 부채를 줄이거 나 새로운 동작을 추가하기 위해 코드 를 리팩토링 할 수 있습니다.

100 % 코드 적용 범위가 필요하지 않습니다.

그러나 100 % 행동 범위가 필요합니다. (예, 코드 적용 범위와 행동 적용 범위는 어떤 식 으로든 상관 관계가 있지만 그와 동일하지 않습니다.)

행동 범위가 100 % 미만인 경우 테스트 스위트를 성공적으로 실행하면 테스트되지 않은 동작 중 일부를 변경할 수 있으므로 아무 의미가 없습니다. 그리고 릴리스가 온라인이 된 다음날 고객에게 통지됩니다 ...


결론

테스트가없는 것보다 낫지 않은 테스트는 거의 없습니다. 의심의 여지가 없습니다!

그러나 단위 테스트를 너무 많이하는 것과 같은 것은 없습니다.

각 단위 테스트는 코드 동작 에 대한 단일 기대치 를 확인하기 때문 입니다. 또한 코드에 대한 기대치보다 더 많은 단위 테스트를 작성할 수 없습니다. 또한 안전 장치의 구멍은 원하지 않는 변경이 생산 시스템에 해를 끼칠 수있는 기회입니다.


2

확실히 맞아요. 예전에는 대규모 소프트웨어 회사의 SDET이었습니다. 우리의 소규모 팀은 훨씬 큰 팀이 처리했던 테스트 코드를 유지해야했습니다. 또한, 우리 제품에는 끊임없는 변화가 지속적으로 발생하는 일부 종속성이 있었기 때문에 지속적인 테스트 유지 관리가 필요합니다. 팀 규모를 늘릴 수있는 옵션이 없었기 때문에 실패했을 때 가치가없는 수천 가지 테스트를 버려야했습니다. 그렇지 않으면 결함을 따라 가지 못할 것입니다.

이 문제를 단순한 관리 문제로 해결하기 전에 실제 프로젝트의 많은 프로젝트가 레거시 상태에 접근 할 때 직원 수가 줄어드는 것을 고려해야합니다. 때로는 첫 번째 릴리스 직후에 시작되기도합니다.


4
"우리 제품에는 중요한 변경 사항이 지속적으로 도입되는 의존성이 있었기 때문에 지속적인 테스트 유지 관리가 필요합니다." -당신이 말하는 그 테스트들은 당신의 의존성이 끊임없이 깨지는 경우에 귀중한 것들과 같은 유지 보수 사운드를 요구합니다.
CodeMonkey

2
테스트에는 문제가 아니라 조직에 문제가 있습니다.
jwenting

2
@CodeMonkey 종속성이 깨지지 않았습니다. 제품을 변경해야하는 방식으로 업데이트되었습니다. 예, 테스트는 가치가 있었지만 다른 테스트만큼 가치가 없었습니다. 자동 테스트는 동등한 수동 테스트가 어려운 경우 가장 유용합니다.
mrog

2
@jwenting 예, 코드 문제가 아니라 조직 문제입니다. 그러나 테스트가 너무 많았다는 사실은 변하지 않습니다. 조사 할 수없는 실패한 테스트는 원인에 관계없이 쓸모가 없습니다.
mrog

"SDET"이란 무엇입니까?
Peter Mortensen

1

복사 붙여 넣기를 제거하기 위해 테스트 코드를 리팩토링한다고 가정 할 때 제품 코드보다 많은 테스트 코드 줄이 문제가되는 것은 아닙니다.

문제는 구현을 반영하는 테스트를 수행하는 것입니다. 예를 들어 모의 및 스텁으로로드 된 테스트와 메소드가 다른 메소드를 호출한다고 주장하는 것과 같은 비즈니스 의미는 없습니다.

"대부분의 단위 테스트가 낭비되는 이유" 논문 에서 큰 인용은 단위 테스트 에 "광범위하고 형식적이며 독립적 인 정확성의 오라클, 그리고 ... 비즈니스 가치"가 있어야한다는 것입니다.


0

내가 언급하지 않은 한 가지는 모든 개발자가 언제든지 테스트를 빠르고 쉽게 실행할 수 있어야한다는 것 입니다.

테스트가 완료되기 전에 소스 제어에 체크인하고 1 시간 이상 (코드베이스의 크기에 따라) 기다릴 필요가 없으므로 변경 사항이 발생했는지 확인하기 위해 수행 할 수 있습니다. 소스 제어에 체크인하기 전에 (또는 최소한 변경 사항을 푸시하기 전에) 자신의 머신. 이상적으로는 단일 스크립트 또는 버튼 누름으로 테스트를 실행할 수 있어야합니다.

이러한 테스트를 로컬로 실행할 때 몇 초 정도 빠르게 실행되기를 원합니다. 더 느리게, 충분히 또는 전혀 실행하지 않으려는 유혹을받을 것입니다.

따라서 테스트를 너무 많이 수행하는 데 몇 분이 걸리거나 지나치게 복잡한 테스트가 문제가 될 수 있습니다.

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