프로그래밍을 할 때 디버깅은 굉장히 중요하다. 자바 프로그래밍을 하다 보면 오류를 해결해야 할 때가 있는데, 이때 디버깅이라는 기술을 사용하면 오류를 쉽게 찾고 해결할 수 있다.
디버그와 디버깅에 대한 개념을 이해하고 VS Code를 사용하여 자바 프로그램을 디버깅하는 방법에 대해 알아보도록 하자.
💡디버깅 관련 개념
디버그와 디버깅
디버깅(debugging)은 프로그램이 예상대로 작동하지 않거나 오류가 발생했을 때 이를 해결하는 과정을 의미한다. 여기서 디버그(debug)는 버그(bug)를 찾아 잡는 것을 의미하며, 버그란 프로그램이 개발자의 의도와 다르게 동작하거나 예상치 못한 오류로 인해 실행이 중단되는 상황을 가리킨다. 디버깅을 이용하여 이러한 오류를 잡아낼 수 있다.
디버거
디버깅 도구 중 하나인 디버거(debugger)는 프로그램의 실행을 관찰하고 제어하는 데 사용된다.
디버거는 프로그램의 상태를 실시간으로 확인하고 코드 실행을 일시 중지하거나 특정 지점에서 실행을 재개할 수 있다. 이 과정에서 변수의 값을 확인하고 코드의 흐름을 따라가며 프로그램의 내부 상태를 자세히 이해하고 복잡한 문제를 해결하는 데 도움을 받을 수 있다.
디버깅은 디버거를 이용하여 코드의 어떤 부분에 문제가 초래되었는지 범위를 좁혀가면서 버그를 빠르게 찾아 명확하게 처리하는 것을 의미한다.
디버깅 단계
1. 오류 식별 단계
소프트웨어가 실행 중에 발생하는 오류를 식별하고 문제점을 보고한다. 이 과정에서 프로그래머는 사용자 보고서, 로그 파일 및 자체적인 테스트를 활용하여 오류를 찾아낸다.
2. 오류 분석 단계
발생한 오류의 원인을 찾아내고 문제를 해결하기 위한 계획을 세운다. 프로그래머는 코드를 검토하고 실행 중인 환경을 분석하여 오류가 발생한 이유를 파악한다.
3. 수정 및 검증 단계
오류를 수정하고 수정된 프로그램을 테스트하여 문제가 해결되었는지 확인한다. 이 과정에서 추가적인 테스트 케이스를 작성하거나 디버깅 도구를 활용하여 오류를 재현하고 확인할 수 있다.
💡테스트 케이스
테스트 케이스는 특정 기능, 성능, 또는 안정성 측면에서 소프트웨어가 예상대로 동작하는지를 검증한다.
테스트 케이스를 통해 소프트웨어의 예상 결과와 실제 결과를 비교하여 오류를 발견하고 이를 수정할 수 있다.
테스트 케이스 구분
기능 테스트 | 요구하는 목적을 만족하는지를 검증하는 테스트 |
도메인 테스트 | 경계값 분석 등 관계성을 지닌 복수의 변수를 동시에 검증하는 테스트 |
사양기반 테스트 | 설계서 및 메뉴얼과 같은 문서 상에 기술된 내용과 소프트웨어가 똑같은 지능을 가진지 검증하는 테스트 |
부하 테스트 | 최대 설계 부하와 그 이상의 부하를 검증하는 테스트 |
회귀 테스트 | 프로그램이 변경 되었을 때의 이상을 검증하는 테스트 |
사용자 테스트 | 사용자에게 실제로 사용하도록 하여 결함 및 사용성을 검증 하는 테스트 |
시나리오 테스트 | 예상되는 일반적인 사용법을 검증하는 테스트 |
상태전이 테스트 | 설정의 전이가 올바르게 변화하는지를 검증하는 테스트 |
탐색적 테스트 | 사전에 작성한 테스트 케이스를 따르지 않고 결과를 검증하는 테스트 |
랜덤 테스트 | 임의적으로 입력하고 조작하는 테스트 |
테스트 케이스 작성법
- 테스트 계획 검토 및 자료 확보
- 위험 평가 및 우선순위 결정
- 테스트 요구사항 정의
- 테스트 구조 설계 및 테스트 방법 결정
- 테스트 케이스 정의
- 테스트 케이스 타당성 확인 및 유지 보수
스프링에서는 JUnit이라는 프레임워크를 이용하여 테스트 케이스를 작성하고 테스트를 한다.
디버깅 단계의 수정 및 검증 단계에서 테스트 케이스에 대한 내용이 언급되어서 간략하게 설명하였는데, JUnit으로 단위 테스트를 하는 게 필수적이라고 생각하기 때문에 이에 대한 자세한 내용을 추후 추가하려고 한다.
💡디버깅 과정 한눈에 보기
간단한 프로그램을 만들어서 디버깅 과정을 확인해 보도록 하자.
테스트 클래스 생성
public class DebugTest {
public static void main(String[] args) {
int a = 0;
int b;
b = a + 1;
System.out.println("a: " + a);
System.out.println("b: " + b);
System.out.println("Hello, World!");
}
}
디버깅을 수행할 DebugTest 클래스를 작성하였다.
a는 0으로 초기화하였으며, b는 값을 할당하지 않았기 때문에 null인 상태로 a + 1 연산을 수행하고 출력하는 간단한 프로그램이다.
Run과 Debug 버튼
main 메서드 상단을 보면 Run | Debug가 있는 것을 확인할 수 있다. 이는 VS Code에서 디버깅을 할 수 있게 제공하는 기능이다.
Run 실행 결과
a: 0
b: 1
Hello, World!
Run 버튼을 누르면 위와 같이 결과가 출력된다.
Debug 시작하기
이제 디버깅을 해보도록 하자! 디버깅을 하려면 시작할 위치를 정해 주어야 한다.
자바는 JVM(자바 가상 머신)의 자바 인터프리터를 이용하여 한 줄씩 실행된다. 즉, 자바 바이트 코드로 작성되어 있는 실행 프로그램을 인터프리터가 한 줄씩 읽으면서 컴퓨터가 이해할 수 있는 2진 코드로 번역하고 실행하는 것이다.
Cannot evaluate because of compilation error(s): b cannot be resolved to a variable.
7번 라인에 중단점을 설정하여 프로그램을 b를 연산하는 코드 직전에 중단하였다.
7번 라인은 중단점이기 때문에 해당 식을 실행하지 않고 대기하는 상태에 진입한다. 그렇기 때문에 a+b에 대한 조사식을 확인하려고 할 때 "컴파일 오류로 인해 평가할 수 없으며, b를 변수로 확인할 수 없다"는 메시지가 출력된다.
중단점 (Breakpoints)
중단점은 디버깅 과정에서 코드 실행을 일시적으로 멈추게 하는 지점을 지정하는 도구이다.
중단점을 설정하면 프로그램이 해당 지점에 도달했을 때 실행이 멈추고, 개발자는 해당 지점에서 코드를 검사하거나 변수의 값을 확인할 수 있다.
조사식 (Watch expressions)
조사식은 디버깅 도구에서 제공되는 기능으로, 특정 변수나 표현식의 값을 실시간으로 확인하는 데 사용된다. 개발자는 조사식을 설정하여 프로그램이 실행되는 동안 특정 변수나 표현식의 값을 모니터링할 수 있다. 이를 통해 코드의 실행 과정을 따라가면서 변수의 값이나 표현식의 결과를 계속 확인하여 프로그램의 상태를 파악할 수 있다.
단위 실행하기
디버그 모드에서는 상단에 아이콘을 사용하여 디버깅을 진행할 수 있다.
첫 번째 아이콘 '계속(F5)' 버튼을 클릭하면 다음 중단점까지 실행을 하며, 두 번째 아이콘 '단위 실행(F10)' 버튼을 클릭하면 다음 라인을 실행한다.
a+b: 1
단위 실행 버튼을 클릭하여 다음 라인으로 넘어가면 7번 라인을 실행하여 a와 b값이 모두 할당되고, 조사식에서 a+b의 값 또한 잘 나타나는 것을 확인할 수 있다.
이와 같이 조사식을 활용하면 중간에 값이 잘 할당되고 있는지를 알 수 있다.
디버그 창 확인하기
첫 번째 변수에서는 변수에 값이 할당될 때마다 변수가 표기된다. 현재 지역(Local) 변수로 a에 0이, b에 1이 할당되어 있음을 알 수 있다.
조사식에서는 개발자가 직접 값을 넣어 식을 만들고 원하는 방식으로 할당된 값을 확인할 수 있다.
호출 스택에서는 현재 디버거가 DebugTest.main 즉, DebugTest 클래스의 main 메서드에서 실행되고 있음을 나타낸다. 프로그램이 복잡해지면 현재 어떤 모듈에서 실행 중이고 중단점이 걸린 상태인지를 여기서 확인할 수 있다.
마지막 중단점은 어느 위치에 중단점이 있는지를 확인할 수 있다. 체크 박스를 해제하면 중단점이 해제되므로 모든 소스를 찾아서 중단점을 제거할 필요 없이 체크박스로 해결할 수 있다.
중단점 편집
중단점 편집을 통해 중단점이 실행되는 조건을 추가할 수 있다.
만약 a가 2일 경우에만 중단점이 실행되도록 하고 싶다면 "a == 2"라는 조건을 추가하면 된다.
확인되지 않은 중단점
확인되지 않은 중단점(Unverified breakpoint)은 디버깅 도구에서 설정한 중단점이 실제로 실행 중인 프로그램에서 인식되지 않는 상태를 말한다.
일반적으로 중단점이 설정된 코드가 실행되지 않거나, 중단점이 설정된 위치에 해당하는 코드가 변경되어서 발생한다.
모든 라인에 중단점을 설정해 보면 코드가 작성되지 않은 빈 라인에서 확인되지 않은 중단점으로 설정되는 것을 확인할 수 있다.
참고 자료
디버그, 위키백과, 2023.09.16.
디버거, 위키백과, 2022.02.15.
디버깅이란 무엇인가요?, Learn Microsoft, 2024.01.12.
[자바]VSCode 에서 Java Debug 하는 방법, VisualStudioCode, 자바, 디버그, 디버깅, debugging, 신기한 연구소, 2023.12.22.
테스트케이스란?, How's the code, 2024.01.01.
[Test] 테스트 케이스(Test Case)란, 프로그래민, 2020.12.18.