DCI(Describe-Context-It) 패턴을 활용해 테스트 케이스의 가독성 향상시키기

lango·2024년 2월 4일
3
post-thumbnail

들어가며

 최근 사라마라라는 사이드 프로젝트 개발을 재미있게 하고 있어요. 프로젝트에서 저는 게시글 관련 비즈니스를 개발하고 있는데 테스트 코드를 작성하던 중, 무엇인가 불편하다면 불편한(?) 점을 발견했어요.

 위 사진의 테스트 케이스를 보면 잘 읽혀지시나요? 제가 짠 코드인데도 잘 읽혀지지 않는데 이 글을 읽으시는 여러분들은 더하겠죠. 해당 테스트 코드는 BDD 패턴의 Given-When-Then 방식으로 작성했어요. 테스트 케이스를 하나하나 개별적으로 살펴볼 때는 나쁘지 않은데, 클래스 단위의 테스트를 수행하거나 전체 테스트를 실행시켰을 때 테스트 케이스들이 한눈에 들어오지 않는다는 점이에요.

 뭐, 목표했던 테스트에 대한 내용에 대한 검증만 잘 되었으면 된 것 아니야? 라고 생각하고 넘어갈 수도 있지만, 추후 이 테스트를 수행해 보거나 테스트 코드를 읽어주실 리뷰어들을 생각하니 마음이 조금 불편했어요.

 저희 프로젝트 팀은 전체 테스트 수행 빈도가 생각보다 높아요. 그래서 테스트 수행 결과를 보여주는 Run 탭을 자주 주시하게 되는데, 보시다시피 테스트 케이스 명에 중복되는 용어나 문구가 많아서 가독성이 좋지 않아요. 그렇다고 테스트 케이스명(DisplayName)을 변경하거나, 불필요 테스트 케이스를 제거하자니 적지 않은 리소스가 들어갈 것 같아 고민은 더욱 깊어지기 시작했어요.

 그렇게 구글과 깃허브를 넘나들며, 여러 자료를 찾아보던 중 DCI 패턴으로 테스트 코드를 계층구조로 작성하는 방법에 대해서 알게 되었습니다. 바로 제가 원하던 내용이었어요. 테스트 케이스명에 기입해야 할 중복되는 용어나 문구를 줄이고 가독성 또한 늘려줄 것이라 예상되어 바로 DCI 패턴을 도입해 봤어요. 앞서 보여드렸던 테스트 케이스들이 얼마나 읽기 편해졌을까요?

 이번 글에서는 Given-When-Then 방식으로 작성된 테스트 케이스들을 DCI 패턴을 반영하여 여러 테스트 케이스들의 실행 결과를 한눈에 읽기 쉽도록 개선했던 과정에 대해서 이야기하려해요. 보시면 대단히 바뀐 것도 없고, 높은 난이도의 기술을 도입한 것도 아니에요. 그냥, 협업하는 동료의 코드 리딩 비용을 줄여줄 수 있을까라는 생각에서 시작된 이야기로 가볍게 봐주시길 바라겠습니다.




DCI(Describe-Context-It) 패턴이란?

 제가 DCI 패턴을 도입하여 테스트 케이스의 가독성을 증가시켰다고 말씀드렸는데, 먼저 DCI 패턴이 무엇인지는 알아야겠죠?

 DCI 패턴은 정확하게 하나의 테스트 메소드에 대한 행위를 검증하는 데 집중하며, 코드의 행동을 설명하는 테스트 코드를 작성하도록 도와줍니다. 그래서 상황이나 시나리오를 기반으로 테스트 케이스의 명확한 의도를 표현하는 Given-When-Then 방식과는 다르게, 실제 테스트 대상을 구체적으로 설명하는 테스트 케이스를 작성하는 데 집중할 수 있어요. 그렇다면 DCI 패턴의 핵심 키워드인 Describe, Context, It 세 단어에 대해서도 알아볼까요?

  • Describe: 설명해야 할 테스트의 대상을 명시합니다.
  • Context: 테스트를 위한 특정한 상황이나 조건을 설명합니다.
  • It: 실제 테스트를 수행하는 부분으로, 특정한 상황에서 기대하는 결과를 검증합니다. 즉 테스트 대상의 행위를 설명합니다.

