Clean ABAP ⑫ 테스트 설계: 원칙, 테스트 클래스, 의존성 주입
3줄 요약
테스트할 수 있는 코드를 먼저 만들고, 공개(public) 부분만 테스트하며, 커버리지 숫자에 집착하지 않아요.
유닛 테스트는 대상 클래스의 로컬 테스트 인클루드에 두고, 의존성은 생성자로 주입해요(세터, FRIENDS 주입은 피해요).
목(mock)은
cl_abap_testdouble부터 써 보고, 테스트 심(seam)은 임시 우회책으로만 써요.
어떤 상황에서 쓰나요
"테스트를 쓰고는 싶은데 레거시라 못 쓰겠다"는 이야기가 나올 때 기준이 되는 장이에요. 이 연재의 12, 13회는 Clean ABAP 의 테스트 장을 둘로 나눠요. 이번 회는 구조와 주입, 다음 회는 테스트 메서드, 데이터, 단언을 다뤄요.
핵심 내용
원칙
자동으로 테스트할 수 있게 코드를 써요. 그러려면 리팩터링이 필요하면 새 기능보다 먼저 해요. 레거시에 코드를 더한다면 적어도 내가 더한 부분은 테스트할 수 있을 만큼 정리해요.
다른 사람이 나를 목(mock)으로 바꿀 수 있게 해요. 바깥에 보이는 곳마다 인터페이스를 두고, 테스트 더블이나 설정 대체 수단을 제공해요.
테스트 코드는 운영 코드보다 더 읽기 쉽게 써요. 나쁜 운영 코드는 좋은 테스트로 다스릴 수 있지만, 테스트마저 없으면 길을 잃어요.
$TMP에 오브젝트를 복사해 두고 만져 보거나, 손으로 반복 실행하는 테스트 리포트를 만들지 않아요. 그 리포트를 단언이 있는 유닛 테스트로 자동화하는 것이 다음 단계예요(원문의 "가난한 사람의 테스트").공개 부분을 테스트하고, private 내부는 테스트하지 않아요. private 메서드를 테스트하고 싶다는 충동은 설계 결함의 신호일 수 있어요. 클래스 안에 별개의 개념이 묻혀 있지 않은지, 도메인 로직과 접착 코드를 안 나눴는지(BOPF 액션이나 Gateway 의
*_DPC_EXT에 로직을 직접 쓰는 경우), 인터페이스가 너무 복잡한지 물어보라고 해요.커버리지는 빠뜨린 테스트를 찾는 도구이지 KPI 가 아니에요. 단언 없는 가짜 테스트로 숫자를 채우지 말아요.
테스트 클래스
로컬 테스트 클래스 이름은 "when"(
ltc_<공개 메서드 이름>)이나 "given"(ltc_<공통 준비 상태>)으로 지어요.ltc_test나 대상 클래스 이름 반복은 정보가 없어요.유닛 테스트는 대상 클래스의 로컬 테스트 인클루드에 두어 리팩터링하는 사람이 바로 찾고 한 번에 실행할 수 있게 해요. 컴포넌트, 통합, 시스템 테스트는 따로 전역 클래스의 로컬 테스트 인클루드에 두고, 그 전역 클래스를
FOR TESTING과ABSTRACT로 해서 운영 코드가 참조하지 못하게 해요."! @testing recruting같은 테스트 관계를 달면 해당 클래스에서 Shift+Ctrl+F12 (macOS는 Cmd+Shift+F12)로 테스트를 실행할 수 있어요.여러 테스트 클래스가 쓰는 도움 메서드는 상속이나 위임으로 도움 클래스에 모아요.
ADT 단축키: Ctrl+Shift+F9(전체 미리보기), F10(클래스의 테스트 실행), F11(커버리지 포함), F12(테스트 관계로 걸린 다른 클래스의 테스트까지). macOS 는 Cmd 예요.
테스트 대상 코드(CUT)
변수 이름은
blog_post,empty_blog_post처럼 의미 있게 짓고, 마땅한 이름이 없으면cut(code under test)으로 두어도 돼요.clean_fra_blog_post처럼 클래스 이름을 되풀이하지 않아요.대상 변수의 타입은 클래스가 아니라 인터페이스로 해요.
호출에 필요한 파라미터가 많으면 기본값을 채워 주는 도움 메서드(
map_xml_to_itab)로 호출을 뽑아내요.
주입
의존성 역전은 모든 의존성을 생성자에 넘기는 것이에요. 세터 주입(
set_customizing_reader)은 운영 코드를 의도하지 않게 쓰이게 하고,FRIENDS주입은 운영용 의존성을 먼저 만들어 버리고 내부 이름이 바뀌면 깨지며 생성자 초기화를 건너뛰어서 피해요.테스트 더블은
cl_abap_testdouble부터 써 봐요. 직접 만든 테스트 클래스보다 짧고 이해하기 쉬워요. 사용 가능한 도구와 예제는SAP-samples/abap-test-isolation-examples저장소에 있어요.테스트 심(
TEST-SEAM)은 다른 방법이 다 안 될 때, 레거시를 리팩터링하기 위한 임시 우회책으로만 써요. 침습적이고 private 의존성과 얽혀 오래 못 가요.CREATE PRIVATE클래스의 의존성 역전 생성자는LOCAL FRIENDS로 접근해요. 단LOCAL FRIENDS로 private 멤버에 목 데이터를 심는 것은 내부 구조가 바뀌면 깨지므로 하지 않아요.운영 코드에
IF is_unit_test_running = abap_true.같은 테스트 전용 기능을 넣지 않아요. 시뮬레이션 전기 같은 사용자용 테스트 기능은 도메인의 일부라 괜찮아요.목을 만들려고 서브클래스를 만들어 메서드를 재정의하지 않아요. 깨지기 쉽고 실제 소비자가 상속할 길도 열어 버려요. 대신 다른 테스트 도구를 쓰거나 문제 메서드를 인터페이스 있는 별도 클래스로 빼요.
필요 없는 것은 목으로 만들지 않고, 필요 없는 데이터도 채우지 않아요. 부작용 없는 데이터 컨테이너는 목 없이 운영용을 그대로 써도 돼요.
테스트 케이스 ID 로 데이터를 고르는 테스트 프레임워크를 만들지 않아요. 유닛 테스트는 데이터를 넣으면 데이터가 나오는 구조로 필요한 데이터를 그 자리에서 정의해요.
주의할 점
가이드는
cl_abap_testdouble, ABAP Unit 이 있는 릴리스를 전제로 해요. 어느 릴리스부터 쓸 수 있는지는 원문에 적혀 있지 않아서 쓰기 전에 대상 시스템에서 확인하세요.테스트 심과 서브클래스 목에 대한 의견은 레거시 현실과 충돌할 수 있어요. 가이드는 "서브클래스 목은 깨지기 쉽고, 테스트 심은 같이 깨지기 쉽지만 운영 동작은 안 바꾸므로 더 깨끗하다"는 순서로 말해요.
원문은 2019년 첫 공개, 2025년 3월 마지막 수정본이에요. 이 글은 읽고 정리한 것이고 예제를 직접 돌려 보지는 않았어요.
원문 주소: https://github.com/SAP/styleguides/blob/main/clean-abap/CleanABAP.md#testing
출처와 이용 안내
원문: Clean ABAP - Testing: Principles, Test Classes, Code Under Test, Injection · 작성자 SAP SE and contributors SAP/styleguides · 작성일 2019-05-01 · 기준 릴리스 무관 ABAP Unit, cl_abap_testdouble 사용 가능한 릴리스 · 확인일 2026-10-25
이 글은 위 원문을 읽고 한국어로 요약·재구성한 글이며 번역본이 아니에요. 원문의 저작권은 작성자와 SAP에 있어요.
원문은 CC BY 3.0 라이선스(https://creativecommons.org/licenses/by/3.0/)로 공개된 자료예요. 이 글은 내용을 한국어로 줄이고 순서를 바꾼 변경본이며, 원저작자가 이 글을 보증하지 않아요.
설정과 화면은 릴리스마다 달라요. 적용하기 전에 원문과 SAP Help Portal, 관련 SAP Note에서 최신 내용을 확인해 주세요.
SAP와 SAP 제품명은 SAP SE의 상표예요. 바로투입은 SAP와 관련이 없어요.
댓글 0
아직 댓글이 없어요.
로그인하고 댓글 쓰기