[테스트] 인프콘 - 테스트를 할 때 기억할 7가지 + 개인적인 경험

2022. 12. 19. 15:32Test

테스트 방법론에 대한 공부를 하면서 인프콘 세션 중 '나도 내 코드의 문제를 찾고 싶다구요?! - 테스트 할 때 기억할 7가지, 한주승' 제목의 세션을 보게되었습니다. 테스트의 중요성은 정말 아무리 강조해도 부족하지 않습니다.

 

직접 경험한 이야기를 좀 적어보겠습니다. 맨 처음 아무것도 모르는 상태에서 입사를 했을 때, 테스트 코드가 없이 개발되었던 어플리케이션을 인수인계 받은 경험이 있습니다. (제가 말하는 테스트 코드는 코드로서 작성된 코드를 테스트하는 코드를 말합니다.) 통합테스트가 가능한 형태로만 별도의 프로세스 형태로 테스트 프로그램만 존재했습니다. 이런 상황에서 간단한 기능을 개발하고 배포할 때도 긴장되는 순간도 많았고, 신규 개발에 대한 테스트만 추가하더라도 다른 모듈의 종속성 때문에 관련된 것들 찔끔찔끔 건드리다 보니... 개발 범위가 늘어나서 업무 생산성도 떨어지는 경우도 있었습니다.

 

제가 참 위 세션이 공감갔던 이유는 문제가 생겼을 때 시니어가 주니어를 바라보는 관점은 '왜 쟤는 저렇게 안했지?', '테스트 당연히 이렇게 이렇게 해야되는거 아니야?' 라고 생각을하고, 사고친 주니어는 '이렇게 하는거 아니었나요?' 이렇게 생각하는게 비슷해서입니다. 저도 해당 경험을 하고나서야 '테스트를 어떻게 해야겠구나' 라는 생각이 들었고 그 내용이 세션 내용과 흡사하여 한번 정리를 해야겠다고 생각했습니다.

 


기억해야 할 것 하나 : 입력과 처리, 출력에 대한 정의를 제대로 해야한다.

위 세션 장표를 아래 내용으로 재정리를 해보았습니다. 기본적으로 시스템을 구성하는 수많은 하위 모듈들은 모두 입력, 처리, 출력의 형태를 가지게 됩니다. 그렇기 때문에 각각을 제대로 정의해야 한다는 것입니다.

여기서 중요한 점은 '기대 결과'와 '실제 결과'가 동일하더라도 테스트가 틀릴 수 있습니다. 입력 정의와 사전 조건에 따른 처리로직 모두 잘못 구현을 하는 경우 비정상인 부분이 정상으로 둔갑 될 수 있습니다.

그렇다면 어떻게 제대로 테스트 케이스를 정의할 수 있을까요?

 

 

기억해야 할 것 둘 : 제품 요구사항

요구사항이란 어떻게 개발을 해야한다는 청사진과 같은 것입니다. 아래 세션 발표자료의 내용이 너무 좋다고 생각했는데, 요구사항을 반대로 말하면 테스트 케이스가 된다는 점입니다. 즉 요구사항을 제대로 이해한다면 정확하게 테스트 케이스를 정의할 수 있다는 것입니다.

SI 프로젝트 경험으로 정리하자면 요구사항 명세는 보통 '시방서'가 될 수 있다고 생각합니다. 관련 도메인 전문가와 설계를 담당하는 아키텍터들이 시스템이 운영되기 위한 모든 명세를 MECE하게 작성하여 정리된 것이 시방서입니다. 다만 이 시방서 항목은 실제 코드 레벨까지 이어질 수 있는 수준은 아닙니다. 따라서 이 요구사항 명세를 기준으로 개발자가 하위 모듈을 적절하게 나누고 테스트가 이루어져야 합니다. 이 역시 위에서 제시한 그림처림 '입력->처리->출력'을 기준으로 MECE하게 쪼개면 됩니다. 잘 나눈 세부사항들 전체가 요구사항을 아우를 수 있도록 하면됩니다.

 

이러헥 하면 세션에서 말하는 것 처럼 '기본적인 문제들을 CATCH 할 수 있다!' 고 할 수 있을것 같습니다.

 

 

기억해야 할 사항 셋 : (외부) 인터페이스

두번째 내용까지는 혼자서 개발하는 영역까지의 이야기인 것 같습니다. 세번째 내용은 다른 사람과 함께 개발하는 상황에서 문제를 정의하고 해결하는 방법에 대한 이야기 입니다.

테스트를 하는 과정에서 문제가 생긴다고 가정해봅시다. 위 프로세스에서 가장 시간을 많이 투자하는 단계는 원인을 찾는 일입니다. 왜 시간이 많이 걸리는 일일까 생각해봅시다. 보통 테스트 코드를 작성할 때 까다로운 부분이 외부 모듈을 연동하는 부분입니다. 이런 부분을 보완하기 위해서 Mocking 할 수 있는 도구들을 적극 적으로 사용하지만 한계가 있습니다. 이럴 경우 두가지를 확인해야 한다고 합니다.

 

먼저 내부 구현을 확인합니다. 내부 구현은 위 1과 2를 잘했다면 테스트 코드나, 시뮬레이션 도구들로 검증이 가능합니다. 하지만, 보통 주니어 입장에서 아래 외부 인터페이스를 의심하기 보다는 '내가 뭔가를 잘못했구나?'라고 생각하게 될 것 같습니다. 모든 과정에 print를 남겨가면서 더이상 의심할 수 없을 때까지 삽질 했던 기억이 납니다. ^^ 하지만 테스트 코드가 잘 작성되었다는 전제하에 아래 내용을 함께 진행을 한다면 원인 파악에 시간을 줄일 수 있을 것입니다.

 

