문제

프로그래머로서, 나는 TDD 철학에 진심으로 구입했으며 내가 쓰는 사소한 코드에 대해 광범위한 단위 테스트를하기 위해 노력했습니다. 때때로이 도로는 고통 스러울 수 있습니다 (행동 변화가 여러 단위 테스트 변경을 일으키는 행동 변화; 많은 양의 비계가 필요함). 그러나 전체적으로 나는 모든 변경 후에 실행할 수 있다는 테스트없이 프로그램을 거부하며, 내 코드는 훨씬 덜 버그가 있습니다. 결과.

최근에 나는 Haskell과 함께 노는 적이 있으며, 거주자 테스트 라이브러리 인 QuickCheck입니다. TDD와 분명히 다른 방식으로, QuickCheck은 코드의 불변성을 테스트하는 데 중점을 둡니다. 빠른 예 : 안정적인 정렬 알고리즘은 우리가 두 번 실행하고 출력이 증가하고 입력의 순열이어야하는 경우 동일한 대답을 제공해야합니다. 그런 다음 QuickCheck은 이러한 불변을 테스트하기 위해 다양한 랜덤 데이터를 생성합니다.

적어도 순수한 기능 (즉, 부작용이없는 기능, 그리고 올바르게 조롱하면 더러운 기능을 순수한 기능으로 변환 할 수 있음)의 경우, 불변의 테스트는 해당 기능의 엄격한 슈퍼 세트로 단위 테스트를 대체 할 수 있습니다. . 각 단위 테스트는 입력 및 출력으로 구성됩니다 (필수 프로그래밍 언어에서 "출력"은 함수의 반환 일뿐 만 아니라 변경된 상태 일뿐 아니라 캡슐화 될 수 있음). 수동으로 생성했던 모든 단위 테스트 입력을 포함하기에 충분한 임의의 입력 생성기를 만들 수 있습니다 (그리고 일부는 생각하지 않은 경우를 생성 할 수 있기 때문에 일부는); 경계 조건으로 인해 프로그램에서 버그를 찾으면 임의의 입력 생성기를 개선하여 해당 케이스도 생성합니다.

그러므로 도전은 모든 문제에 대한 유용한 불변량을 공식화 할 수 있는지 여부입니다. 나는 그것이 말한다 : 당신이 처음으로 답을 계산하는 것보다 정확한지 확인하기 위해 답이 있으면 훨씬 간단합니다. 불변에 대한 생각은 또한 복잡한 알고리즘의 사양을 임시 테스트 사례보다 훨씬 잘 명확하게하는 데 도움이되며, 이는 문제에 대한 사례 별 생각을 장려합니다. 이전 버전의 프로그램을 모델 구현 또는 다른 언어의 프로그램 버전으로 사용할 수 있습니다. 결국 입력 또는 출력을 명시 적으로 코딩하지 않고도 이전 테스트 사례를 모두 커버 할 수 있습니다.

내가 미쳤습니까, 아니면 내가 뭔가를하고 있습니까?

도움이 되었습니까?

해결책

1 년 후, 나는 이제이 질문에 대한 답이 있다고 생각합니다. 아니! 특히, 단위 테스트는 항상 필요하고 회귀 테스트에 필요하고 유용합니다. 여기서 테스트는 버그 보고서에 첨부되고 코드베이스에 거주하여 버그가 다시 오는 것을 방지합니다.

그러나 모든 단위 테스트를 입력이 무작위로 생성되는 테스트로 대체 할 수 있다고 생각합니다. 명령 코드의 경우에도“입력”은 당신이해야 할 명령문의 순서입니다. 물론, 임의의 데이터 생성기를 작성할 가치가 있는지 여부와 무작위 데이터 생성기를 올바른 배포 할 수 있는지 여부는 또 다른 질문입니다. 단위 테스트는 단순히 랜덤 생성기가 항상 동일한 결과를 제공하는 퇴화 케이스입니다.

다른 팁

당신이 제기 한 것은 기능 프로그래밍에만 적용될 때 매우 좋은 지점입니다. 당신은 필수 코드 로이 모든 것을 달성 할 수있는 수단을 언급했지만 왜 그렇게하지 않은지에 대해서도 다루었습니다. 특히 쉽지 않습니다.

그것이 그것이 단위 테스트를 대체하지 않을 이유라고 생각합니다. 그것은 명령 코드에 쉽게 적합하지 않습니다.

불안한

이런 종류의 테스트 만 들었지만 두 가지 잠재적 인 문제가 있습니다. 나는 각각에 대한 의견을 갖고 싶습니다.

오해의 소지가있는 결과

다음과 같은 테스트에 대해 들었습니다.

  • reverse(reverse(list)) 동일해야합니다 list
  • unzip(zip(data)) 동일해야합니다 data

이것들이 광범위한 입력에 적용된다는 것을 아는 것이 좋을 것입니다. 그러나 함수가 입력을 반환하면이 두 테스트 모두 통과됩니다.

예를 들어, 당신이 그것을 확인하고 싶을 것 같습니다. reverse([1 2 3]) 동등합니다 [3 2 1] 적어도 하나의 경우에 올바른 행동을 증명하려면 추가하다 임의의 데이터로 일부 테스트.

복잡성을 테스트합니다

입력과 출력 사이의 관계를 완전히 설명하는 불변 테스트는 함수 자체보다 더 복잡 할 수 있습니다. 복잡한 경우 버그가 될 수 있지만 테스트에 대한 테스트가 없습니다.

대조적으로, 좋은 단위 테스트는 너무 간단하게 독자로서 망치거나 오해 할 수 없습니다. 오타만이 "기대에 버그를 만들 수 있습니다. reverse([1 2 3]) 동일하게 [3 2 1]".

원래 게시물에 쓴 내용은이 문제를 상기시켜주었습니다.이 문제는 루프 불변이 루프를 정확하게 증명하는 것이 무엇인지에 대한 열린 질문입니다 ...

어쨌든, 나는 당신이 공식적인 사양에서 얼마나 많이 읽었는지 잘 모르겠지만, 당신은 그 생각을 내려 가고 있습니다. David Gries의 책은 주제에 관한 고전 중 하나이며, 나는 여전히 매일 매일 프로그래밍에서 빠르게 사용할 수있을만큼 개념을 마스터하지 않았습니다. 공식적인 사양에 대한 일반적인 반응은 어렵고 복잡하며 안전 중요 시스템을 연구하는 경우에만 노력할 가치가 있습니다. 그러나 나는 QuickCheck가 사용 할 수있는 것과 비슷한 봉투 기술의 등받이가 있다고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top