💡 또 다른 DCI 패턴에 관련된 내용은 다른 분들의 글에서도 쉽게 찾을 수 있어요. 그중에서도 이종립님의 JUnit5로 계층 구조의 테스트 코드 작성하기 라는 글을 보시면 큰 도움이 될 겁니다.




테스트 케이스를 계층 구조로 정리하기

 이전에 GIven-When-Then으로 작성된 테스트 케이스들이 한눈에 잘 읽히지 않는다고 했는데, 그 이유 중 하나로 테스트할 상황에 대한 용어나 문구의 빈도수가 많은 것 때문이라고도 앞에서 정리했었어요. 그렇다면 어떻게 이 문제를 개선할 수 있을까요? 여기서 바로 DCI 패턴을 적용하여 자주 쓰이는 시나리오 문구의 중복을 줄일 수 있겠다 싶었어요. 일단 기존의 테스트케이스 이름만을 추려보자면 아래와 같아요.

#1 투표 타입의 게시글 생성 시, 이미지는 최소 2장 이상 등록해야 한다.
#2 투표 타입의 게시글 생성 시, 등록한 이미지가 1장일 경우 예외가 발생한다.
#3 투표 타입의 게시글 생성 시, 등록한 이미지가 5장을 초과할 경우 예외가 발생한다.
#4 찬반 타입의 게시글 생성 시, 이미지는 1장만 등록할 수 있다.
#5 찬반 타입의 게시글 생성 시, 등록한 이미지가 1장을 초과할 경우 예외가 발생한다.
#6 투표 타입의 게시글 수정 시, 이미지는 최대 5장까지 추가할 수 있다.
#7 투표 타입의 게시글 수정 시, 추가한 이미지가 5장을 초과할 경우 예외가 발생한다.
#8 투표 타입의 게시글 수정 시, 이미지는 2장까지만 삭제할 수 있다.
#9 투표 타입의 게시글 수정 시, 이미지를 2장 미만으로 삭제할 경우 예외가 발생한다.
#10 찬반 타입의 게시글 수정 시, 등록한 이미지 1장만 변경할 수 있다.
#11 찬반 타입의 게시글 수정 시, 추가한 이미지가 1장을 초과할 경우 예외가 발생한다.
#12 게시글 수정 시, 게시글 작성자만 수정할 수 있다.
#13 게시글 수정 시, 게시글 작성자가 아닐 경우, 수정할 수 없다.

 위 테스트 케이스들을 DCI 패턴을 통해 계층 구조로 고쳐보려 해요. 어떤 기준으로 계층 구조로 나열할 수 있을까요? 저는 다음과 같은 기준으로 계층 구조로 나열해 보았어요.

  • 단위 테스트이기에 Public 메서드의 주된 검증을 우선하자.
  • 계층 구조로 구분한 테스트 케이스는 각각 하나의 문장으로 읽을 수 있어야 해.
  • 가독성을 헤칠 정도로 테스트 케이스를 분리하지는 말자.

 위 3가지 기준을 두고 위 테스트 케이스들을 계층 구조 형식으로 변경하여 다시 작성해 보았어요.

#1 게시글 생성 시
	#1.1 투표 카테고리일 경우  
    	#1.1.1 이미지는 최소 2장 이상 등록해야 한다.
        #1.1.2 등록한 이미지가 1장일 경우 예외가 발생한다.
        #1.1.3 등록한 이미지가 5장을 초과할 경우 예외가 발생한다.
	#1.2 찬반 카테고리일 경우
    	#1.2.1 이미지는 1장만 등록할 수 있다.
        #1.2.2 등록한 이미지가 1장을 초과할 경우 예외가 발생한다.
