저는 assert를 한번도 써본적이 없는데 이걸 쓸 경우 디버깅에 도움이 된다고 해서 써볼려고하는데요
assert가 오류가 있을 거 같은 부분에 코드를 추가해서 미리 캐치 한다는 거 같은데요
제가 약간 이해가 안되는게 만약 어떤 웹사이트를 파싱한다고 하고
index 에러가 날 거 같아서 index 에러가 날거 같은 부분에 assert 코드를 사용하면
테스트 중에 index에러가 나는지 확인할 수 있다는 거 잖아요
근데 만약 테스트 중에는 문제 없다가 나중에 파싱하는 사이트 구조가 바뀐다던가 하면 알 수 없는거 맞나요?
그리고 테스트 중에는 문제를 못잡다가 실제 릴리즈시에는 나타날 수 있는 경우도 많잖아요
우리가 개발 중 테스트 하는 거랑 실제 사용자랑 테스트 하는 거는 엄청난 차이가 있는 거고요
그래서 assert 코드가 그렇게 도움이 될까 하는 생각도 드는데 초보가 그런데 다른 분들은 어떻게 사용하고 계신가요?
panic("index is not 0);
}
라고 안쓰고
assert(index == 0);
라고 쓰면 되니(조건문 내용을 로그에 찍어줌) 디버깅시 편하다고 하는겁니다.
원하는 값이 아닌지에 대한 예외처리는 따로 하셔야죠
프로그램에서 버그라고 자명한 부분과 로직이 있다면, 처리해야지 .그부분에서는 assert를 사용하는게 아닙니다. (그러나....)
대표적인 예로,
본인이 어떤 api를 만들고,
그 api를 다른 팀원들에게 배포하는 의무를 가졌다고 칩시다.
팀원이 그 api를 사용하다가, 문서에 정의된 방식이 아닌, 다른 방식으로 호출할 경우(정말 흔합니다.)
1. 프로그램이 미정의 행동으로 이어질 줄 수 있다. 이때, assert문을 씁니다. 갑자기 전혀 다른 곳에서 down될 수 있습니다.
어떤 프로그램이 있습니다.,
잘못된 input 값이 입력되었습니다.
근데 이 프로그램이 처리가 됩니다.
결국 잘못된 output를 만들면, 전체로직에서 그 부분을 찾는 엄청난 시간을 소비하게 됩니다.
만약에 그부분이 메모리 주소와 참조와 관련된 거라면, 죽음이죠.
이때는 정의되지 않는 값에 대한 조건에 assert를 추가합니다.
다시 말하지만, 자명한 버그라는 부분이라면, 처리해야 하지만,
우리가 개발의 시간은 항상 짧기에..(ㅠㅠ), 급한 경우 버그 처리를 제때 할수 없다면,
최소한으로 assert를 넣는 경우도 있습니다.
assert를 쓰는 것은 논리를 코드로 만들었을 때 그 논리가 정확한지 확인하기 위해서 사용합니다. 즉 논리 오류를 찾아내는데 쓰이는 것입니다.
C 언어에서 assert는 디버깅 모드에서만 쓰입니다. 32비트 CPU가 나오기 전에 16비트 CPU에서는 실행파일 크기가 64kb밖에 안되는데 그런 검사를 넣을 공간이 없었고(인텔 16비트 CPU에서는 far pointer를 써서 20비트 주소를 쓰기는 했지만 불편했구요) 32비트 CPU(인텔 80386)이 나온 후에 주로 쓰이기 시작했는데 워낙 느려서 릴리스 모드에서는 제거하여 실행하지 않도록 했습니다. 80386이 33Mhz인데 AMD 5600G는 최대 클럭이 4.4 GHz라 현재 저렴한 CPU와 비교하면 0.75% 속도였으니까요.
그 이후의 많은 언어들이 별 생각없이 디버깅 모드에서만 사용한다는 제한을 따랐습니다. 하지만 지금은 그럴 필요가 거의 없는 시대가 되었구요. 임베디드 환경에서 16비트 CPU를 사용하는 경우는 아직도 그래야 할 것 같구요.
수학 계산을 아주 빠르게 해야 하는 경우에서는 이제 GPU를 사용한다던지 CPU의 최신 명령어를 사용하는 라이브러리를 사용한다던지 해서 릴리스 모드에서 사용안할 이유는 없습니다.
자바스크립트는 원래 디버깅 모드가 없으므로 제한 없이 사용하구요. C#은 Debug.Assert에 추가로 Trace.Assert를 넣어서 릴리스 모드에서도 쓰게 했습니다. 자바는 -ea를 넣어서 릴리스 모드에서 사용할 수 있게 했구요. 스위프트도 옵션을 바꾸면 가능할 것으로 보이구요.
지금은 속도의 문제는 해결 된 것으로 보입니다. 그래서 그냥 릴리스 모드에서도 쓰는 것을 권장합니다.
하지만 인터넷이 발달하면서 클라이언트-서버 구조가 만들어져서 서버는 멈추면 안되는 시대가 왔습니다. 그래서 서버에서는 use case만(요즘의 한 API 정도) 정지시키고 로그를 남기는 방식으로 처리해야 합니다. 그래서 assert의 전체를 멈춘다는 방식은 요즘 실행 서버에서는 맞지 않는 방식으로 보입니다. assert를 디버깅 모드에서 쓰고 그 다음에 예외를 던진다던지 귀찮으면 예외만 던지는 코드를 둔다던지 해야 합니다.
릴리스 모드에서 못 쓰는 경우라도 사용할 만한 가치가 있습니다. 단위 테스트도 모든 경우의 오류를 잡아내지는 못하지만 상당 부분 잡아내서 요즘에는 다 사용하는 것 처럼요. 오류를 줄일 수 있을 만큼은 줄여봐야 하니까요. 당시 assert를 널리 알렸던 책인 writing solid code나 code complete도 그런 점을 강조한 것이니까요.
어떤 값이 꼭 그 값이어야 함을 확인하는 것입니다.
디버깅이든 릴리즈든 유용하죠.
/Vollago