kok202
스프링 테스트 코드 전환기 근황2 (2/2): 작업 방식과 규칙

2021. 12. 19. 23:26[개발] 기록/스프링 테스트 코드 전환

비욘세 규칙과 BDD

구글의 소프트웨어 엔지니어링이라는 책을 읽다보면 비욘세 규칙이라는 말이 나옵니다. 비욘세의 노래 Single ladies 중 가사 Cause if you like it, then you shoulda put a ring on it (네가 나를 좋았다면 프로포즈를 해줫어야지) 라는 내용에서 기인한 규칙이라는데요. 이걸 테스트 코드 작성과 연결해서 생각한다고 합니다. 구글에서 말하는 비욘세 규칙은 "필요했으면 테스트 했었어야지" 정도로 의역할 수 있을 것 같습니다. 

책에서는 비욘세 규칙을 설명하면서 구글의 인프라 팀이 이 규칙을 활용해서 얻을 수 있었던 장점에대해 이야기합니다. 보통 인프라팀은 사내에 있는 대부분의 코드 베이스와 연관되어있고 긴밀한 협력관계에 있는 팀입니다. 따라서 인프라팀에서 어떤 변경이 있을 때 여러 팀에 영향을 줄 수도 있는데, 이러한 부작용들을 미리 알아내고 막기 위해선 모든 팀들과 한번씩 이야기하는 자리가 필요할겁니다. 그렇다면 여기에 낭비되는 엔지니어링 비용은 어마어마할 것이고, 결과적으로 인프라팀에서는 변경사항을 적용하려해도 자유롭게 할 수 없을겁니다.

인프라팀은 여기에 비욘세 규칙을 적극적으로 활용한다 합니다. "우리는 이런 변경을 할건데, 사내에 있는 테스트코드를 돌려볼거야. 테스트 코드에서 에러를 검출하지 못한다면, 변경해도 되는 것으로 알게." 라는 말입니다. 즉 "의존체에 변경되어선 안되는 항목이 있었다면, 그것 역시 테스트해라." 정도로도 해석이 되겠네요. 

 

이번에 테스트 코드 전환을 하면서 역시 가급적이면 이 비욘세 규칙을 적용하려 하였습니다. 구글에서 말하는 비욘세 규칙은 계약이 존재하는 모든 인터페이스에 사용될 수 있는 규칙이라고 생각합니다. 따라서 테스트 코드를 작성할 때 단순히 결과물의 상태 변경을 감지하는 코드뿐만 아니라 보장해야하는 어떤 행동이 있다면 이에대한 테스트도 추가로 작성하려했습니다. 정리하고 보니 결국 BDD 와 같은 얘기를 하고 있는 것 같네요.

 

Mocking 은 지양

TDD 관련 책을 찾아보면 가급적 Mocking 은 지양하라는 말이 항상 나옵니다. 실제로 테스트 코드를 짜면서, Mocking 은 되도록 피하려하고 있습니다. 만약 Mocking 이 필요한 경우면 혹시 설계가 잘못된게 아닌지 고민하고 있습니다.

 

테스트 코드에 논리 코드를 넣는 것은 지양

조금의 코드 중복이 있더라도 크게 심한 것이 아니라면 테스트 코드에선 그냥 중복을 허용하고 있습니다. 이건 저의 개발 바이블과도 같은 구글의 소프트웨어 엔지니어링의 조언을 듣고 반영한 사안입니다.

https://kok202.tistory.com/326?category=977005 

 

구글의 소프트웨어 엔지니어링 (4/5)

테스트 테스트 관련 챕터를 읽기 전 업무를 하면서 느꼈던 몇 가지 궁금증들을 해소하고 싶었습니다. 간략히 몇 개를 정리하면 아래와 같습니다. 대규모 트래픽이 있는 환경을 테스트하려면 어

kok202.tistory.com

 

테스트 제목은 그냥 한글로

좀 더 나아가서 정확한 테스트의 목적을 전달하기 위해 테스트 제목은 그냥 한글로 작성하고 있습니다. 테스트 제목은 대부분 서술적으로 풀어쓰는 경우가 많은 것 같습니다. 그래서 아무래도 영어로 작성된 테스트 제목은 어색하고 잘 읽히지도 않았던 것 같습니다. 더불어 테스트 코드는 생각보다 상당히 자주 돌리는데, 테스트 fail 이 났을 때 프로그래머가 바로 원인을 파악할 수 있으면 좋을 것 같았습니다. 이미 테스트 코드 정도는 한글로 작성해도 되게 허용하는 조직이나 회사들도 많으니, 테스트의 제목은 그냥 한글로 작성해도 될 것같아 저희도 예외적으로 허용하고 있습니다.

 

가급적 모든 public 메소드에는 테스트 코드가 있어야한다.