#2 게시글 수정 시
	#2.1 작성자라면
    	#2.1.1 투표 카테고리의 글을 수정할 때
        	#2.1.1.1 이미지는 최대 5장까지 추가할 수 있다.
            #2.1.1.2 추가한 이미지가 5장을 초과할 경우 예외가 발생한다.
            #2.1.1.3 이미지는 2장까지만 삭제할 수 있다.
            #2.1.1.4 이미지를 2장 미만으로 삭제할 경우 예외가 발생한다.
		#2.1.2 찬반 카테고리의 글을 수정할 때
    		#2.1.2.1 등록한 이미지 1장만 변경할 수 있다.
            #2.1.2.2 추가한 이미지가 1장을 초과할 경우 예외가 발생한다.
	#2.2 게시글 작성자가 아닐 경우
    	#2.2.1.1 수정할 수 없다.

 어때요? 이전의 Given-When-Then 방식의 테스트 케이스 명보다는 쉽게 읽을 수 있지요? 물론, 이보다 더 잘 작성할 수도 있겠지만 기존의 용어 문구 중복을 줄일 수 있는 것만으로도 동료들에게 제가 작성한 테스트 케이스를 설명하기에는 충분하다는 생각이 들었어요.




@Nested 어노테이션 사용하기

 테스트 케이스를 계층화하여 정리를 완료하였으니, 이제 실제 테스트 코드에 반영해야 합니다. 저는 JUnit5를 이용해 테스트 코드를 작성했는데요. JUnit에서 계층 구조로 테스트 코드를 어떻게 작성할 수 있을까요?

 JUnit5 문서를 살펴보면 @Nested 어노테이션을 활용하여 계층 구조로 테스트 케이스를 구분하여 작성할 수 있다고 알려주고 있네요. 하위 요소로 작성할 테스트 케이스를 @Nested 어노테이션이 명시된 Inner Class로 작성하도록 안내하고 있으니 이대로 테스트 코드를 수정해 보면 되겠어요. 먼저 간단하게게시글 생성 시 투표 카테고리일 경우 이미지는 최소 2장 이상 등록해야 한다. 라는 테스트 케이스 하나를 작성해 볼까요?

class BoardTest {

    @Nested
    @DisplayName("게시글 생성 시")
    class Create_Board {

        @Nested
        @DisplayName("투표 카테고리일 경우")
        class Category_Is_Vote {

            @Test
            @DisplayName("이미지는 최소 2장 이상 등록해야 한다.")
            void it_returns_more_than_two_images() {
							...
            }

        }

    }

}

 위와 같이 테스트 케이스를 코드로 작성해보고 테스트를 수행했어요. 그리고 테스트를 수행하니 계층화된 테스트 수행 결과를 바로 확인할 수 있었습니다.

 테스트를 수행하여 정상 여부를 확인한 후, 나머지 테스트 케이스들도 마저 동일하게 작성해주었어요.

