Java

[JAVA] assert 키워드

LimeCoding 2024. 4. 28. 17:23

Assert 키워드란?


 우리는 간단한 프로그램을 만들 때도 다양한 버그와 에러를 보게 된다. 예를 들어 입자 가속기 안에 있는 입자들의 속도를 구하는 프로그램을 만들었다고 해보자. 이 프로그램을 통해 입자의 속도를 측정했을 때 30만 km/s가 나온다면 이건 올바른 결과일까? 컴퓨터 내부에서는 계산을 통해 나올 수 있는 값이지만 논리적으로는 어떤 물체든 빛의 속도인 30만 km/s를 넘을 수 없다. 이와 같은 프로그램의 논리적 오류를 잡아내기 위해 사용하는 키워드가 바로 Assert 키워드이다.

 Assert 키워드는 JDK 1.4버전에서 처음으로 등장했다. 이 키워드는 내가 참이라고 생각하는 결과가 정말 참인지를 검증할 때 사용할 수 있다. 만약 참이면 문제가 없지만 거짓일 경우 AssertionError를 일으킨다.

 

Assert 키워드 사용 전 세팅


 

Assert 키워드를 사용하기 위해선 JVM에서 -ea 옵션을 설정해줘야 한다. IntelliJ를 기준으로 설명하려고 한다.

Run/ Debug Configuration > Edit Configuration > Modify options > VM arguments 항목을 찾아 -ea 입력

Run/ Debug Configuration

 

Modify options

Assert 키워드 사용법


Assert 키워드는 아래와 같이 2가지 형태로 사용할 수 있다.

  1. assert Expression1 ;
  2. assert Expression1 : Expression2 ;

 

1번과 같은 형태로 사용하는 경우, Expression1에 참 거짓을 결과로 가지는 수식을 넣어주면 된다. 2번은 1번과 동일한 형태로 사용하되, 추가적으로 Expression2에 정수, 문자열, 리턴 값이 있는 함수 등을 넣어 세부적인 메세지를 만들 수 있다. 이 메세지는 AssertionError를 만들 때 사용된다.

 여기서 재미있는 게 Expression2에 정수, 실수, 문자열과 같은 '값'을 넣게 되면 AssertionError가 나면서 해당 값을 이용해 메세지를 만드는 데 함수를 넣게 되면 해당 함수를 실행하고 에러를 보여준다. 이때 함수는 무조건 어떤 값이든 반환해야 한다. 이 말은 void 함수를 사용할 수 없다는 말과 같다.

 

// assert Expression1; 형태
assert 30 == 20;

// assert Expression1: Expression2; 형태
assert 30 == 20: func("오류");

 

 

 

Assert 키워드를 언제 사용하면 좋을까?


언제 사용하면 좋을까?

 Assert 키워드는 테스트 환경에서 사용하거나 프로덕트에 대한 일시적인 디버깅을 할 때 사용할 수 있다. 어떤 로직이 있을 때 로직의 결과가 예상한 결과와 같은지를 assert 키워드를 통해 알 수 있다. 디버깅 또한 같은 방식으로 코드 중간에 assert를 삽입하여 예상 결과와 디버깅 결과를 비교해 볼 수 있다.

 위 설명만 보면 if문을 사용하는 것과 별차이가 없어보인다. if문 또한 결과값을 비교할 수 있기 때문이다. 그러나 if문을 사용해 디버깅을 하면 다른 프로그래머가 로직 흐름을 이해하는 데 걸림돌이 될 수 있다. 또한 프로덕트로 만드는 과정에서 디버깅용 if문을 없애지 않으면 불필요한 CPU 사용이 생기므로 성능상에도 안좋은 영향을 미칠 수 있다.

 반면 assert의 경우 JVM 옵션을 통해 assert 키워드 사용을 켜고 끌 수 있기 때문에 테스트 환경과 프로덕트 환경을 분리할 수 있다. 뿐만 아니라 assert 키워드 자체가 테스트를 위한 키워드이기에 다른 프로그래머가 볼 때도 직관적으로 흐름을 이해할 수 있다.

 

언제 사용하지 말아야 할까?

 기본적으로 Assert는 로직에서 절대로 나와서는 안되는 결과가 나오는지 안나오는지 확인하기 위한 테스트용 키워드이다. 그렇기 때문에 데이터베이스 연결 또는 stackoverflow와 같은 자바의 근본적인 에러는 Assert로 하지 않는 게 좋다. 이런 종류의 에러는 해당 에러의 발생 원인에 따라 각각 다른 조치를 취해야 하는데 Assert를 사용하는 경우 AssertionError만 보내기 때문이다.

 유저의 입력을 검증하는 데 사용하는 것도 좋지 않다. 유저 입력을 XSS 공격이나 SQLInjection을 방어하기 위해 assert로 검사할 수 있지만 그 이외의 전화번호 형태나 비밀번호 길이와 같은 조건을 assert로 검사하는 건 좋은 방법은 아니다. 이런 에러들은 각 문제에 따라 다른 예외를 발생시켜 적절하게 처리하는 게 더 좋은 방법이다.

 

JVM 기본 설정에서 assert를 끄는 이유


assert는 조건이 거짓일 때 AssertionError를 반환하면서 프로그램을 종료시킨다. 이는 프로그래머에게 해당 구간에서 심각한 오류가 발생했다는 것을 프로그램 종료를 통해 알리도록 설계되었기 때문이다. 만약 실제 환경에서 갑자기 종료가 된다면 치명적인 문제가 발생할 가능성이 있다.

 

참고문헌