gyuwon
205
2019-07-22 03:57:38 작성 2019-07-22 04:07:11 수정됨
0
1923

테스트 하기 어려운 코드는 코드냄새다


코드냄새(code smell)는 그 자체로 나쁜 것은 아닙니다. 나쁜 것이 숨어있을지도 모른다는 신호죠. 위키피디아의 정의(https://en.wikipedia.org/wiki/Code_smell)는 이런 표현을 사용합니다.

possibly indicates a deeper problem

만약 어떤 코드가 테스트 하기 어렵다면 그건 설계와 관련된 코드냄새 입니다. 설계를 개선하면 해결될 가능성이 높다는 것이죠. 예를 들어 저는 테스트 작성이 번거로운 설계에 대해 내가 뭘 잘 못하고 있는지 고민하다 CQRS를 배우게 되었습니다.

그 밖에도 테스트 하기 어려움이 보내는 잘못된 설계 신호는 많습니다. 비즈니스 논리 코드를 테스트 하려는데 데이터베이스 관리가 어려워 실용적이지 않다는 주장은 아주 흔합니다. 이건 테스트 자동화가 실용적이지 않은 것이 아니라 비즈니스 논리 코드가 데이터베이스에 의존하도록 설계되었거나, 더 나쁘게는 비즈니스 논리 자체가 데이터베이스 안에 저장 프로시저 형태로 구현되었기 때문입니다. 프로그래머가 맞아야 할 돌을 테스팅에 던지는 꼴입니다. 응집을 높이고 결합을 낮춰야 좋은 설계라는 지침은 학부과정에 배우는 거에요. 그걸 실천하는 건 졸라 어렵지만요.

둘 사이의 결합을 낮추기 위해 David Parnas의 정보 숨김(information hiding), Uncle Bob의 의존성 역전 원칙(dependency inversion principle), Bertrand Meyer의 명령 조회 분리(command query separation) 또는 계층적 아키텍처 패턴(layered architecture pattern) 등 여러가지 설계 기법들을 사용할 수 있습니다. 이런 설계 기법들은 오로지 테스팅만을 위한 것은 아닙니다. 진짜 목적은 코드를 둘러싼 다양한 변화에 대응하고 재사용하기 쉬운 코드를 만들기 위함이죠. 그리고 이런 코드는 테스트 하기 쉽습니다. 단위 테스트라는 것이 소프트웨어 일부를 떼어내어 사용해 보는 클라이언트 프로그램이라는 것을 떠올리면 잘 설계된 코드가 테스트 하기 쉽다는 것은 당연한 결과입니다. 반대로 질낮은 설계를 가진 코드는 테스트 하기 어렵고요. 구린 UX를 가진 앱은 사용자가 쓰기 어려운 것과 마찬가지 입니다.

물론 단위 테스팅만이 유일한 테스트 기법은 아닙니다. 수동 테스트 역시 테스트 기법이고 자동화된 기법도 한가지가 아니라 다양합니다. 모두 장단점을 가지기 때문에 그것들을 잘 이해하고 실용적으로 선택해야죠. 잘 설계된 하위 모듈들을 가져도 기능 테스팅(functional testing)을 하려면 데이터베이스 인스턴스, 메시지 중개자 등 인프라 관리가 필요합니다. 이런 상황에는 컨테이너와 IaC(https://en.wikipedia.org/wiki/Infrastructure_as_code)가 도움이 됩니다. 테스트 기법들의 장단점과 선택 기준에 대해서 구글 테스팅 블로그의 다음 글이 약간의 팁이 될 수 있습니다.

https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html

소프트웨어 세상 밖 현실적인 이유로 나쁜 설계를 개선할 수 없을 수도 있습니다. 빠듯한 일정, 프로그래머들의 부족한 설계 역량 등. 하지만 지금 내가 불가능한 것과 세상 모두가 불가능한 것은 다릅니다. 전자를 후자로 착각하면 지금의 괴로움에서 끝나지 않고 앞으로의 성장 가능성을 잃어버리게 됩니다.

다음 영상은 1:00:00부터 비동기 분산 응용프로그램의 단위 테스팅과 기능 테스팅을 어떻게 할 수 있는지 간단한 모의 사례를 라이브 코딩과 함께 보여줍니다.

https://www.youtube.com/watch?v=UttzAcbuk5k&t=3600s


2
2
  • 댓글 0

  • 로그인을 하시면 댓글을 등록할 수 있습니다.