class BoardTest {
    @Nested
    @DisplayName("게시글 생성 시")
    class Create_Board {
        @Nested
        @DisplayName("투표 카테고리일 경우")
        class Category_Is_Vote {
            @Test
            @DisplayName("이미지는 최소 2장 이상 등록해야 한다.")
            void it_returns_more_than_two_images() {
                ...
            }
            @Test
            @DisplayName("등록한 이미지가 1장일 경우 예외가 발생한다.")
            void it_returns_exception_only_one_images() {
                ...
            }
            @Test
            @DisplayName("등록한 이미지가 5장을 초과할 경우 예외가 발생한다.")
            void it_returns_exception_more_than_five_images() {
                ...
            }
        }
        @Nested
        @DisplayName("찬반 카테고리일 경우")
        class Category_Is_Choice {
            @Test
            @DisplayName("이미지는 1장만 등록할 수 있다.")
            void it_returns_only_one_images() {
								...
            }
            @Test
            @DisplayName("등록한 이미지가 1장을 초과할 경우 예외가 발생한다.")
            void it_returns_exception_more_then_one_images() {
		            ...
            }
        }
    }
    @Nested
    @DisplayName("게시글 수정 시")
    class Update_Board {
        @Nested
        @DisplayName("작성자 라면")
        class When_Writer {
            @Nested
            @DisplayName("투표 카테고리의 글을 수정할 때")
            class Category_Is_Vote {
                @Test
                @DisplayName("이미지는 최대 5장까지 추가할 수 있다.")
                void it_returns_maximum_five_images() {
		                ...
                }
                @Test
                @DisplayName("추가한 이미지가 5장을 초과할 경우 예외가 발생한다.")
                void it_returns_exception_more_then_five_images() {
		                ...
                }
                @Test
                @DisplayName("이미지는 2장까지만 삭제할 수 있다.")
                void it_returns_less_then_two_images() {
					          ...
                }
                @Test
                @DisplayName("이미지를 2장 미만으로 삭제할 경우 예외가 발생한다.")
                void it_returns_exception_less_then_two_images() {
					          ...
                }
            }
            @Nested
            @DisplayName("찬반 카테고리의 글을 수정할 때")
            class Category_Is_Choice {
                @Test
                @DisplayName("등록한 이미지 1장만 변경할 수 있다.")
                void it_returns_only_one_images() {
										...
                }
                @Test
                @DisplayName("추가한 이미지가 1장을 초과할 경우 예외가 발생한다.")
                void it_returns_exception_more_then_one_images() {
					          ...
                }
            }
        }
        @Nested
        @DisplayName("작성자가 아니라면")
        class When_Not_Writer {
            @Test
            @DisplayName("수정할 수 없다.")
            void test() {
		            ...
            }
        }
    }
}

 위와 같이 나머지 테스트 케이스들도 모두 코드로 작성해주고 다시 테스트를 수행해보았어요.

 짠! 계획했던 대로 모든 테스트 케이스들의 테스트 수행 결과가 계층화되어 출력되는 것을 확인할 수 있었답니다.




@DisplayNameGeneration 어노테이션 사용하기

 @Nested 어노테이션을 통해 테스트 클래스를 중첩으로 구분하고 구분된 하위 계층 클래스 내부에 테스트 메서드를 작성해 볼 수 있었습니다. 그런데, 이전부터 오랜 시간이 걸리는 작업이 있었어요. 바로 테스트 메서드의 이름을 짓는 작명 작업인데요.

 보시다시피 현재 테스트 케이스의 @DisplayName은 한글로 표기했는데, 테스트 메서드명은 여전히 영어로 작명하고 있었어요. 한글로 표현되는 @DisplayName과 일맥상통하는 메서드명을 작명하는 것은 쉽지 않았어요. 거기다 영어 실력이 부족했기에, 대부분의 테스트 클래스와 메서드의 이름들을 원하는 뜻대로 작명했다고 볼 수 없었어요.

 이 때, @DisplayNameGeneration 어노테이션을 이용한다면, 클래스의 이름을 작명하는 비용을 대폭 줄일 수 있겠다 싶었어요. 그래서 한글로 표현했던 테스트 케이스가 곧 클래스와 메서드의 이름이 될 수 있도록 이왕에 일관성을 부여하기로 했으니, 메서드 이름도 @DisplayName과 동일하게 한글로 작성하고 공백을 언더바(_)로 바꾸어 작성했어요.

 자, 그러면 이번에도 게시글 생성 시 투표 카테고리일 경우 이미지는 최소 2장 이상 등록해야 한다. 라는 테스트 케이스에 대해서 @DisplayNameGeneration 어노테이션을 적용하여 클래스 이름을 해볼게요.

