2009-02-23 3 views
36

Quickcheck 및 그 변형 (심지어 Java에 하나 있음)이 흥미 롭습니다. 그러나 학문적 인 관심 외에도 실제 응용 프로그램 테스트 (예 : GUI 응용 프로그램 또는 클라이언트/서버 또는 StackOverflow 자체 가져 오기)에서 정말 유용합니까? 유사한 테스트 생성기에 대한 경험은 인정됩니다.실제 프로젝트에서 Quickcheck을 사용 했습니까

답변

48

예. 실제로는 아니지만, 원래 QuickCheck를 개발 한 사람으로 공부했습니다. 그는 정말 재미있는 사람입니다.

지난 2004 년 우리는 하스켈 프로그램을 테스트하기 위해 QuickCheck를 사용해야했으며, 좋고 나쁨의 조합이었습니다. 하스켈이 약간 위협적 이었기 때문에 주로 좋았지 만 작업 할 때 하찮은 적이 없었습니다.

존 (John)은 몇 년 전에 쓴 Ericssion의 복잡한 텔레콤 하드웨어 테스트에 도움을주었습니다. 그리고 그는 2000 만 개가 넘는 코드 줄에서 버그를 발견하여 접근 방식을 단순한 3 단계로 줄였습니다. 그는 훌륭한 연설자이기 때문에 항상 자신이하는 것을 듣는 것이 기쁨입니다.하지만 QuickCheck로 한 일은 새로운 것이 었습니다. 그래서 나는 그에게 시장에 가져 오기 위해 그의 관심이 무엇인지 물었다. 그는 아이디어에 대해 개방적 이었지만 당시 (QuickCheck를 기반으로 한) 그의 비즈니스는 상대적으로 새롭고 그가 집중할 다른 분야가있었습니다. 지금은 2007입니다. 요점은 QuickCheck를 사용하여 끝내지 않더라도 QuickCheck에서 배울 수 있다는 것입니다.

하지만 QuickCheck이란 무엇입니까? 이는 조합 테스트 프레임 워크이자 프로그램을 테스트하는 흥미로운 방법입니다. Microsoft Research의 사람들은 비슷한 종류의 Pex을 구축했습니다. Pex는 IL을 검사하여 자동으로 검사를 생성합니다. 그러나 John은 함수의 가능한 입력 및 테스트 속성에 대해 생성기를 작성합니다. 속성은 쉽게 테스트 할 수있는 무언가이며 훨씬 더 공식적입니다. 예 : 목록 뒤집기? 목록을 뒤집는 것은 목록을 두 개의 반쪽으로 나눠서 각각 개별적으로 뒤집은 다음 두 개의 반전 된 반쪽을 역순으로 연결하는 것과 같습니다.

1,2,3,4 // original 
1,2 3,4 // split into A and B 
2,1 4,3 // reverse A and B 
4,3,2,1 // concat B and A 

이것은 QuickCheck로 테스트 한 훌륭한 속성이며 그 결과는 매우 놀랍습니다.

Pex는 멋지지만 QuickCheck만큼 멋있지는 않지만 Pex는 작업을 단순화합니다. QuickCheck는 그렇지만 좋은 사양을 작성하는 데 많은 노력이 필요합니다.

QuickCheck의 기능은 오류가 발생하면 테스트가 실패한 입력을 가능한 가장 작은 형식으로 줄이는 것입니다. 상태의 진전으로 인해 테스트가 실패한 원인에 대해 자세히 설명합니다. 무차별 방식으로 코드를 해독하려고하는 다른 테스트 프레임 워크와 비교할 때.

이것은 테스트 사양 작성 방법으로 인해 가능합니다. QuickCheck는 입력을 생성하기 위해 의사 임의성에 의존합니다.이 때문에 입력을 되돌릴 수 있고 테스트를 통과하지 못하는 아주 작은 입력을 찾을 수 있습니다.

QuickCheck 속성을 작성하는 데는 많은 작업이 필요하지만 최종 결과는 테스트가 더 좋습니다. John 자신이 말했듯이, 버그의 70 %는 유닛 테스팅에 의해 잡히지 만, 다른 30 %는 프로그램이 충돌하게 만듭니다. QuickCheck는 지난 30 %를 테스트하고 있습니다.

+2

매우 좋습니다. 그러나, 내 질문에 돌아와서, 우리는 기능이 순수하지 않을 수있는 다른 경우에 그것을 사용할 수 있습니까 (단지 부작용으로 일을 할 수도 있음). 한 위치에서 다른 위치로 파일을 복사하는 함수를 예로 들어 보겠습니다. – amit

+1

오, 그래, 당신의 기능은 부작용이 정말 문제가되지 않습니다. 그 자체로는 문제가 있지만 QuickCheck를 사용하는 것을 방해하지는 않습니다. Ericssion 테스트 슈트에는 부작용이 있었으며이를 해결할 수있는 방법이 있습니다. –

