테스트 : 결정적 또는 비 결정적?


16

두 가지 중 하나를 갖는 것이 더 낫습니까?

  • 결정적 테스트 스위트, 동일한 테스트 성공
  • 잠재적으로 더 많은 사례를 포괄 할 수있는 비 결정적 테스트 스위트

?

예 : MVC 애플리케이션에서 컨트롤러 기능을 테스트하기 위해 테스트 스위트를 작성합니다. 컨트롤러는 테스트 중에 데이터베이스의 애플리케이션 데이터를 입력으로 요구합니다. 이를 수행하는 두 가지 옵션이 있습니다.

  • 테스트 데이터베이스에서 어떤 행을 입력으로 선택했는지 하드 코딩합니다 (예 : 10 번째 및 412 번째 행)
  • 난수 생성기를 사용하여 데이터베이스에서 데이터를 의사 난수 적으로 선택합니다 (난수 생성기에 의해 선택된 두 개의 행)

첫 번째는 결정적입니다. 동일한 코드 개정판에 대한 모든 테스트 실행에서 동일한 결과를 가져와야합니다. 두 번째는 비 결정적입니다. 테스트 스위트를 실행할 때마다 다른 결과를 얻을 수 있습니다. 그러나 임의로 선택한 데이터는 데이터 에지 사례를 더 잘 표현할 수 있습니다. 예측할 수없는 데이터를 컨트롤러에 공급하는 사용자를 시뮬레이션 할 수 있습니까?

다른 것을 선택해야하는 이유는 무엇입니까?


5
때로는 테스트가 실패합니다. martinfowler.com/articles/nonDeterminism.html

그 링크 주셔서 감사합니다. 그 기사를 염두에두고, 나는 비결정론 이이 테스트 스위트의 맥락에서 의미한다는 것을 분명히해야한다고 생각했습니다. 데이터베이스에서 데이터가 무작위로 선택되므로 컨트롤러에 공급 된 모든 데이터는 기본적으로 유효한 데이터입니다. 이는 비결정론에 대해서는 테스트 스위트에 잘못된 부정이 존재하지 않음을 의미합니다. 어떤 방식으로,이 임의성은 컨트롤러에서 사용하기 위해 '임의로'데이터를 선택하는 사용자를 시뮬레이션합니다. 이것은 반드시 기사가 논의하는 것과 같은 비결정론이 아닐 수도 있습니다.
DCKing


10
@DCKing : 테스트가 실패하면 어떻게되는지 고려하십시오. 알았어, 버그가있어 어, 이제 뭐? 디버그 모드에서 다시 실행하십시오! 성공한 곳! 다음 백 번처럼 실행 한 다음이 문제를 우주 광선 파업으로 기록합니다. 테스트에서 결정적이지 않은 소리는 절대적으로 불가능합니다. 테스트 케이스에서 더 많은 접지를 커버 할 필요가 있다고 생각되면 더 많은 접지를 커버하십시오. 설정된 시드로 RNG를 초기화하고 지속적으로 임의의 값으로 수백 번 "테스트"를 실행하십시오.
Phoshi