class BoardTest {

    @Nested
    @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
    class 게시글_생성_시 {
    
        @Nested
        @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
        class 투표_카테고리일_경우 {
        
            @Test
            @DisplayName("이미지는 최소 2장 이상 등록해야 한다.")
            void 이미지는_최소_2장_이상_등록해야_한다() {
                ...
            }
            
        }
        
    }
    
}

 @Nested로 구분한 테스트 클래스 상위에 @DisplayNameGeneration 어노테이션을 붙여 테스트 메서드명의 언더바(_)를 공백으로 변환하여 메서드명으로 부여하도록 해주었어요. 이를 위해서는 @DisplayNameGeneration 어노테이션에 DisplayNameGenerator.ReplaceUnderscores.class 설정을 해주어야 해요.

 테스트를 수행하니 의도한 대로 테스트가 수행되었어요. 이에 따라, 테스트 클래스와 테스트 메서드의 이름을 영어로 작명할 필요가 없어졌어요. 이제 나머지 테스트 케이스들도 동일하게 변경해 볼까요?

class BoardTest {
    @Nested
    @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
    class 게시글_생성_시 {
        @Nested
        @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
        class 투표_카테고리일_경우 {
            @Test
            @DisplayName("이미지는 최소 2장 이상 등록해야 한다.")
            void 이미지는_최소_2장_이상_등록해야_한다() {
								...
            }
            @Test
            @DisplayName("등록한 이미지가 1장일 경우 예외가 발생한다.")
            void 등록한_이미지가_1장일_경우_예외가_발생한다() {
                ...
            }

            @Test
            @DisplayName("등록한 이미지가 5장을 초과할 경우 예외가 발생한다.")
            void 등록한_이미지가_5장을_초과할_경우_예외가_발생한다() {
                ...
            }
        }
        @Nested
        @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
        class 찬반_카테고리일_경우 {
            @Test
            @DisplayName("이미지는 1장만 등록할 수 있다.")
            void 이미지는_1장만_등록할_수_있다() {
                ...
            }

            @Test
            @DisplayName("등록한 이미지가 1장을 초과할 경우 예외가 발생한다.")
            void 등록한_이미지가_1장을_초과할_경우_예외가_발생한다() {
                ...
            }
        }
    }
    @Nested
    @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
    class 게시글_수정_시 {
        @Nested
        @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
        class 작성자_라면 {
            @Nested
            @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
            class 투표_카테고리의_글을_수정할_때 {
                @Test
                @DisplayName("이미지는 최대 5장까지 추가할 수 있다.")
                void 이미지는_최대_5장까지_추가할_수_있다() {
                    ...
                }
                @Test
                @DisplayName("추가한 이미지가 5장을 초과할 경우 예외가 발생한다.")
                void 추가한_이미지가_5장을_초과할_경우_예외가_발생한다() {
                    ...
                }
                @Test
                @DisplayName("이미지는 2장까지만 삭제할 수 있다.")
                void 이미지는_2장까지만_삭제할_수_있다() {
                    ...
                }
                @Test
                @DisplayName("이미지를 2장 미만으로 삭제할 경우 예외가 발생한다.")
                void 이미지를_2장_미만으로_삭제할_경우_예외가_발생한다() {
                    ...
                }
            }
            @Nested
            @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
            class 찬반_카테고리의_글을_수정할_때 {
                @Test
                @DisplayName("등록한 이미지 1장만 변경할 수 있다.")
                void 등록한_이미지_1장만_변경할_수_있다() {
                    ...
                }
                @Test
                @DisplayName("추가한 이미지가 1장을 초과할 경우 예외가 발생한다.")
                void 추가한_이미지가_1장을_초과할_경우_예외가_발생한다() {
                    ...
                }
            }
        }
        @Nested
        @DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
        class 작성자가_아니라면 {
            @Test
            @DisplayName("수정할 수 없다.")
            void 수정할_수_없다() {
                ...
            }
        }
    }
}

 위와 같이 나머지 테스트 클래스에 대해서 @DisplayNameGeneration 어노테이션을 붙여주고, 테스트 메서드들의 메서드 이름도 한글화를 완료했어요. 마지막으로 테스트를 수행해 볼까요?

 정상적으로 계층화된 테스트 수행 결과를 볼 수 있었어요. 이번에는 테스트 이름 작명에 대한 비용과 시간을 대폭 줄일 수 있었네요.

