Assert () 메소드의 기능은 무엇입니까? 여전히 유용합니까?


156

중단 점으로 디버깅하고 어설 션 호출을 알고 있습니까? 나는 그것이 단위 테스트만을위한 것이라고 생각했다. 중단 점 이상의 기능은 무엇입니까? 중단 점을 사용할 수 있으므로 Assert를 사용해야하는 이유는 무엇입니까?


9
그건 그렇고, 당신이 주장에 관심이 있다면 분명히 코드 계약을 탐구해야합니다 .
MasterMastic

답변:


200

디버그 컴파일 Assert에서 부울 조건을 매개 변수로 사용하고 조건이 false 인 경우 오류 대화 상자를 표시합니다. 조건이 true이면 프로그램이 중단없이 진행됩니다.

Release에서 컴파일하면 모든가 Debug.Assert자동으로 제거됩니다.


12
릴리스 모드에서 Debug.Assert의 동일한 동작을 어떻게 얻을 수 있습니까?
Hamish Grubijan

15
릴리스 모드에 대한 Trace.Assert는 명백히 참조 : msdn.microsoft.com/en-us/library/… msdn.microsoft.com/en-us/library/e63efys0.aspx
Tim Abell이

8
@HamishGrubijan 그리고 왜 Debug.Assert릴리스 모드로 하시겠습니까?
Camilo Martin

25
릴리스 코드에서 주장을 생략하는 IMO는 도킹 된 상태에서 구명정 훈련을 실시한 다음 항해 할 때 구명정을 남겨 두는 것과 같습니다. :)
chrisd

113
주장은 구명정이 아니며 빙산 탐지 시스템입니다. 사용자가 함선을 조종하지 않기 때문에 릴리스 코드의 주장은 그들이 파멸되었다고 알려줍니다. 그들은 빙산을 피할 수 없습니다.
Stefan

97

에서 코드 완성

8 방어 프로그래밍

8.2 주장

어설 션은 개발 중에 사용되는 코드 (일반적으로 루틴 또는 매크로)로 프로그램이 실행될 때 자체적으로 확인할 수 있습니다. 어설 션이 true이면 모든 것이 예상대로 작동한다는 의미입니다. False이면 코드에서 예기치 않은 오류가 감지되었음을 의미합니다. 예를 들어, 시스템에서 고객 정보 파일에 레코드가 50,000 개를 넘지 않는다고 가정하면 프로그램에 레코드 수가 50,000보다 작거나 같다는 주장이 프로그램에 포함될 수 있습니다. 레코드 수가 50,000보다 작거나 같은 한 어설 션은 자동입니다. 그러나 50,000 개가 넘는 레코드가 발생하면 프로그램에 오류가 있다고 크게 "어설트"합니다.

어설 션은 특히 크고 복잡한 프로그램과 안정성이 높은 프로그램에 유용합니다. 이를 통해 프로그래머는 불일치 한 인터페이스 가정, 코드 수정시 발생하는 오류 등을보다 신속하게 제거 할 수 있습니다.

어설 션은 일반적으로 두 가지 인수를 사용합니다. 참이라고 가정하는 가정을 설명하는 부울 식과 그렇지 않은 경우 표시 할 메시지입니다.

(…)

일반적으로 사용자는 프로덕션 코드에서 어설 션 메시지를 보지 않기를 원합니다. 어설 션은 주로 개발 및 유지 관리 중에 사용됩니다. 어설 션은 일반적으로 개발시 코드로 컴파일되고 프로덕션 코드에서 컴파일됩니다. 개발 중에 어설 션은 모순 된 가정, 예기치 않은 조건, 잘못된 값이 루틴에 전달되는 등을 제거합니다. 생산하는 동안 어설 션이 시스템 성능을 저하시키지 않도록 코드에서 컴파일됩니다.


2
Writing Solid Code라는 책에는 assert 사용법에 대한 훌륭한 토론이 있습니다. 그들은 훌륭한 디버깅 도구입니다!
zooropa

39

변수를 확인하기 위해 모든 작은 코드 줄을 중단하지 않으려는 경우에 사용해야하지만 특정 상황이있는 경우 일종의 피드백을 원합니다. 예를 들면 다음과 같습니다.

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");

위와 비슷한 코드 줄을 추가하면 프로그램을 실행하면 "오류 CS0103 : 현재 컨텍스트에 'Debug'라는 이름이 없습니다"라는 오류가 발생합니다. 작동시키기 위해 일종의 사용 문장이 필요합니까?
Josh Desmond

4
@JoshDesmondSystem.Diagnostics
Sinjai

16

Assert는 Microsoft의 UI 디자인 기술을 익힐 수있는 또 다른 기회를 제공합니다. 의미 : 중단, 다시 시도, 무시 및 세 개의 버튼이있는 대화 상자와 제목 표시 줄에서 해석하는 방법에 대한 설명!


3
중단 / 재시도 / 무시는 고전입니다! Windows 3.1에서이 오류를 항상 표시하는 데 사용한 어설 션입니까?
devlord