이런 룰을 기반으로 코드 리뷰시 public 메소드인데 테스트 코드가 없다면 TCR(Test code required) 이라는 코멘트를 남기고 있습니다. 일단 목표는 소형 테스트를 넣는 것에 집중하고 있기 때문에 이러한 규칙은 POJO 클래스에서만 사용되고 있습니다. 더 큰 그림을 보면 사실 스프링 부트 컴포넌트의 모든 public 메소드에도 테스트 코드가 들어가야겠지만, 암만 생각해도 중형 테스트를 넣는 것은 소형 테스트를 넣는 법을 완벽하게 파악하고 나서 인것 같습니다. 여러모로 갈길이 멀긴한 것 같습니다.

테스트 코드 짜는 작업은 생각보다 많이 지루하기 때문에 테스트 코드를 짜는게 번거롭다면 불필요하게 public 메소드를 만들지는 않았는지 고민해봐야할 것입니다. 캡슐화에 대해 한번 더 고민해볼 수 있어서 좋은 규칙인 것 같습니다.

 

테스트가 쉬운 쪽으로

테스트 코드 전환을 하면서 어떤 코드에 테스트를 넣어야할지, 어떻게 변경해야할지 같은 것들을 고민했어야 했습니다. (물론 장기적으로 보면 모든 코드에 테스트 코드가 들어가야 할겁니다.) 그래서 테스트 코드를 넣었을 때 유의미한 비즈니스 로직부터 테스트 코드를 넣으려 하고 있습니다.

그리고 테스트 코드를 작성하면서 리팩토링을 같이 하고 있는데요. 여기에 어떤 그라운드 룰을 하나 발견할 수 있었던 것 같습니다. "테스트 코드를 작성하기 쉬운 방향으로 설계하라" 라는 것입니다.  

개발에는 왕도가 정해져있는게 아니기 때문에, 항상 다양한 솔루션들이 있었던 것 같습니다. 그럴때마다 항상 장단점을 비교하고 트레이드 오프를 고려해서 괜찮아 보이는 방식을 사용해왔던 것 같은데요. 그런데 돌이켜보면 이게 그 당시에 알맞은 방법을 그때 그때 선택해왔기 때문에 어찌보면 일관된 설계와는 조금 멀어진 것 같다는 생각이 들었습니다. 반면 이번에 도입된 "테스트하기 쉬운 설계"라는 기준은 명확하고 조금은 좋은 설계에 가까워지고 있는게 아닌가. 하는 생각도 듭니다. 

테스트 하기 쉬운 쪽으로 라는 룰은 리팩토링 하는 코드 뿐만 아니라 새로 추가되는 코드들에도 적용되고 있습니다. 하지만 TDD 강의를 하신 이규원님은 단위 테스트가 좋은 설계를 반드시 보장하는 것은 아니라고 하니, 항상 주의는 기울이고 있어야할 것 같습니다.  https://kok202.tistory.com/336

 

TDD 안정감을 주는 코드 작성 방법

해당 강의를 듣고 정리한 포스팅입니다 https://fastcampus.co.kr/dev_red_ygw The RED : 이규원의 현실 세상의 TDD : 안정감을 주는 코드 작성 방법 | 패스트캠퍼스 그동안 우리나라에는 TDD를 제대로 다루는

kok202.tistory.com

 

그래서 어디까지 했을까?

아쉽게도 두 달 사이에 모든 코드에 테스트가 생기는 기적같은 일은 일어나지 않았습니다. 애초에 이런 일은 바라지도 않았습니다. 기존의 업무가 있고 우선순위와 작업 속도라는 것이 있으니 그것들은 유지해야한다고 생각합니다. 개인적으로는 저는 이 작업을 프로젝트당 1~2년 정도로 정말 길게 보고 있습니다. 그럼에도 불구하고 두 달 사이에 변화가 눈에 보이고 있어서 신기하면서도 성취감을 느낍니다.

앞으로 추가되는 코드에는 테스트 코드가 왠만하면 포함되서 추가될 수 있도록 하고 있습니다. 덕분에 테스트 코드를 추가하면서 설계에 대한 고민을 한번씩 더하게 되는 것 같습니다. 코드 퀄리티가 확실히 올라가고 있는게 눈에 보여서 이게 맞다는 확신을 얻고 있고요.

그 동안 개발을 해오면서 설계나 패턴에 대한 고민을 안해본 것이 아닙니다. 남들 다 읽는 설계 패턴 책들 다읽어봤고 원리 원칙들도 어느정도 아는 편에 속한다 생각합니다. 그런데 테스트코드를 짜면서 느끼는 것이, 사실 알고보니 그런 내용들 다 필요 없고 "테스트 코드를 쉽게 짜도록 설계하는 법", "테스트 가능하게 코드를 짜는 법"에대해 고민하다보면 좋은 설계는 자연스럽게 따라온다는 생각이 듭니다. 조금 극단적인 생각인 것 같기도합니다. 그럼에도 불구하고 이런 말을 하는 이유는 테스트 코드를 작성해서 얻은 설계와 아닌 설계를 비교해보면 그 품질 차이가 확실히 있다고 느꼈기 때문입니다. Testability 와 좋은 설계는 강한 상관관계에 있는 것은 분명한 것 같습니다.