+1

국가 진보에 대해 신중하고 생각하는 것이 포함됩니다. 그러나 기본 원칙이 적용됩니다. 줄이기 부분은 까다 롭지 만 근본적으로 작동하는 것 같습니다. 충돌이 계속 발생하면 잘못된 입력을 가져 와서 입력을 제거하십시오. 그것은 순수 함수에만 국한되지 않습니다. –

7

:

그러나, 여기 내 개인적인 경험에서 덜 사소한 비트입니다. 지난 6 개월 이내 :

  • 란 이미지 압축기에서 색상 변환 및 이산 코사인 변환을 테스트하는 데 사용됩니다.

  • Ran QuickCheck를 사용하여 수치 최적화를 위해 필자가 채운 기호 차별화 모듈을 테스트 할 수 있습니다.

  • Ran Bentley 및 Sedgewick 스타일의 3 진 검색 트리를 테스트하는 빠른 검사.

QuickCheck 거의 모든 내 단위 테스트 요구 사항을 충족하지 않습니다, 그러나 그것은 시작하는 좋은 방법 ---와 QuickCheck 법률은 좋은 문서를 확인하십시오.

+0

명백히 QuickCheck는 IO 모나드의 코드를 테스트하는 데 적합하지 않지만 QuickCheck가 모든 순수 코드를 테스트하는 데 적합하다는 것을 알고 있습니까? 그렇지 않다면, 그것은 어디에 잘 맞지 않습니까? –

8

이산 이벤트 시뮬레이션과 관련된 실제 하스켈 문제를 해결했습니다. 그래서 MVars와 채널에 해당하는 것과 함께 연속 모나드에 기반한 DES 라이브러리를 작성했습니다. 이 작업이 제대로되었는지 확인해야하므로 여러 개의 QuickCheck 속성을 작성하여 채널에 작성된 동시 데이터의 두 스트림을 올바르게 삭제할 수 있습니다.

또한 Quick Check를 사용하여 Ranged SetsDecimal 라이브러리의 속성을 문서화하고 확인했습니다.

제 경험으로 보면 빠른 검사가 종종 있습니다. 중요한 속성을 간결하게 요약 할 수 있다면 해당 속성을 제공하는 알고리즘은 털이 있지만 QuickCheck는 큰 이점입니다. 반면에 알고리즘은 내가 검증하고자하는 속성과 동등하다는 것을 자주 발견합니다. 이 경우 나는 더 간단한 속성을 찾는다. 예를 들어 함수 "foo"가 엄격하게 단조롭지 않다고 가정합니다. 그러면 쓸 수 있습니다

prop_fooMonotonic x y = (x > y) ==> (foo x >= foo y) 
2

작은 헬퍼 도구 개발을 위해 프로덕션 환경에서만 하스켈을 사용했습니다. 주로 내가 하스켈을 읽는 유일한 개발자이기 때문에 주로. QuickCheck를 광범위하게 사용했지만 C#에서는 이와 유사한 것을 사용할 수 없다는 것이 정말 짜증났습니다. 그래서 나는 시도하기로 결정했다 write it myself. 나는 Pex를 보았지만, QuickCheck가하는 것보다 덜 흥미로운 최소한의 입력을 찾는 데 사용되는 프로그램 탐색 기술을 발견했다.

3

AFAIK XMonad는 QuickCheck

2

내가 QuickCheck 어떤 언어로 작성된 명령 줄 프로그램의 동작을 테스트하는 데 사용으로 광범위하게 테스트됩니다.

저수준 또는 동적 입력 프로그램이 충돌하는 입력을 찾는 것이 특히 유용합니다.

편의상, 나는이 방법으로 명령 줄 프로그램을 테스트하기 위해 hspec 및 HUnit과 함께 사용되는 QuickCheck의 몇 가지 예를 포함하여 http://hackage.haskell.org/package/proctest을 작성했습니다.

1

우리는 FsCheck을 사용하여 OCaml에서 F # 로의 번역이 정확한지, 그리고 최적화 된 버전이 최적화되지 않은 버전과 동일한 지 확인합니다. 또한 NHol 프로젝트가 parser 연결자를 사용하기 때문에이 도구를 사용하여 렉서와 파서를 테스트 할 계획입니다.

NUnit (.Net 용 XUnit) 내에 테스트를 실행할 수있는 도우미 기능이 있습니다. assertProp을 참조하십시오.

0

내 프로젝트가 아니지만 containers 패키지는 QuickCheck를 상당히 광범위하게 사용합니다. 개인적으로, 나는 이것을에 썼던 바보 같은 작은 프라임 체와 비교하기 위해 그것을 사용하려고 시도했다. 그것은 내가 arithmoi에서 그 중 하나를 발견 할 때가끔 segfaults가되었다.