9. 🧪 테스트 및 디버깅
9.1 전자정부프레임워크 개발도구 소개
전자정부프레임워크 개발도구는 이클립스 기반의 통합개발환경(IDE)으로, 홍익인간CMS 개발 및 테스트를 위한 다양한 기능을 제공합니다.
9.1.1 개발도구 주요 기능
주요 기능
- 프로젝트 생성 및 관리: 전자정부프레임워크 기반 프로젝트 생성 및 관리
- 코드 템플릿: 표준 코드 템플릿 제공
- 디버깅 도구: 강력한 디버깅 기능 제공
- 테스트 도구: JUnit 기반 테스트 지원
- 배포 도구: 서버 배포 기능 제공
9.1.2 개발도구 설치 및 구성
전자정부프레임워크 개발도구는 이클립스 기반으로 제공되며, 다음과 같이 설치할 수 있습니다:
📥 개발환경 다운로드
전자정부프레임워크 포털(www.egovframe.go.kr)에서 개발환경 다운로드
📂 압축 해제
다운로드한 파일 압축 해제
🚀 실행
이클립스 실행 파일(eclipse.exe) 실행
9.2 개발도구 기반 테스트 방법
9.2.1 JUnit 테스트 작성 및 실행
전자정부프레임워크에서는 JUnit을 사용하여 단위 테스트를 작성하고 실행할 수 있습니다.
테스트 클래스 생성 방법
🎯 테스트 클래스 선택
테스트할 클래스에서 우클릭 > New > JUnit Test Case 선택
⚙️ 설정
테스트 클래스 이름 및 테스트할 메소드 선택
✅ 생성 완료
Finish 버튼 클릭하여 테스트 클래스 생성
[실제 코드] JUnit 테스트 클래스 예시
package humanframe.test.service;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import humanframe.backoffice.service.BbsService;
import humanframe.backoffice.vo.BbsVO;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
"classpath:humanframe/spring/context-common.xml",
"classpath:humanframe/spring/context-datasource.xml",
"classpath:humanframe/spring/context-mapper.xml"
})
public class BbsServiceTest {
@Autowired
private BbsService bbsService;
@Test
public void testSelectBbs() {
// 테스트 실행
BbsVO bbs = bbsService.selectBbs(1);
// 결과 검증
assertNotNull(bbs);
assertEquals(1, bbs.getBbsNo());
}
}
테스트 실행 방법
🎯 테스트 선택
테스트 클래스 또는 메소드에서 우클릭
▶️ 실행
Run As > JUnit Test 선택
📊 결과 확인
JUnit 뷰에서 테스트 결과 확인 (녹색: 성공, 빨간색: 실패)
9.2.2 테스트 커버리지 분석
이클립스에서 EclEmma 플러그인을 사용하여 테스트 커버리지를 분석할 수 있습니다.
EclEmma 사용 방법
🎯 테스트 선택
테스트 클래스 또는 메소드에서 우클릭
📊 커버리지 실행
Coverage As > JUnit Test 선택
📈 결과 확인
커버리지 결과 확인 (녹색: 커버, 빨간색: 미커버, 노란색: 부분 커버)
9.3 전자정부프레임워크 디버깅 방법
9.3.1 디버그 모드 실행
이클립스에서 디버그 모드로 애플리케이션을 실행하는 방법은 다음과 같습니다:
🚀 디버그 실행
프로젝트 우클릭 > Debug As > Debug on Server 선택
🖥️ 서버 선택
서버 선택 후 Finish 버튼 클릭
🔄 퍼스펙티브 전환
디버그 퍼스펙티브로 자동 전환
9.3.2 중단점(Breakpoint) 설정 및 관리
중단점 설정 방법
- 코드 편집기에서 중단점을 설정할 라인 왼쪽 여백 더블 클릭
- 또는 라인에서 우클릭 > Toggle Breakpoint 선택
중단점 유형
중단점 유형
- 라인 중단점: 특정 라인에서 실행 중지
- 조건부 중단점: 특정 조건이 충족될 때만 실행 중지
→ 중단점에서 우클릭 > Breakpoint Properties > 조건 입력 - 예외 중단점: 특정 예외 발생 시 실행 중지
→ Run > Add Java Exception Breakpoint 선택
중단점 관리
- 중단점 활성화/비활성화: 중단점에서 우클릭 > Enable/Disable
- 중단점 삭제: 중단점에서 우클릭 > Remove
- 모든 중단점 보기: Window > Show View > Breakpoints
9.3.3 디버깅 제어 기능
디버그 모드에서 실행을 제어하는 주요 기능은 다음과 같습니다:
| 기능 | 단축키 | 설명 |
|---|---|---|
| Resume | F8 | 다음 중단점까지 실행 |
| Suspend | - | 실행 중인 스레드 일시 중지 |
| Terminate | Ctrl+F2 | 디버깅 세션 종료 |
| Step Into | F5 | 현재 라인의 메소드 내부로 진입 |
| Step Over | F6 | 현재 라인 실행 후 다음 라인으로 이동 |
| Step Return | F7 | 현재 메소드 실행 완료 후 호출한 곳으로 복귀 |
| Drop to Frame | - | 현재 스택 프레임의 시작점으로 돌아감 |
9.3.4 변수 및 표현식 감시
변수 값 확인
변수 확인 방법
- Variables 뷰: 현재 스코프의 변수 값 표시
- Expressions 뷰: 사용자 정의 표현식 평가
→ Add Watch Expression 버튼 클릭하여 표현식 추가 - 마우스 오버: 변수에 마우스를 올려 값 확인
변수 값 변경
🎯 변수 선택
Variables 뷰에서 변수 선택
✏️ 값 변경
우클릭 > Change Value 선택
✅ 적용
새 값 입력 후 OK 버튼 클릭
9.3.5 스택 트레이스 분석
Debug 뷰 활용
- 현재 실행 중인 스레드 및 스택 트레이스 표시
- 스택 프레임 더블 클릭하여 해당 위치로 이동
- 스레드 상태 확인 (실행 중, 일시 중지, 종료 등)
스택 트레이스 분석 방법
📋 스택 트레이스 확인
예외 발생 시 콘솔 뷰에 출력된 스택 트레이스 확인
🔍 코드 부분 찾기
스택 트레이스에서 자신의 코드 부분 찾기
🐛 문제 파악
해당 라인으로 이동하여 문제 원인 파악
9.4 로깅 및 로그 분석
9.4.1 전자정부프레임워크 로깅 설정
전자정부프레임워크는 Log4j를 사용하여 로깅을 구현합니다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- 콘솔 출력 -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
</layout>
</appender>
<!-- 파일 출력 -->
<appender name="file" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${LOG_PATH}/humanframe.log" />
<param name="Append" value="true" />
<param name="DatePattern" value="'.'yyyy-MM-dd" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %5p [%c] %m%n" />
</layout>
</appender>
<!-- SQL 로그 -->
<logger name="jdbc.sqlonly" additivity="false">
<level value="INFO" />
<appender-ref ref="console" />
<appender-ref ref="file" />
</logger>
<!-- 애플리케이션 로그 -->
<logger name="humanframe" additivity="false">
<level value="DEBUG" />
<appender-ref ref="console" />
<appender-ref ref="file" />
</logger>
<!-- 루트 로거 -->
<root>
<priority value="INFO" />
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>
</log4j:configuration>
로그 레벨
| 레벨 | 설명 |
|---|---|
| FATAL | 심각한 오류, 애플리케이션 중단 |
| ERROR | 오류, 기능 실행 실패 |
| WARN | 경고, 잠재적 문제 |
| INFO | 정보, 주요 이벤트 |
| DEBUG | 디버그 정보, 상세 실행 정보 |
| TRACE | 가장 상세한 정보 |
9.4.2 로그 작성 방법
코드에서 로그를 작성하는 방법은 다음과 같습니다:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BbsServiceImpl implements BbsService {
private static final Logger logger = LoggerFactory.getLogger(BbsServiceImpl.class);
@Override
public BbsVO selectBbs(int bbsNo) {
logger.debug("게시판 조회: bbsNo={}", bbsNo);
try {
BbsVO bbs = bbsDAO.selectBbs(bbsNo);
logger.debug("게시판 조회 결과: {}", bbs);
return bbs;
} catch (Exception e) {
logger.error("게시판 조회 중 오류 발생: {}", e.getMessage(), e);
throw e;
}
}
}
9.4.3 이클립스에서 로그 파일 분석
이클립스에서 로그 파일을 분석하는 방법은 다음과 같습니다:
📂 로그 파일 열기
- File > Open File 메뉴 선택
- 로그 파일 선택 후 Open 버튼 클릭
🔍 로그 검색
- Ctrl+F 단축키로 검색 대화상자 열기
- 검색어 입력 후 Find 버튼 클릭
- 정규식 검색 활용 (예: ERROR|WARN)
🔧 로그 필터링
- 로그 뷰어 플러그인 설치 (LogViewer, EclipseLogViewer 등)
- 로그 레벨, 시간, 메시지 등으로 필터링
9.5 SQL 쿼리 디버깅
9.5.1 MyBatis 로그 설정
MyBatis 쿼리를 디버깅하기 위한 로그 설정 방법은 다음과 같습니다:
log4jdbc 설정
📦 의존성 추가
pom.xml에 의존성 추가:
<dependency>
<groupId>org.lazyluke</groupId>
<artifactId>log4jdbc-remix</artifactId>
<version>0.2.7</version>
</dependency>
🔧 DataSource 설정 변경
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="net.sf.log4jdbc.DriverSpy"/>
<property name="url" value="jdbc:log4jdbc:mysql://localhost:3306/humanframe"/>
<property name="username" value="username"/>
<property name="password" value="password"/>
</bean>
📝 log4j.xml에 로거 추가
<logger name="jdbc.sqlonly" additivity="false">
<level value="INFO"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.sqltiming" additivity="false">
<level value="INFO"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.audit" additivity="false">
<level value="WARN"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.resultset" additivity="false">
<level value="WARN"/>
<appender-ref ref="console"/>
</logger>
<logger name="jdbc.resultsettable" additivity="false">
<level value="INFO"/>
<appender-ref ref="console"/>
</logger>
9.5.2 SQL 맵 디버깅
MyBatis SQL 맵을 디버깅하는 방법은 다음과 같습니다:
📄 SQL 맵 파일 확인
- src/main/resources/humanframe/sqlmap/ 디렉토리에서 해당 SQL 맵 파일 열기
- SQL 쿼리 문법 확인
🔍 파라미터 확인
- 디버그 모드에서 중단점 설정
- Variables 뷰에서 파라미터 값 확인
📋 SQL 로그 확인
- 콘솔 또는 로그 파일에서 실행된 SQL 쿼리 확인
- 바인딩된 파라미터 값 확인
🔄 결과 매핑 확인
- 결과 객체의 필드와 SQL 결과 컬럼 매핑 확인
- 타입 변환 오류 확인
9.6 일반적인 오류 및 해결 방법
9.6.1 컴파일 오류
주요 컴파일 오류 및 해결 방법
- 클래스를 찾을 수 없음:
→ 원인: 클래스 경로 문제 또는 의존성 누락
→ 해결: 프로젝트 우클릭 > Maven > Update Project - 메소드를 찾을 수 없음:
→ 원인: API 변경 또는 라이브러리 버전 불일치
→ 해결: 메소드 시그니처 확인 및 라이브러리 버전 확인 - 구문 오류:
→ 원인: 잘못된 Java 구문
→ 해결: 코드 검토 및 수정
9.6.2 런타임 오류
주요 런타임 오류 및 해결 방법
- NullPointerException:
→ 원인: null 객체 참조
→ 해결: 객체 초기화 확인 및 null 체크 추가 - ClassNotFoundException:
→ 원인: 클래스 로딩 실패
→ 해결: 클래스 경로 확인 및 의존성 추가 - SQLException:
→ 원인: 데이터베이스 연결 또는 쿼리 오류
→ 해결: SQL 쿼리 및 데이터베이스 연결 설정 확인
9.6.3 웹 애플리케이션 오류
주요 웹 애플리케이션 오류 및 해결 방법
- 404 Not Found:
→ 원인: URL 매핑 오류 또는 리소스 누락
→ 해결: 컨트롤러 매핑 및 리소스 경로 확인 - 500 Internal Server Error:
→ 원인: 서버 측 예외 발생
→ 해결: 로그 파일에서 예외 스택 트레이스 확인 및 디버깅 - 400 Bad Request:
→ 원인: 잘못된 요청 파라미터
→ 해결: 요청 파라미터 검증 및 수정
9.7 디버깅 모범 사례
9.7.1 효율적인 디버깅 전략
🔄 문제 재현
- 문제를 일관되게 재현할 수 있는 방법 찾기
- 재현 단계 문서화
📋 로그 분석
- 로그 파일에서 오류 메시지 및 스택 트레이스 확인
- 로그 레벨 조정하여 상세 정보 수집
🎯 중단점 전략
- 문제 발생 지점 근처에 중단점 설정
- 조건부 중단점 활용
🔬 가설 검증
- 문제 원인에 대한 가설 수립
- 디버깅을 통해 가설 검증
9.7.2 디버깅 도구 활용 팁
디버깅 도구 활용 팁
- 조건부 중단점 활용:
→ 특정 조건에서만 중단되도록 설정
→ 반복문에서 특정 반복 횟수에서만 중단 - Watch 표현식 활용:
→ 복잡한 표현식 평가
→ 객체 상태 모니터링 - Hot Code Replace 활용:
→ 디버그 모드에서 코드 수정 후 즉시 적용
→ 디버깅 세션 재시작 없이 코드 변경 테스트 - 스레드 덤프 분석:
→ 교착 상태 또는 성능 문제 분석
→ Thread.getAllStackTraces() 메소드 활용
테스트 및 디버깅 핵심 포인트
- 체계적인 테스트: JUnit을 활용한 단위 테스트 작성
- 효율적인 디버깅: 중단점과 변수 감시를 통한 문제 해결
- 로그 활용: 적절한 로그 레벨과 메시지로 문제 추적
- 도구 활용: 전자정부프레임워크 개발도구의 고급 기능 활용
- 지속적 개선: 디버깅 경험을 통한 코드 품질 향상