요즘 Industry 쪽에서도 테스트 주도 개발 Test Driven Development을 적용하기 위한 노력들을 많이 하고 있죠? 이번에는 유지보수 관점에서의 테스트 방법론에 대해 이야기를 해보려 합니다. 테스트에 대한 이야기를 하면 빠지지 않고 나오는 것이 그것의 오너십에 대한 논쟁이죠. 테스트의 오너가 시스템이냐 현업이냐 하는 것이 그것입니다. 이에 대한 개인적인 의견을 이야기하기 전에 테스트에 대한 본질적인 이야기를 먼저 시작해보겠습니다.
시스템의 신규 개발이나 유지보수 추가 개발, 모두 테스트가 완전히 끝났다고 말하기 위해서는 최종 애플리케이션에 대한 테스트가 완료되어야 합니다. 무엇보다도 실제 사용 레벨에서의 작동 보증이 중요하기 때문입니다. 물론 개발자들도 개발을 진행하면서 테스트를 함께 수행하죠. 사실 테스트를 하지 않으면서 개발을 한다는 것은 – 정도의 차이는 있겠지만 – 말이 안 되니까요. 그때 얼마나 효과적으로 테스트를 했느냐에 따라 사용자 테스트 단계의 고행길 여부가 결정됩니다.
TDD는 개발자가 진행하는 단위 테스트를 보다 명확하게 계량할 수 있도록 단위 모듈별로 테스트 코드를 만들어 넣는 것을 기본으로 합니다. 그렇게 함으로써 테스트 코드를 재활용할 수도 있고, 테스트 코드의 커버리지를 측정하여 단위 테스트 수준을 정량적으로 확인할 수도 있어요. 그렇다면, 모든 모듈의 테스트 코드를 만들어 넣기만 하면 애플리케이션의 퀄리티는 올라갈까요? MS에서 제시하는 TDD를 사용한 프로젝트와 아닌 것과의 출하 이후 버그 발생 비율을 보면 확실히 효과가 있는 것처럼 보이기도 합니다. 하지만, 여기서 중요한 것은 – 단순한 테스트 코드의 커버리지가 아닌 – 어떻게 TDD를 해당 애플리케이션에 적용했느냐 하는 것이겠죠. 이 부분에 대한 이야기는 테스트 전체로 확장시켜서 이야기해볼 수 있을 것 같습니다.
개발자든 현업이든 테스트를 제대로 수행하기 위해서 가장 중요한 것은 테스트 관련된 여러 기법이 아니라 테스트를 해야 하는 시스템(이 담고 있는 비즈니스)에 대한 이해입니다. 이 이야기를 개발자의 단위 테스트에 적용한다면, 각 비즈니스 로직을 어떤 구조로 설계했는지에 대해한 이해가 먼저 필요하다는 이야기가 되겠죠.
개인적으로 테스트를 효율적으로 하기 위해서는 일반화된 방법론을 적용하는 것보다는, 해당 비즈니스나 개발된 시스템의 구조에 적합한 테스트 프레임웍을 설계하는 것이 더 효과적이라고 생각해요. 특히 Industry처럼 유지보수 인력이 제한적인 경우에는 테스트에 절대적인 규칙을 적용하는 것보다는, 선택과 집중으로 효율적인 진행을 할 필요가 있기 때문입니다. TDD를 적용하는 경우에도 개발을 진행하는데 20~30% 정도의 공수가 더 들어가기 때문에, 유지보수 운영에 무조건적인 적용을 강제하는 것도 쉽지는 않죠. 고정 인력 운영 비용이 그만큼 증가하게 되는 건 아무래도 부담스러우니까. 그렇기 때문에 시스템의 구조나 비즈니스에 따라 적절하게 테일러링 된 방법을 고안하게 되는 것 같습니다. 사실 애플리케이션의 성격에 따라 TDD의 적용이 쉽지 않은 경우도 꽤 있는데요. 특정 데이터를 주기적으로 변화시키며 관리해야 하는 시스템의 경우에 TDD를 적용하려면 배보다 배꼽이 더 큰 경우가 많죠. 게다가 필요한 데이터가 존재하지 않는다면 아예 테스트 코드를 돌릴 수 없는 경우도 발생하는데, Industry의 시스템은 대부분 관리 시스템이기 때문에 TDD 뿐 아니라 일반 테스트에서도 늘 그와 관련된 고민을 하게 됩니다.
앞에서 이야기했던 대로 개인적으로는 비즈니스 사용자 레벨에서의 테스트가 무엇보다도 중요하다고 생각해서, – 개발자의 단위 테스트는 기본이라 해두고 – 이 부분에서 작은 노력으로 큰 효과를 얻는 방법에 관심이 많은 편이거든요. 효과를 높이기 위해서는 꼭 신경 써야 하는 두 가지가 있는데, 하나는 – 위에서 계속 이야기했던 – 효과적인 테스트 프레임웍 구성이 되겠고, 다른 하나는 새로울 것도 없는 자동화입니다.
해당 프로젝트 혹은 유지보수에 관련된 테일러링 된 테스트 프레임웍을 구성하기 위해서는, 비즈니스 전반에 대한 이해와 과거 경험, 그리고 그것을 처리하는 시스템의 아키텍처 및 인터페이스 되는 시스템의 메커니즘까지 모두 고려해야 합니다. 이 작업을 통해 선택과 집중을 하기 위한 포인트들을 찾아내고, 이 부분들을 가장 효율적으로 테스트할 수 있는 방법들을 고안해내는 거죠. 물론 모든 시스템에 적절한 테스트 방법론을 빌드업하고 적용하는 것이 필요하다고 생각하지는 않습니다. 생각보다 비즈니스가 심플해서 오류가 좀처럼 발생하지 않는 시스템도 있고, 사용 빈도도 떨어지고 비즈니스적 리스크도 적은 시스템도 있으니까요. Industry는 일반 IT 관련 비즈니스 기업과는 달리 운영하는 시스템이 한둘이 아니잖아요. 페이스북은 페이스북 애플리케이션만 잘 운용하면 되는데 말이죠. 하지만, Industry에서도 핵심 비즈니스를 다루는 시스템의 경우라면 그런 작업을 확실히 해둘 필요가 있다고 생각합니다. 어쨌든, 그 비즈니스로 인해 기업이 영속될 테니 말이죠.
테스트 프레임웍이 정의되고 나면 그것을 기반으로 적절한 자동화 계획이 만들어지게 됩니다. 자동화의 경우는 모든 기업이 관심을 가지고 있는 부분이고, 이미 RPA 나 해당 기술을 활용한 솔루션을 사용한 적용사례도 꽤 많이 존재하고 있습니다. 하지만, 테스트의 모든 부분을 테스트 솔루션으로만 커버하려 하면 여러 가지 벽에 부딪치게 되는 경우가 있어요.(특히 데이터베이스와 연계되어야 하는 테스트의 경우) 이럴 때는 그 부분의 테스트를 위해 특화된 테스트 애플리케이션을 개발하여 상호 보완할 수 있게 하는 것도 좋은 방법입니다. 예를 들자면, 생성된 PDF 리포트의 수치를 검증하는 경우 RPA를 사용하게 되면 데이터베이스를 연계하는데 많은 노력을 들여야 하고, 테스트 시간도 오래 걸리게 되는 경우가 있어요. 이런 경우에는 해당 기능에 MVC 모델을 확실히 적용해서 UI 컨트롤 부분에 로직이 없도록 디자인을 하고, 서비스 레벨에서 데이터를 검증하도록 하는 애플리케이션을 따로 만드는 게 더 효율적일 수 있습니다. 반대로 실제 UX 및 애플리케이션 작동 부분을 테스트할 때에는 RPA를 사용하는 것이 훨씬 효과적이고요. 저도 한 십 년쯤 전에 핵심 비즈니스 관련 시스템을 효율적으로 유지 보수하기 위해서 테스트 애플리케이션을 직접 디자인해서 개발한 적이 있었는데, 아직까지도 잘 사용하고 있습니다.
처음 이야기를 시작할 때 테스트의 오너에 대한 이야기를 했었는데, 개발의 영역에서는 오류가 발생하지 않는 시스템을 Delivery 해야 하는 것은 기본이겠죠? 전달된 시스템을 비즈니스 쪽에서 검증하면서 비즈니스 로직이나 작동 메커니즘에 대해 개발자가 잘못 이해하고 있던 부분을 발견해내고, 바로잡아 가는 것이 현업 테스트에서 수행되어야 하는 일이라고 생각합니다. 그런 이유로 최종 테스트 작업의 오너는 비즈니스 쪽에 있겠지만, 그 단계에서 수행되어야 하는 테스트만을 진행할 수 있도록 개발자는 개발 퀄리티를 반드시 확보해 주어야 합니다.
역시 아무리 테스트 프레임웍이 잘 정의되어있다고 하더라도, 개발을 제대로 못했다면 갈 길이 멀다는 이야기가 되겠죠?