테스트 케이스 내부까지 코드로 전달해 드리기엔 너무 길어서 의도적으로 생략했어요. 모든 테스트 코드 전문은 Github에서 찾아보실 수 있습니다.




DCI 패턴을 적용한 후!

DCI 패턴에 대한 이야기는 프로젝트의 테스트 코드 작성을 시작할 무렵부터 조심스럽게 몇 번 꺼냈었는데, 다행스럽게도 팀원분들 모두 DCI 패턴 도입을 호의적으로 바라봐주셨고, 적극적으로 리뷰해주셨어요.

🙋🏻‍♂️ Woogi
중복으로 설명할 수 밖에 없었던 테스트 행위에 대한 설명이 줄어들어 훨씬 보기 좋아졌네요! 👍

🙋🏻‍♂️ Sonny
given절도 재활용할 수 있고, 중첩 클래스별로 구분되어 있어서 독립적으로 설정할 수 있는 요소가 많아 사용하기 편해보여요. 잘 활용해보시죠!

그리고 두 분에게 받은 피드백 중 공통으로 언급주셨던 것들은 다음과 같아요.

  • 중첩 클래스를 활용해서 내부 클래스마다 독립된 테스트 환경을 구성할 수 있네요.
  • 영어 메소드 명을 작성하는 비용을 줄일 수 있다는 점이 좋아요.
  • 라인 수가 길어진다는 점은 어쩔 수 없이 감수해야 하네요.

DCI 도입에 대한 리뷰를 진행하며 또 저희 팀만의 테스트 컨벤션을 기록할 수 있었고, 어떻게 DCI 패턴을 적절하게 적용할 수 있을지와 같은 동기부여를 통해 테스트 리팩토링 계획도 조금이나마 세워볼 수 있었습니다.




DCI 패턴을 적용하며 궁금했던 점들!

 DCI 방식으로 테스트 케이스를 작성하면서 여러가지 궁금했던 점들이 여러 가지 생겼었는데, 그 중 의미있다고 느껴지는 내용 두 가지를 공유드리려 해요.


Q. 테스트 수행 순서를 꼭 지켜야 할까?

#1 게시글 생성 시
	#1.1 투표 카테고리일 경우  
    	#1.1.1 이미지는 최소 2장 이상 등록해야 한다.
        #1.1.2 등록한 이미지가 1장일 경우 예외가 발생한다.
        #1.1.3 등록한 이미지가 5장을 초과할 경우 예외가 발생한다.
	#1.2 찬반 카테고리일 경우
    	#1.2.1 이미지는 1장만 등록할 수 있다.
        #1.2.2 등록한 이미지가 1장을 초과할 경우 예외가 발생한다.
