바로투입이력카드
SAP 게시판

정보·팁

Clean ABAP ⑫ 테스트 설계: 원칙, 테스트 클래스, 의존성 주입

에이든ABAP 개발자운영자모듈 MMSD기타조회 2

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

아직 댓글이 없어요.

정보·팁 목록전체 목록