테스트를 테스트하는 방법?


53

우리는 코드가 더 정확하도록 (실제로 부정확하지 않도록) 테스트합니다 . 그러나 테스트는 코드이기도하며 오류가 포함될 수도 있습니다. 그리고 테스트가 버그가 있다면 코드를 개선하기가 어렵습니다.

테스트에서 세 가지 가능한 유형의 오류를 생각할 수 있습니다.

  1. 프로그래머가 당면한 과제를 잘못 이해했을 때의 논리적 오류와 테스트는 그가해야 할 것으로 생각하는 것을 수행합니다.

  2. 기본 테스트 프레임 워크의 오류 (예 : 누출 모의 추상화)

  3. 테스트의 버그 : 테스트는 프로그래머가 생각하는 것과 약간 다릅니다.

타입 (1) 오류는 예방하기가 불가능한 것 같습니다 (프로그래머가 그냥 똑똑하지 않으면). 그러나 (2)와 (3)은 다루기 쉬울 수 있습니다. 이러한 유형의 오류를 어떻게 처리합니까? 이를 피하기위한 특별한 전략이 있습니까? 예를 들어, 테스트 작성자의 전제 조건 만 확인하는 특별한 "빈"테스트를 작성하십니까? 또한 깨진 테스트 사례를 어떻게 디버깅합니까?


3
조롱에 대해 읽은 모든 입문 작품 이이 문제에 부딪친 것 같습니다. 일단 모의를 시작하면 테스트는 항상 테스트하는 코드보다 복잡해 보입니다. 분명히 실제 코드를 테스트 할 때는 그렇지 않을 수 있지만 배우려고 할 때 매우 실망합니다.
Carson63000

@ Carson63000 테스트 된 모의로 테스트 하는 간단한 테스트 라면 복잡성이 분리되어 제어됩니다 (제 생각에).
mlvljr

13
그러나 어떻게 테스트 테스트를 테스트합니까?
ocodo

+1. 항목 1은 요구 사항 오류 일 수 있습니다. 요구 사항을 검토해야만 예방할 수 있습니다. 또한 요구 분석가가 아닌 한 프로그래머의 손에서 벗어날 것입니다.
MarkJ

@ocodo : 감시자를 보는 것과 같은 방식입니다. :)
Greg Burghardt

답변:


18

테스트는 이미 테스트되었습니다. 테스트는 코드와 기대치의 차이 만 감지하기 때문에 설계는 버그로부터 보호됩니다. 문제가 있으면 오류가 있습니다. 코드에 오류가 있거나 테스트에서 같은 확률로 오류가 발생할 수 있습니다.

  1. 코드와 테스트에서 동일한 버그를 추가하지 못하게하는 몇 가지 기술이 있습니다.

    1. 클라이언트는 구현 자와 다른 사람이어야합니다.
    2. 먼저 테스트를 작성한 다음 코드를 작성하십시오 (Test Driven Development에서와 같이).
  2. 기본 플랫폼을 테스트 할 필요는 없습니다. 테스트는 사용자가 작성한 코드를 실행할뿐 아니라 플랫폼에서도 코드를 실행합니다. 테스트 플랫폼에서 버그를 잡을 필요는 없지만 플랫폼에서 항상 버그를 숨기는 코드 및 테스트를 작성하는 것은 매우 어렵습니다. 즉, 테스트 / 코드 및 플랫폼에서 사용자가 생성 할 때마다 확률이 낮아집니다. 이 작업을 시도하더라도 매우 어려운 작업이됩니다.

  3. 테스트에는 버그가있을 수 있지만 일반적으로 테스트는 개발 된 코드에 의해 테스트되기 때문에 쉽게 발견됩니다. 코드와 테스트 사이에는 자체 시행 피드백이 있습니다. 둘 다 인터페이스의 특정 호출이 어떻게 동작해야하는지 예측합니다. 응답이 다르면 코드에 버그가 없어도됩니다. 테스트에도 버그가있을 수 있습니다.