#2 게시글 수정 시
	#2.1 작성자라면
    	#2.1.1 투표 카테고리의 글을 수정할 때
        	#2.1.1.1 이미지는 최대 5장까지 추가할 수 있다.
            #2.1.1.2 추가한 이미지가 5장을 초과할 경우 예외가 발생한다.
            #2.1.1.3 이미지는 2장까지만 삭제할 수 있다.
            #2.1.1.4 이미지를 2장 미만으로 삭제할 경우 예외가 발생한다.
		#2.1.2 찬반 카테고리의 글을 수정할 때
    		#2.1.2.1 등록한 이미지 1장만 변경할 수 있다.
            #2.1.2.2 추가한 이미지가 1장을 초과할 경우 예외가 발생한다.
	#2.2 게시글 작성자가 아닐 경우
    	#2.2.1.1 수정할 수 없다.

 DCI 패턴을 도입하기로 마음먹고 나서 위 시나리오를 작성할 때, @TestMethodOrder를 활용해 게시글 생성(#1) 케이스부터 게시글 수정(#2) 케이스까지 순서대로 테스트가 수행되도록 하고 싶었습니다.

 그런데, @Nested 어노테이션을 명시한 클래스로 테스트 메서드가 구분되기에 테스트마다 @Order 어노테이션을 붙여서 수행 순서를 일일이 명시하는 것은 너무 번거롭다고 느꼈어요.

 또한, 지정한 테스트 수행 순서의 영향을 받게 되는 순간, 테스트의 독립성이 무너질 수도 있겠다 생각이 들었어요. 그래서 테스트 수행 순서와 상관없이 테스트를 수행하도록 하기 위해 수행 순서 관련 작업을 추가로 하지는 않았습니다.


Q. 테스트 픽스처는 어디에서 만들어야 할까?

 이렇게 테스트 케이스를 변경하고 나니, 모든 테스트 케이스의 given절에 동일한 회원 픽스처를 생성하고 사용하고 있었네요. 이러한 픽스처 구문의 중복을 줄이는 것이 좋을까요? 아니면 테스트 독립성을 지키자는 취지로 그대로 두는 것이 좋을까요?

 제가 작성한 테스트는 게시글(Board)의 단위 테스트였고, 게시글 관련 검증을 위해선 회원 픽스처가 필요했는데요. 그런데, 회원 픽스처는 게시글의 작성자로 매핑하는 것 외에는 특별한 책임을 가지고 있지 않았어요. 그래서 모든 메서드에서 만들고 있었던 회원 픽스처 생성 구문을 SetUp 메서드에서 명시하도록 수정했습니다.

 이전에는 테스트 메서드마다 명시되었던 회원(Member) 타입의 NORMAL_MEMBERSetUp에서 한번만 명시하도록 변경할 수 있었어요. 최상위 클래스의 SetUp에서 명시하지 않고, 생성, 수정 클래스에 각각 SetUp을 두었는데요. 그 이유는 생성과 수정시 회원 픽스처 변경 확장성을 무시할 수 없겠다 생각이 들어서에요.




마치며

 사실 Given-When-Then 방식에서 Describe-Context-It 방식으로 전환했다기보다는 테스트 케이스 가독성 향상이라는 목표를 달성하기 위해 기존 Given-When-Then 방식과 Describe-Context-It 방식을 함께 사용하는 방식으로 수정을 해보았어요. 직접 DCI 방식을 적용해보니, 얻을 수 있던 이점도 많았지만, 남용해서도 안된다는 것을 느꼈어요. 굳이 테스트 상황을 설명할 필요가 없거나, 문서화를 목적으로 하는 경우에는 굳이 DCI 방식을 적용할 필요가 없어보였기 때문이에요.

 그래서 단순히 가독성만을 늘리자고 모든 계층에서 DCI 방식을 남발하기 보다는 현재 상황에 사용하기 적절한지를 팀원분들과 충분히 논의하고 결정하는 것이 무엇보다 중요할 것 같아요.

🥰 이전 글까지는 문어체로 작성했었는데, 이번 글부터는 구어체로 작성해봤습니다. 제 글이 딱딱하지 않았으면 했는데, 무언가를 설명하는 느낌으로 글을 작성할 수 있어서 훨씬 더 재밌게 글을 작성해볼 수 있었네요. 당분간 이번 글과 동일한 방식으로 글을 작성할 예정입니다.




참고자료

profile
찍어 먹기보단 부어 먹기를 좋아하는 개발자

0개의 댓글