요즘 저의 자작(自作) 프로그램에 기능 하나를 추가 했습니다. 테스트 케이스 도출 프로그램에 테스트 데이터 생성 기능을 넣는 것인데 생각보다 경우의 수가 많아 쉽지 않았습니다. 부끄럽지만 처음 이 프로그램을 제작할 때는 테스트 코드를 작성하지 않았었습니다. 엄밀히 말하면 중요한 로직만 테스트 코드를 만들었고 간단하다고 판단된 것은 만들지 않았습니다.

기능 추가를 하면서, 이번에는 모든 메쏘드 및 함수에 대하여 테스트 코드를 만들기로 하였습니다. 여기에 세부 내용을 전부 적지는 않을 것이지만, 작업을 하면서 제가 느꼈던 것들에 대하여 정리를 해 보려 합니다.

단위 테스트 커버리지는 가급적 100% 로…

이제 저는 단위 테스트는 항상 100%로 맞추라고 이야기 하고 싶습니다. 커버해야 할 대상은 개발자 “자신이” 만든 코드 입니다. 사이트에서 단위 테스트 하시라고 하면 ‘구조상’ 어렵다고 하는 분들이 계십니다. 테스트에 대한 고려 없이 코드를 작성한 경우입니다. 저는 예전에는 그러면 그건 스킵하시고 다음부터는 테스트를 고려하여 코딩하시라 했읍니다만, 이제는 『그럼 코드의 구조를 바꾸세요』 라고 말할 것입니다. 단위 테스트가 주는 메리트를 놓치지 않기 위해서 입니다. 제가 품질팀장이라면 100% 하라고 요구할 겁니다. (이전에 NIPA공학센터에서는 도메인별로 기준을 나눠 놨었던게 기억납니다. 일반 도메인 60%, 자동차, 안전 쪽은 80%..)

100줄의 주석보다 하나의 테스트코드가 더 낫다

예전에 제가 개발을 처음 배울 때 사수로부터 「주석」의 중요성을 엄청 들었습니다. 코드의 설명을 위해 주석을 엄청나게 썼던 세대 입니다. 하지만 이제 메쏘드나 클래스에 대하여 테스트 코드가 해당 대상에 대한 모든 설명을 해 주는 시대가 왔습니다. 이 메쏘드는 어떤 형태의 데이터를 집어넣어야 하는지, 리턴값은 무엇인지 모든 케이스를 테스트를 통해 「실감」시켜 주기 때문입니다. 이 내용들을 모두 「주석」으로 하기에는 상상도 못할 일입니다.

코드의 안전망

테스트코드는 코드의 안전망입니다. 이번에 추가 작업을 하면서 이런 안전망의 필요성을 절실히 느꼈습니다. 특히 테스트 코드가 없는 부분에 대해서는 수정된 라이브러리 때문에 영향이 있을까..? 너무 이에 대하여 궁금했지만 단위 테스트 코드가 없어 확인할 길은 없었습니다. 그냥 빌드 후 해당 기능을 써 보는 수 밖에 없었습니다. 코드간 영향도 분석은 사실 너무 어렵습니다. 하지만 이런 테스트 코드들이 잘 짜여 있다면 이런 영향도 분석은 필요 없을 것 같습니다.

커버리지는..?

각종 테스트 프레임워크에서는 커버리지 측정도구를 지원하고 있습니다. 이 때 커버리지는 브렌치 커버리지(Branch Coverage)입니다. IF 등의 조건절의 모든 분기를 태웠는지 확인하는 것입니다. 이것만 커버 해도 단위 테스트는 충분 합니다. Mission Critical한 도메인(항공, 자동차 등)에서는 브렌치 커버리지 보다 더 강력한 커버리지인 MC/DC(Muitiful Condtion/Decision Coverage)를 요구하는 경우가 있으며 이 경우의 코드 테스트는 좀 다르게 커버되어야 합니다. 어떻게 하는지 궁금한 분들은 제 영업 비밀이기 때문에 저에게 개인적으로 문의를…^^;; 아.. 그리고 브렌치던 MC/DC건 커버리지는 100%로 맞추어 주세요. 기왕 하는 거 충분하게 해야죠.

마치며…

제가 돌아다니며 수많은 개발 조직에 「단위 테스트」를 하시라고 이야기 하면, 기능리스트를 뽑고 그것을 수행한 게 단위 테스트라고 이야기 합니다. 중소기업들은 물론이고 중견 기업들에서도 그렇게 이야기 하더군요. 단위 테스트는 「기능」을 다 커버했는지 체크하는게 목적이 아니라 『코드의 안정성, 가독성』의 확보 목적이 오히려 더 큰 것 같습니다. 테스트 케이스를 구성할 때 그냥 브렌치 커버리지 커버를 목표로 한다면 개발자가 직접 코드를 짜는게 더 나을 것 같습니다. 하지만 MC/DC같은 커버리지를 목표로 하신다면 테스트 설게전문가가 붙어서 같이 짜시는게 더 나을 것입니다.