아주 좋은 답변입니다. 테스트와 코드 사이의 자체 강화 루프 아이디어와 기본 플랫폼에 버그를 일관되게 숨기는 테스트를 작성하는 것이 어렵다는 관찰이 마음에 듭니다.
Ryszard Szopa

실제 코드의 기능에 대한 잘못된 가정을 기반으로 테스트가 작성되는 것을 막지 않습니다. 테스트하는 동안 발견되지 않은 버그가 발생할 수 있습니다. 이를 방지하는 유일한 방법은 실제 코드를 작성하는 조직과 전혀 관련이없는 제 3자가 작성한 테스트를 수행하는 것이므로 요구 사항 문서를 해석 할 때 서로의 생각을 "공해"시킬 수 없습니다.
jwenting

24

개별 테스트를 가능한 한 작게 (짧게) 만들어보십시오.

이렇게하면 처음에 버그가 발생할 가능성이 줄어 듭니다. 하나를 만들더라도 더 쉽게 찾을 수 있습니다. 단위 테스트는 작고 구체적이어야하며 실패 및 편차에 대한 내성이 낮습니다.

결국, 그것은 아마도 경험의 문제 일 것입니다. 더 많은 테스트를 작성할수록 더 나은 결과를 얻을 수 있습니다.


3
테스트에 다소 복잡한 설정이 필요한 경우 어떻게합니까? 때로는 이런 종류의 것들이 당신의 통제하에 있지 않습니다.
Ryszard Szopa

글쎄, 복잡한 설정은 테스트의 "초기 조건"이라고 생각합니다. 실패하면 모든 테스트가 실패합니다. 사실, 나는 지금 그러한 프로젝트를 진행하고 있으며 단위 테스트를 사용하지 않은 사람들은 끊임없이 같은 것을 요구했습니다. 프로젝트의 복잡성.
Dr Hannibal Lecter

이 "초기 조건"이 충족되었는지 확인하는 가장 좋은 방법은 내 질문의 핵심입니다. 별도의 테스트를 작성합니까? 아니면이 조건이 맞지 않으면 테스트가 중단된다고 가정합니까? 설정이 "치명적으로"나쁘지 않고 약간 꺼져있는 상황은 어떻습니까?
Ryszard Szopa

2
초기 조건이 맞지 않으면 테스트가 실패해야합니다. 상태에있을 때 A결과가 예상됩니다 B. state가 없으면 A테스트가 실패합니다. 이 시점에서 실패한 이유, 잘못된 초기 조건 또는 테스트 실패를 조사 할 수 있지만 두 경우 모두 실패 해야합니다 . 당신이 말하는 것처럼 "약간 꺼진"경우에도 (즉 "A" => "B", "a" => "b"결코, "a" => "B"또는 테스트가 나쁘다).
Dr Hannibal Lecter

19

한 가지 전술은 테스트하는 코드 전에 테스트를 작성하고 올바른 이유로 테스트가 먼저 실패하는지 확인하는 것입니다. TDD 를 사용하는 경우 최소한이 수준의 테스트 테스트를 받아야합니다.

테스트 스위트의 품질을 테스트하는 더 철저한 방법은 돌연변이 테스트 를 사용하는 것 입니다.


2
그리고 당신의 테스트는 올바른 이유로 실패합니다 .
Frank Shearar

@ 프랭크-예. 답변에 추가하겠습니다.
Don Roby

그리고 새로운 행동을 테스트하기 위해 새로운 테스트를 추가하고 있습니다. 기존 테스트에 추가하지 마십시오.
Huperniketes

@DonRoby, 돌연변이 테스트가 실제로 유용하다고 생각하십니까? 테스트 사례에서 어떤 결함이 발견 되었습니까?
dzieciou

4

# 1 및 # 3의 경우 : 단위 테스트에는 논리가 포함되어 있지 않아야합니다.이 경우 단위 테스트에서 둘 이상의 항목을 테스트하는 것입니다. 단위 테스트의 한 가지 모범 사례는 단위 테스트 당 하나의 테스트 만하는 것입니다.