1
(결국 내가 제대로 트위터를 검색 할 수있는 시스템으로 주위에 있어요 -은 " 그 시험을 그냥 가끔 실패는 "트위터에 #FiveWordTechHorrors에서입니다 - 제대로 신용 원)

답변:


30

테스트 스위트를 실행할 때마다 다른 결과를 얻을 수있는 가능성이 있다면 테스트는 거의 가치가 없습니다. 스위트에 버그가 표시되면 버그를 재현 할 수 없을 가능성이 높습니다. 버그, 수정이 작동하는지 확인할 수 없습니다.

따라서 테스트 데이터 생성에 일종의 난수 생성기를 사용해야한다고 생각되면 항상 동일한 시드로 생성기를 초기화하거나 테스트에 공급하기 전에 임의의 테스트 데이터를 파일로 유지하십시오. 따라서 이전 실행과 동일한 데이터를 사용하여 테스트를 다시 실행할 수 있습니다. 이렇게하면 비 결정적 테스트를 결정적 테스트로 변환 할 수 있습니다.

편집 : 난수 생성기를 사용하여 일부 테스트 데이터를 선택하면 IMHO는 때때로 좋은 테스트 데이터를 선택하는 너무 게으르다는 신호입니다 . 무작위로 선택된 10 만 가지의 테스트 값을 던지는 대신 우연히 모든 심각한 버그를 발견하고 뇌를 더 잘 활용하고 10 ~ 20 개의 "흥미로운"사례를 선택하여 테스트 스위트에 사용하기에 충분할 것으로 기대합니다. 이렇게하면 테스트 품질이 향상 될뿐만 아니라 스위트의 성능이 훨씬 향상됩니다.


답변 주셔서 감사합니다. 내 질문에 대한 의견에 대한 귀하의 의견은 무엇입니까?
DCKing

1
@DCKing : 무작위 생성기가 나보다 좋은 테스트 사례를 선택하는 것이 더 낫다고 생각한다면 (내가 의심하는 것) 한 번만 사용하여 프로그램이 실패한 테스트 데이터의 조합을 찾고 해당 조합을 "하드 코딩 된"부분에 넣습니다. 테스트 스위트
Doc Brown

다시 감사합니다. MVC 앱에만 적용되지 않도록 답변을 업데이트했습니다.
DCKing

1
임의의 키 입력을 생성하는 테스트 프로그램이있는 일부 UI 컨텍스트 (예 : 컨트롤러 입력을받는 게임)에서는 스트레스 테스트에 유용 할 수 있습니다. 의도적 인 입력으로는 찾기 어려운 결함을 발견 할 수 있습니다.
로봇

@StevenBurnap : 글쎄, 내가 질문을 이해하는 방식은 OP 가보다 전통적인 회귀 테스트를 염두에두고 있다고 생각합니다. 물론 스트레스 테스트는 하드웨어에 종속적이고 임의 생성기를 사용하지 않는 경우에도 결정적이지 않은 동작을 유발할 수있는 특별한 경우입니다. 그것은 질문 아래 첫 번째 의견에서 MichaelT가 링크 한 기사에 설명 된 것입니다. 그리고 무작위 입력을 이용한 스트레스 테스트에서도 정의 된 랜덤 시드를 사용하여 동작을보다 결정 론적으로 만들려고 할 수 있습니다.
Doc Brown

4

결정 론적 및 비결정론 적 둘 다 장소가 있습니다.

나는 다음과 같이 나눌 것입니다.

단위 테스트.

이것들은 매번 똑같은 데이터로 결정적이고 반복 가능한 테스트를해야합니다. 단위 테스트는 격리 된 특정 코드 섹션과 함께 제공되며 결정적인 방식으로 테스트해야합니다.

기능 및 입력 스트레스 테스트.

이들은 다음과 같은 경고와 함께 비 결정적 접근 방식을 사용할 수 있습니다.

  • 그 사실은 명확하게 묘사되고 불려집니다
  • 선택한 임의의 값이 기록되며 수동으로 다시 시도 할 수 있습니다

3

양자 모두.

결정 론적 테스트와 비결정론 적 테스트에는 스위트마다 다른 사용 사례와 다른 값이 있습니다. 일반적으로 비결정론 적 (nondeterministic)은 결정 론적 (deterministic) 테스트와 동일한 정밀도를 제공 할 수 없으며, "비결정론 적 테스트는 가치를 제공하지 않습니다." 이것은 거짓입니다. 그것들은 덜 정확할 수도 있지만, 훨씬 더 넓을 수도 있으며, 그 자체의 이점이 있습니다.

예를 들어 보자. 정수 목록을 정렬하는 함수를 작성한다. 유용한 결정적 단위 테스트는 무엇입니까?

  • 빈 목록
  • 요소가 하나만있는 목록
  • 동일한 요소가 모두있는 목록
  • 여러 개의 고유 한 요소가있는 목록
  • 여러 요소가 포함 된 목록 (일부는 중복 됨)
  • 목록 NaN, INT_MIN그리고INT_MAX
  • 이미 부분적으로 정렬 된 목록
  • 10,000,000 개의 요소가있는 목록

그리고 그것은 단지 정렬 기능입니다! 물론, 이들 중 일부는 불필요하거나 일부는 비공식적 추론으로 배제 될 수 있다고 주장 할 수 있습니다. 그러나 우리는 엔지니어이며 비공식적 인 추론이 우리의 얼굴에 터지는 것을 보았습니다. 우리는 우리가 구축 한 시스템을 완전히 이해하거나 머리 속에 복잡성을 완전히 유지할만큼 똑똑하지 않다는 것을 알고 있습니다. 그래서 우리는 처음에 테스트를 작성합니다. 비 결정적 테스트를 추가한다고해서 모든 좋은 테스트를 선험적으로 알기에는 반드시 영리하지는 않을 것입니다. 반 랜덤 데이터를 함수에 던져서 놓친 경우를 찾을 수 있습니다.

물론 결정 론적 테스트도 배제하지는 않습니다. 비 결정적 테스트는 프로그램의 거대한 부분에서 버그를 찾는 데 도움이됩니다. 그러나 버그를 발견하면 수정했다는 것을 보여주는 재현 가능한 방법이 필요합니다. 그래서:

  • 비 결정적 테스트를 사용 하여 코드에서 버그찾으십시오.
  • 결정적 테스트를 사용 하여 코드에서 수정 사항확인하십시오.

이것은 단위 테스트에 대한 많은 확실한 조언이 반드시 비 결정적 테스트에 적용되는 것은 아니라는 것을 의미합니다. 예를 들어, 그것들은 빨라야합니다. 낮은 수준의 속성 테스트는 빠르지 만 "웹 사이트에서 사용자가 임의로 버튼을 클릭하고 500 오류가 발생하지 않는지 확인"과 같은 비 결정적 테스트는 속도에 대한 종합 성을 선호해야합니다. 개발 속도를 늦추지 않도록 빌드 프로세스와 독립적으로 실행되는 테스트를 수행하십시오. 예를 들어, 자체 전용 준비 상자에서 실행하십시오.


-1

결정 론적 대 비결정론 적을 원하지 않습니다.

당신이 원하는 것은 "항상 같음"대 "항상 같지 않다"입니다.

예를 들어, 빌드마다 증가하는 빌드 번호가있을 수 있으며 임의의 숫자를 원할 경우 빌드 번호를 시드로 사용하여 난수 생성기를 초기화합니다. 따라서 모든 빌드마다 다른 값으로 테스트를 수행하여 버그를 찾을 수있는 더 많은 기회를 제공합니다.

그러나 버그가 발견되면 동일한 빌드 번호로 테스트를 실행하기 만하면 재현 할 수 있습니다.


1
또는 사용할 빌드 번호가없는 경우 초기 시드 값을 테스트 실행 출력에 배치하면 동일한 시드로 테스트를 다시 실행할 수 있습니다.
RemcoGerlich
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.