바로 외부 인터페이스 관련입니다. 상호간에 정의된 것이 정상적으로 동작하는지 확인을 하면 됩니다. 

그 단계는 아래와 같습니다.

  1. (협력하는) 외부 인터페이스를 모두 찾는다.
  2. 메시지를 모두 확인한다.
  3. 메시지의 전체 흐름을 이해한다.
  4. 기준을 가지고 테스트 한다.

 

여기까지 기본적인 3가지였습니다. 1번과 2번은 문제를 찾는 방법이고, 3번은 문제를 해결하는 과정이었습니다. 저는 업무를 하면서 보니까 개인적으로 외부 인터페이스 테스트 또한 자동화가 가능하도록 스크립트나 테스트 툴 형태로 개발이 되면 좋겠다고 생각을 했습니다. 그리고 그렇게까지 하기에는 조금 어렵다고하면 적어도 체크리스트라도 먼저 확보를 한다면 좋을 것 같습니다. 동일한 솔루션을 여러대 만들어 납품을 해야하는 상황에서 이 행위는 반복적인 단순작업이 될 가능성이 높기 때문입니다. 근데 아쉽게도, 여러가지 업무를 하다보면 가장 놓치기가 쉽고 담당자의 공백이 생기면 항상 문제가 발생하는 부분이었습니다.

 

 

 


아래 세가지는 통합테스트 측면에서 고려하면 좋을 듯한 내용입니다.

 

더 나아가면 좋은 3가지 하나 : 추상적인 설계 내용이 구현 된 결과물을 최초로 만나는 시점은 테스트

사실 아무리 분석을 잘 하고, 범위를 잘 나눠서 개발을하고 단위 테스트를 아무리 잘 한들... 통합 테스트에서 무너지게되면 모두 나가리라는 내용입니다. 근데 애석하게도 개발 단계가 아닌 전체 통합이 된 시점에서야 프로덕트 형태의 결과물로 통합 테스트를 진행하기 때문에 통합 테스트는 참 중요합니다.

 

그리고 업무 경험상 통합 테스트의 시점은 가급적 실제 배포가 되는 시점을 기준으로 충분히 여유를 두고 하는 것이 좋은 것 같습니다. 업무를 하다보면 여러가지 이유로 사실 정말 힘든 부분이라는 생각은 들면서도, 막상 그 개고생의 시점이 지나가면 아 더 빨리 할 수 있었을 걸...하는 아쉬움이 남는 부분이기도 합니다.

 

더 나아가면 좋은 3가지 둘 : 내가 최초의 사용자가 되어본다.

최초의 사용자가 되어 필요한 내용들을 테스트하면서 추가적으로 더 고려해야 될 사항들을 고민하거나, 추가하는 행위등을 하면서 제품의 질을 개선한다는 내용입니다. 다만, 완벽보다는 완성에 초점을 두고 진행을 해야 현업에서 문제가 없을 것 같습니다. ^^

 

더 나아가면 좋은 4가지 셋 : 일관성

기능을 개발할 때 사용자가 기억 할 것을 최소화해야 하고 쉽게 익숙해 질 수 있도록 해야한다는 점입니다. 테스트 과정에서 이런 부분도 잘 체크를 해야겠다는 의미로 이해는 했습니다.

 

 


가장 기본 하나 : 테스트를 하는 것

세션 발표 내용 중 가장 공감되는 부분입니다. 모든 문제의 원인은 테스트를 하지 않아서이다.

저는 임베디드 환경에서 gcc나 g++ 같은 보편화된 도구가 아니라 Cross-compile 환경에서 개발을 진행했습니다. 지금은 물론 Cross-compiler를 사용하더라도 필요한 라이브러리 모듈을 제가 수정하여 포함시키는 행위를 통해 적극 테스트코드 작성이 가능하겠지만... 첫 신입 시절은 그렇지 못했습니다. 그래서 '테스트 환경 구성하기가 까다로워서', '너무 간단한 기능이라서' 등등의 이유로 skip을 시전했고 사고로 이어진 경험이 있습니다. 이런 경험은 제 입사 동기들도 다 있었고 지나고나서 추억으로 웃고 넘기는 이야기지만, 참 씁쓸한 기억이기도 합니다.

 

해당 글의 마무리는 아래 내용으로 정리하고자 합니다.

 

정말 공감가는 내용입니다. 그리고 한가지 더 추가하고 싶은 내용은 테스트에 대한 코드작성과 리뷰도 문화라는 생각이 많이듭니다. 기존에 코드에 테스트 코드가 없는데, 그걸 주니어가 붙잡고 있어서 테스트코드가 막 생기고 제대로 된 테스트가 될까라고 생각했을 때, 절대 아니라고 생각합니다. 이런 부분은 시니어, 미드레벨의 개발자분들도 그런 문화를 만들고, 테스트에 대한 내부적인 프로세스를 함께 만들어야 된다고 생각합니다.

 

테스트에 대한 관점, 가장 기본이 되는 방법론, 공통적으로 사용하는 도구, 테스트 시나리오 정도는 팀 내부적으로 공유 정도가 필요하지 않을까 싶은데, 이런 역할을 주니어에서 미드로 넘어가는 과정에서 한번 정립을 할 수 있는 수준까지 올라간다면 Best라는 생각이들고 저도 그것을 목표로 삼아볼 생각입니다.