Roy Osherove의이 비디오 를보고 단위 테스트를 작성하는 방법에 대해 자세히 알아보십시오.


ad # 3-테스트가 가능한 한 간단해야하며 논리를 포함해서는 안된다는 데 동의합니다. 그러나 필요한 개체를 만들 때 테스트의 설정 단계를 고려하십시오. 약간 잘못된 개체를 만들 수 있습니다. 이것은 내가 생각하는 종류의 문제입니다.
Ryszard Szopa

'약간 잘못된 개체'라고 말하면 개체 상태가 잘못되었거나 실제 디자인이 올바르지 않은 것입니까? 객체 상태의 경우 유효성을 검사하는 테스트를 작성할 수 있습니다. 디자인이 잘못되면 테스트가 실패합니다.
Piers Myers

3

# 1의 관점에서-나는이 측면에 대해 리뷰 / 쌍을 이루는 것이 좋은 생각이라고 생각합니다. 전치사를 쉽게 만들거나 잘못 이해하는 것은 쉽지만 테스트가 수행하는 작업, 요점을 설명해야하는 경우 잘못된 대상을 목표로 삼을 경우 더 많이 선택할 수 있습니다.


2

단위 테스트를 중단해야 할 시점이 있어야합니다. 선을 그릴 때 알아야합니다. 테스트 사례를 테스트하기 위해 테스트 사례를 작성해야합니까? 테스트 케이스를 테스트하기 위해 작성된 새로운 테스트 케이스는 어떻습니까? 우리는 그들을 어떻게 테스트 할 것입니까?

if (0 > printf("Hello, world\n")) {
  printf("Printing \"Hello, world\" failed\n");
}

편집 : 의견에서 제안한 설명으로 업데이트되었습니다.


-1 무엇? 이것은 관련이없는 것 같습니다.
대안

2
단위 테스트를 중단해야 할 시점이 있어야합니다. 선을 그릴 때 알아야합니다. 테스트 사례를 테스트하기 위해 테스트 사례를 작성해야합니까? 테스트 케이스를 테스트하기 위해 작성된 새로운 테스트 케이스는 어떻습니까? 우리는 그들을 어떻게 테스트 할 것입니까?
aufather

2
프로세스 브레인은 당신의 진술을 추정하려고 시도하면서 EInfiniteRecursion을 일으켰습니다 ...
Mason Wheeler

답변을 귀하의 의견으로 바꾸면 +1이 나옵니다.
자기 자신에 대한 메모 – 이름을 생각하십시오.

3
모든 공정에서 당신의 모범은 짚맨입니다. printf ()를 호출하는 실제 프로그램이 아니라 C 라이브러리에서 printf () 서브 시스템을 테스트하고 있습니다. 그러나 어느 시점에서 테스트의 재귀 테스트를 중단해야한다는 데 동의합니다.
Tim Post

2

야.
당신은 응용 프로그램에해야합니다 :

  • 당신의 제품
  • 해당 제품에 대한 테스트.

제품에 대해 테스트를 실행하는 경우 실제로 테스트 자체가 아니라 제품과 테스트 사이의 상호 작용영향 을받습니다. 테스트가 실패하면 응용 프로그램에 버그가 있다고 말하는 것은 아닙니다. 그것은 제품과 테스트 사이의 상호 작용이 성공하지 못했다고 말합니다 . 이제 무엇이 잘못되었는지 확인하는 것이 당신의 일입니다. 다음 중 하나 일 수 있습니다.

  • 응용 프로그램이 예상대로 작동하지 않습니다 (이 기대치는 테스트에 표시됨)
  • 응용 프로그램이 올바르게 동작하고 있습니다. 테스트에서이 동작을 올바르게 문서화하지 않았습니다.

나에게 실패한 테스트는 단순한 피드백이 아니며 이것이 잘못되었다는 것이다 . 불일치가 있음을 나타내는 지표이며, 원하는 것이 잘못되었는지 확인하기 위해 둘 다 검사해야합니다. 결국, 나는 응용 프로그램이 올바른지 확인해야 할 책임이 있습니다. 테스트는 검사 할 가치가있는 영역을 강조하는 도구 일뿐입니다.

