ETC

백준에서 Assert 메서드를 사용할 수 있을까?

SH3542 2024. 5. 28. 15:12
 

목차

 

     

    결론

    assert 키워드가 아닌, Error Class를 상속받는 무언가로 던져야한다. ex) AssertionError()

     

     

    개요

    백준을 풀다가 랭커들이 맞왜틀일 때 Assert 메서드로 입력값을 검증하는 경우를 보았다.

     

    물론, 대부분의 문제들은 제시한 범위 내의 입력만 주겠지만, 대회 문제 등 접한 사용자가 적은 문제는 출제자의 실수가 남아있을 수 있다.

     

    이 외 백준 문제에 기여할 때 유용하게 사용할 수 있다.

     

     

    Assert?

    - 일종의 검증 메소드이다. 정상적인 플로우에서 test false가 발생하면 안되는 논리식에 사용하여, 런타임 익셉션인 AssertException을 통해 잘못되었음을 찾아낸다.

     

    - 현대 JAVA에서는 Junit, Mockito와 같은 테스트 프레임워크등을 사용한다.

     

    - 디버깅 환경에서만 사용해야한다. 프로덕션 환경에서는 런타임익셉션으로 프로그램을 강제 종료시킬 수 있다.

     

     

    Java에서 사용하는 법

    백준에서 사용하는 것이 목적이므로, JavaSE 환경에서 별도의 설치없이 사용할 수 있는 방법이여야 한다.

     

    Java는 assert 키워드를 자체 제공한다. 하지만, 다음과 같은 코드는 예외가 발생하지 않는다.

     

    Java는 성능과 설계 의도를 이유로, 활성화 전까지 assert 키워드를 검증하지 않는다. 따라서 옵션을 추가해준다.

    -> Run/Edit Configurations.. 에서 현재 애플리케이션의 VM options에 -ea을 추가해준다. ( enableassertions의 준말)

     

    이후엔 정상적으로 테스트가 실패하는 것을 볼 수 있다.



    백준에서 사용할 수 있을까?

    예제 문제의 링크이다.

    https://www.acmicpc.net/problem/16394

     

    입력 값 N = (1,946 ≤ N ≤ 1,000,000) 일 때,

    N - 1946을 출력하는 브론즈5 문제이다.

     

     

    항상 N은 aasert 조건식을 false로 만드는 값만 주어진다. 그럼에도 맞았습니다!를 받았다.

    따라서, assert가 적용이 되지 않는다.

     

    자바는 -ea옵션 활성화 전까지 assert를 검증하지 않는다. 백준의 컴파일 환경도 마찬가지이다.

    또한, 백준은 온라인 저지 사이트 특성상 성능을 이유로 디버깅 옵션을 제공하지 않는다.

     

     

    다른 언어도 그런가? (C++)

     

    C++은 된다. Java와 달리 기본적으로 assert 검증을 하기 때문일 것이다.

     

     

    그렇다면 Java는 사용 못할까?

     

     

    된다! 근데 AssertException이 아닌 NZEC를 던진다. NZEC는 뭘까?

     

     

    백준에 따르면, NZEC(Non Zero Exit Code) 는 정상 종료 되지 않은 경우를 뜻한다.

    찾아본 결과, AssertionError은 Exit Code 1을 리턴한다. 고로 NZEC로 분류되는 것이였다.