기본적으로 Windows 3.1로 거슬러 올라가며 미리 정의 된 단추 레이블 만있는 MessageBox를 사용하기 때문입니다. 따라서 해킹이 발생한 이유를 이해할 수 있지만 2008 년에 여전히 존재하는 이유는 알 수 없습니다!
Joe

4
@Joe 이것은 최종 사용자가 아닌 개발자 만 볼 수있는 것으로, 업데이트하는 것이 우선 순위가 매우 낮은 항목 일 수 있습니다. 방해가되는 경우 Debug.Listeners 또는 Trace.Listeners 컬렉션을 수정하여 기본 처리기를 원하는 작업으로 대체 할 수 있습니다.
Dan Is Fiddling By Firelight

5
그리고 이제 2019 년이며 동일한 대화 상자 / 버튼이 여전히 있습니다!
Bouke

10

Assert를 사용하면 코드에 조건 (포스트 또는 프리)을 적용 할 수 있습니다. 의도를 문서화하고 의도가 충족되지 않으면 디버거가 대화 상자를 통해 알려주는 방법입니다.

중단 점과 달리 Assert는 코드와 함께 제공되며 의도에 대한 추가 정보를 추가하는 데 사용할 수 있습니다.


10

Assert를 사용하면 테스트와 릴리스간에 별도의 메시징 동작을 제공 할 수 있습니다. 예를 들어

Debug.Assert(x > 2)

릴리스 빌드가 아닌 "디버그"빌드를 실행중인 경우에만 중단을 트리거합니다. 여기 에이 동작의 전체 예가 있습니다.


10

첫째 Assert()방법은 사용할 수 있습니다 TraceDebug클래스.
Debug.Assert()디버그 모드에서만 실행 중입니다.
Trace.Assert()디버그 및 릴리스 모드에서 실행 중입니다.

예를 들면 다음과 같습니다.

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

이 코드를 디버그 모드에서 실행 한 다음 릴리스 모드에서 실행하십시오.

여기에 이미지 설명을 입력하십시오

디버그 모드에서 코드 Debug.Assert문이 실패하면 응용 프로그램의 현재 스택 추적을 보여주는 메시지 상자가 나타납니다. Trace.Assert()조건이 true 이므로 해제 모드에서는 발생하지 않습니다 (i == 4).

WriteLine() method는 단순히 Visual Studio 출력에 정보를 기록하는 옵션을 제공합니다. 여기에 이미지 설명을 입력하십시오


5

Assertions는 Design by Contract (DbC)에서 많은 부분을 차지하고 있는데, 제가 이해 한 것처럼 Bertand Meyer가 소개 / 승인했습니다. 1997. 객체 지향 소프트웨어 참조.

중요한 기능은 부작용을 일으키지 않아야한다는 것입니다. 예를 들어 예외를 처리하거나 if 문 (방어 프로그래밍)으로 다른 조치를 취할 수 있습니다.

어설 션은 계약의 사전 / 사후 조건, 고객 / 공급자 관계를 확인하는 데 사용됩니다. 고객은 공급 업체의 사전 조건이 충족되는지 확인해야합니다. 5 파운드를 보내면 공급 업체는 사후 조건이 충족되는지 확인해야합니다. 12 장미를 제공합니다. (클라이언트 / 공급자에 대한 간단한 설명만으로도 더 많이 수용하고 더 많이 제공 할 수 있지만 어설 션에 대해서는 설명 할 수 있습니다). C #에는 릴리스 코드에 사용할 수있는 Trace.Assert ()도 도입되었습니다.

그렇다. 우리는 여전히 그것들을 사용해야합니까? 예, 우리 모두 사용할까요? 아마도 마이어가 묘사하는 방식이 아닐 수도 있습니다.

(내가이 기술을 배운 OU Java 코스조차도 간단한 예제 만 보여 주었고 나머지 코드는 대부분의 코드에서 DbC 어설 션 규칙을 시행하지 않았지만 프로그램 정확성을 보장하는 데 사용되었다고 가정했습니다!)


3

내가 생각하는 방식은 Debug.Assert는 메서드가 호출되는 방식에 대한 계약을 설정하는 방법으로 매개 변수 대신 유형의 값에 대한 세부 사항에 중점을 둡니다. 예를 들어, 두 번째 매개 변수에 null을 보내지 않으려면 해당 매개 변수 주위에 Assert를 추가하여 소비자에게하지 말라고 지시하십시오.

그것은 누군가가 당신의 코드를 뼈대로 사용하는 것을 막습니다. 그러나 그것은 또한 당신이 릴리스 빌드를 구축한다고 가정 할 때, 골치 아픈 방법으로 생산을 진행하고 고객에게 불쾌한 메시지를 전하지 못하게합니다.


6
그러나 공용 메소드에서 유효하지 않은 매개 변수는 인수 예외를 발생시켜야한다는 점을 지적하는 것이 중요합니다. 개인 메소드 만이 어설 션을 사용하여 입력의 유효성을 검증해야합니다. 외부에서 들어오는 가치는 항상 의심됩니다!
Jeffrey L Whitledge
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.