답변:
어설 션 은 프로그램의 내부 상태 를 알려주는 데 유용합니다 . 예를 들어, 데이터 구조가 유효한 상태 (예 : Time
데이터 구조가 값을 보유하지 않음)를 갖는 경우 25:61:61
. 주장에 의해 확인 된 조건은 다음과 같습니다.
발신자가 계약을 유지하도록하는 전제 조건
수신자가 계약을 유지하도록 보장하는 사후 조건
함수가 반환 된 후 데이터 구조가 항상 일부 속성을 보유하도록하는 불변량 불변은 전제 조건과 사후 조건 인 조건입니다.
단위 테스트 는 모듈의 외부 동작에 대해 알려주는 데 유용 합니다 . 귀하는 Stack
애프터 일관된 상태를 가질 수있다 push()
메서드가 호출되지만이 세 번 호출 된 후 스택의 크기가 세 증가하지 않는 경우, 그 오류입니다. (예를 들어, 잘못된 push()
구현이 어설 션 만 확인하고 종료 하는 사소한 경우 입니다.)
엄밀히 말하면 어설 션과 유닛 테스트의 주요 차이점은 유닛 테스트에는 테스트 데이터 (프로그램을 실행하는 데 필요한 값)가 있지만 어설 션은 그렇지 않다는 것입니다. 즉, 어설 션에 대해 동일하게 말할 수는 없지만 단위 테스트를 자동으로 실행할 수 있습니다. 이 논의를 위해, 당신은 고차 함수 테스트 (전체 프로그램을 실행하고 단위 테스트와 같은 모듈을 구동하지 않음)의 맥락에서 프로그램을 실행하는 것에 대해 이야기한다고 가정했습니다. "실제 입력을 보는"수단으로 자동화 된 기능 테스트에 대해 이야기하고 있지 않다면, 그 가치는 자동화에 있으며, 따라서 단위 테스트가 이길 것입니다. (자동) 기능 테스트의 맥락에서 이에 대해 이야기하고 있다면 아래를 참조하십시오.
테스트 대상에 약간의 중복이있을 수 있습니다. 예를 들어 Stack
의 사후 조건은 실제로 스택 크기가 1 씩 증가한다고 주장 할 수 있습니다. 그러나 해당 주장에서 수행 할 수있는 작업에는 한계가 있습니다. 또한 최상위 요소가 방금 추가 된 항목인지 확인해야합니까?
둘 다 목표는 품질을 높이는 것입니다. 단위 테스트의 목표는 버그를 찾는 것입니다. 어설 션의 목표는 유효하지 않은 프로그램 상태가 발생하자마자 관찰하여 디버깅을보다 쉽게 만드는 것입니다.
참고 도 기술은 정확성을 확인합니다. 실제로 프로그램이 올바른지 확인하기 위해 단위 테스트를 수행하면 제대로 작동 할 것이라는 흥미로운 테스트가 나올 것입니다. 그것은 심리적 효과입니다. 목표를 달성하기 위해 무엇이든 할 것입니다. 당신의 목표가 버그를 찾는 것이라면, 당신의 활동은 그것을 반영 할 것입니다.
둘 다 중요하며 자체 목적이 있습니다.
[어설 션에 대한 마지막 참고 사항 : 최대한의 가치를 얻으려면 몇 가지 주요 기능이 아니라 프로그램의 모든 중요 지점에서 사용해야합니다. 그렇지 않으면 문제의 원래 원인이 숨겨져 몇 시간 동안 디버깅하지 않고 감지하기 어려울 수 있습니다.]
어설 션에 대해 이야기 할 때는 스위치를 켤 때 끌 수 있습니다.
매우 잘못된 어설 션의 예 :
char *c = malloc(1024);
assert(c != NULL);
왜 이것이 나쁜가요? NDEBUG와 같은 정의로 인해 해당 어설 션을 건너 뛰면 오류 검사가 수행되지 않기 때문입니다.
단위 테스트는 위 코드에서 segfault 일 것입니다. 물론, 무언가 잘못되었다고 말함으로써 그 일을 했습니까? malloc()
테스트에서 실패 할 가능성은 얼마나 됩니까?
어설 션은 프로그래머가 '정상적인'이벤트로 어설 션이 발생하지 않음을 암시해야 할 경우 디버깅 목적으로 사용됩니다. malloc()
실패는 실제로 정상적인 사건이므로 절대로 주장해서는 안됩니다.
잘못 될 수있는 일을 적절히 처리하는 대신 어설 션을 사용하는 다른 많은 경우가 있습니다. 그렇기 때문에 어설 션의 평판이 나 빠지고 Go와 같은 언어에 포함되지 않은 이유가 있습니다.
단위 테스트는 변경 한 사항이 다른 항목을 위반 한 시점을 알려주기 위해 고안되었습니다. 빌드 할 때마다 프로그램의 모든 기능을 사용하지 않아도 (대부분의 경우) 테스터 가 릴리스에 중요합니다.
둘 사이에 어떤 일이 잘못되었다고 말해주는 것 외에는 둘 사이에 뚜렷한 상관 관계가 없습니다. 디버거를 사용하지 않고 어설 션을 작업중인 중단 점으로 생각하십시오. 단위 테스트는 당신 이하고 있지 않은 것을 깨뜨 렸는지 알려주는 것으로 생각하십시오 .
두 도구 모두 구축중인 시스템의 전반적인 품질을 향상시키는 데 사용되는 도구입니다. 사용하는 언어, 작성하는 응용 프로그램 유형 및 시간이 가장 많이 소비되는 위치에 따라 다릅니다. 말할 것도없이 당신은 그것에 대해 몇 가지 생각의 학교를 가지고 있습니다.
먼저 assert
키워드 없이 언어를 사용하는 경우 어설 션을 사용할 수 없습니다 (적어도 여기서 말하는 방식이 아님). 오랫동안 Java에는 assert
키워드 가 없었으며 여전히 많은 언어가 없습니다. 그러면 단위 테스트가 더욱 중요해집니다. 일부 언어에서는 어설 션이 플래그가 설정된 경우에만 실행됩니다 (여기서는 Java와 함께). 보호 기능이 항상있는 것은 아니지만 유용한 기능은 아닙니다.
당신이 무언가를 "어설트 (asserting)"한다면 if
/ throw
의미있는 예외 블록을 쓸 수도 있다고 생각하는 학교가 있습니다 . 이 사고 과정은 모든 값이 한계 내에 있도록 방법의 시작 부분에 배치 된 많은 주장에서 비롯됩니다. 사전 조건 테스트는 예상되는 사후 조건을 갖는 데 매우 중요한 부분입니다.
단위 테스트는 작성하고 유지해야하는 추가 코드입니다. 많은 사람들에게 이것은 단점입니다. 그러나 현재 단위 테스트 프레임 워크를 사용하면 비교적 적은 코드로 많은 수의 테스트 조건을 생성 할 수 있습니다. 매개 변수화 된 테스트와 "이론"은 수많은 데이터 샘플로 동일한 테스트를 수행하여 찾기 어려운 버그를 발견 할 수 있습니다.
개인적으로 뿌리를 뿌리는 것보다 단위 테스트를 통해 더 많은 마일리지를 얻는다는 것을 알았습니다. 그러나 그것은 대부분의 시간에 개발 한 플랫폼 (Java / C #) 때문입니다. 다른 언어는보다 강력한 어설 션 지원을 제공하며 "계약에 의한 설계"(아래 참조)를 통해 더 많은 보증을 제공합니다. 이러한 언어 중 하나를 사용하는 경우 단위 테스트보다 DBC를 더 많이 사용할 수 있습니다.
http://en.wikipedia.org/wiki/Design_by_contract#Languages_with_native_support
:-)