Jello's development blog

Jello's development blog

테스트를 하는 방법, 관점과 나의 생각

얼마 전까지 토이 프로젝트를 하면서 Node.js에서 테스트 코드를 작성해야 할 일이 생겼다. 간단하게 DB에 있는 row들을 json형식으로 반환하는 라우터의 테스트 코드였다. 나는 ORM으로 sequelize를 사용하고 있었다. 테스트를 작성하다가 “테스트에서까지 매번 DB에 접속해야하나?” 라는 생각에, 검색을 하여 mocking이라는 개념을 알아봤고, 그로부터 꽤 이후에 테스트 더블, mockist, classical이라는 것을 알게 되었다. 물론 지금으로부터는 꽤나 오래 된 일이지만 말이다.

아무튼 mocking이라는 것을 처음 알았을 때에는, “역시나 이런게 있을 줄 알았어” 하면서 자세히 들여다 보았다. 그리고 마침내 ORM로직을 테스트 더블로 간단하게 만드는 데에 성공했다. 꽤나 힘든 작업이었다. Sequelize는 promise로 엮인 함수였고, 무조건 promise를 한 단계 이상 거친 후에야 내가 만든 서비스 로직이 실행되었다. 그렇기 때문에 나는 sequelize와 비슷한 promise를 테스트 더블이 반환하도록 구현해야 했다.

Sequelize의 함수별로 꽤 정교한 테스트 더블을 만드는 과정이 계속되었다. 하지만 내가 실제 로직을 변경하려 했을 때, 내 나름대로 정교하게 만들었다고 생각했던 테스트 더블이 작동하지 않는 경우가 빈번했다. 나는 실제 로직보다 테스트 더블의 로직을 완벽하게 바꾸는 데에 시간이 더 많이 걸렸고, 회의감이 왔다.

친구와 대화하며 알아보니, 테스트해야 할 로직을 제외하고 모든 것을 가짜 함수로 만들어서 순수하게 해당 로직만 테스트하는 mockist와, 테스트하기에 예측이 불가능하거나, 외부 환경만 가짜로 만들어서 전체를 아우르는 테스트를 하는 classical(classicist)가 있었다. 그 중에서 나는 mockist의 가치관을 따르고 있었다.

당연히 하나의 유닛 테스트는 순수하게 하나의 로직만 테스트해야 한다고 스스로 믿고 있었다. Classical처럼 했다가는, A로직에서 에러가 나면, A의 유닛 테스트 뿐만 아니라, A와 의존성이 있는 B와 C의 유닛테스트까지 실패하게 될 것이다.

하지만 그렇다고 mockist처럼 하기에는 위에서 말했던 것처럼 비용이 컸다.. 로직이 바뀔 때마다 원래 만들어 놓았던 가짜 환경도 바꿔줘야 하니, 개발을 두 배로 하는 느낌이었다..

그러다가 답답해서 나에게 테스트를 알려주신 멘토님한테 물어봤다. 각자 장단점이 있는 거라고 하셨다. 상대적으로 중요하거나 몇 년 동안 길게 보는 프로젝트에서 기반을 탄탄하게 잡아야 할 때는 가짜 환경을 잘 만들어서 완벽한 테스트를 짜야 할 것이고, 상대적으로 덜 중요하거나 빠르게 개발해야 할 경우에는 전체를 아우르는 테스트를 하여 효율이 좋게 가져가는 것이 좋다고 생각했다.

소프트웨어를 개발하는 것 또한 공학인 만큼, 적절한 상황에 적절한 방법을 사용해서 실용성이나 가성비를 최대로 올리는 것이 좋다고 생각한다.