테스트는 응용 프로그램의 일부만 확인합니다. 응용 프로그램을 테스트하고 테스트를 테스트합니다.


2

테스트는 버그를 일으킬 정도로 "스마트"해서는 안됩니다.

작성하는 코드는 일련의 사양을 구현합니다. (Z 인 경우 Q 등이 아닌 한 X 인 경우 Y 인 경우) 수행해야 할 모든 테스트는 Z가 아닌 경우 X가 실제로 Y인지 확인하는 것입니다.이 경우 Q는 X를 설정하고 Y를 확인하는 것입니다.

그러나 그것은 모든 경우를 다루지는 않습니다. 아마도 당신은 말하고 있으며 당신이 옳을 것입니다. 그러나 Z가 아니라면 X 만 Y로만해야한다는 것을 알기 위해 테스트를 "스마트"하게 만들면 기본적으로 테스트에서 비즈니스 로직을 다시 구현하는 것입니다. 이것은 우리가 아래에서 좀 더 깊이 들어가기 때문에 문제가됩니다. 첫 번째 테스트를 "더 똑똑하게"하여 코드 적용 범위를 향상시키지 말고 대신 X와 Z를 설정하고 Q를 확인하는 두 번째 바보 테스트를 추가해야합니다. 이렇게하면 일반적인 경우를 다루는 두 가지 테스트 ( '행복한 길'이라고도 함) 및 별도의 테스트로 엣지 케이스를 다루는 경로입니다.

여기에는 여러 가지 이유가 있습니다. 가장 먼저 실패한 테스트가 비즈니스 논리의 버그 또는 테스트의 버그로 인한 것인지 어떻게 판단합니까? 분명히 대답은 테스트가 가능한 한 간단하다면 버그가있을 가능성이 거의 없다는 것입니다. 테스트에 테스트가 필요하다고 생각되면 테스트가 잘못되었습니다 .

다른 이유는 요구 사항이 변경되는 경우 (복수의 노력을 복제하는 것입니다 (이미 언급했듯이 단일 테스트에서 모든 가능성을 발휘할 수 있도록 테스트 스마트 작성은 기본적으로 테스트하려는 비즈니스 논리를 기본적으로 복제하는 것입니다)) 테스트는 새로운 요구 사항을 반영하도록 변경하기 쉬워야하며 테스트는 일종의 문서 역할을합니다 (테스트중인 유닛의 사양이 무엇인지 공식적으로 설명하는 방식 등).

TL : DR : 테스트에 테스트가 필요한 경우 잘못하고 있습니다. 바보 테스트를 작성하십시오 .


0

대답이 아닙니다 (나는 말할 수있는 권한이 없지만) 테스트 사례를 개발 해야하는 다른 이유를 잊었는지 궁금합니다 ... 테스트의
모든 버그를 파악하면 응용 프로그램을 쉽게 회귀 테스트 할 수 있습니다. 자동화 된 테스트 스위트를 사용하면 통합 전에 문제를 더 빨리 찾을 수 있습니다. 요구 사항에 대한 변경 사항은 테스트하기가 비교적 쉽습니다. 변경 사항이 최신 테스트 사례의 새로운 버전, 변경된 버전이 될 수 있고 이전 사례는 계속 실패를 포착 할 수 있기 때문입니다.


0

짧은 대답 : 프로덕션 코드는 테스트를 테스트 합니다.

이것을 경제학에 사용 된 신용 / 직불 모델 과 비교하십시오 . 역학은 매우 간단합니다. 크레딧이 직불 카드와 다른 경우 문제가 있습니다.

단위 테스트도 마찬가지입니다. 테스트에 실패하면 문제가 있음을 나타냅니다. 프로덕션 코드 일 수도 있지만 테스트 코드 일 수도 있습니다! 이 마지막 부분은 중요하다면.

단위 테스트로는 유형 (1) 버그를 찾을 수 없습니다. 이러한 유형의 버그를 피하려면 다른 도구가 필요합니다.

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