본문 바로가기
Homo Coding

비즈니스 로직의 거대화와 테스트 방법의 변화

by javauser 2010. 11. 26.
IT의 사용이 증가하면서 그 넓이(오프라인 업무의 온라인 업무화) 뿐만 아니라, 그 깊이(다양한 유형의 온라인 업무화)까지도 상당한 영역까지 구현의 범위가 넓어지고 있습니다. 따라서, 시스템의 구현에 대한 테스트는 그 입력과 예상되는 출력의 검증 뿐만 아니라, 다양한 경우의 조합(다양한 입력 변수들)을 통한 테스트가 비즈니스적으로 예상하는 형태로 결과값이 얻어지는지에 대한 테스트도 상당히 중요해지는 것 같습니다.

예를 들어, 금융권의 상품들은 다양한 옵션들이 추가되면서 다양한 상품들이 나타나고, 이에 대한 수익율이나 이자율, 환급율과 같은 결과치들이 상품으로써 팔릴 만한 가치인가를 결정하려고 하는 요구들이 강하게 나타나며, 특히, 파생상품의 경우들은 그 결과를 허용오차 범위 내에서 미리 예상할 수 있는 것이 중요해졌습니다. 따라서, 테스트를 할 수 있는 범위가 여러가지 조합에 의해서 케이스(커버리지)가 무한대수로 증가했으며, 테스트하는 입장에서는 거의 이 부분에 대한 검증을 수행할 수 있는 방법이 전무한 상태이기도 합니다. 

이러한 테스트에 대해서 접근할 수 있는 방법은 시뮬레이션이라는 것일텐데, 시뮬레이션을 통한 검증에 대한 방법 역시 정확한 결과값을 예상하려면, 그 테스트 데이터를 마련하는 것부터 그 어려움에 봉착하게 됩니다. 우선은 복잡한 시뮬레이션 테스트를 수행하기 이전에, 사전에 개발자 측면에서 이러한 테스트를 수행하기 위한 방법에 대한 시도가 필요하다고 봅니다.

그 첫번째 단계로, 우선은 단위테스트 단계에서 테스트 이전과 이후 상태에 대한 스냅샵의 축적이 필요합니다. 즉, 테스트 대상의 내부를 모니터링하고, 이를 기록할 수 있는 장치가 필요하며, 이러한 방식은 Test Spy 라는 것을 통해서 가능합니다. Test Spy는 어떤 특정 방식이라기 보다는 테스트의 내부를 들여다보고, 변화를 감지할 수 있는 장치를 만드는 기법이라고 보면 됩니다.

xUnit Test Patterns 라는 책에서 Test Spy를 사용하는 시점은 다음과 같이 소개되어 있습니다.

  • 테스트 대상 시스템으로 발생되는 간접적인 영향을 검증하고 이전에 테스트 대상 시스템에 영향을 미치는 모든 변수에 대한 값들을 예상할 수 없는 경우
  • 테스트를 가시적으로 검증하기를 원하고 Mock Object의 기대치에 대한 내용을 설정하기 어려운 경우
  • 테스트가 테스트에 특화된 동등성(test-specific equality)이 필요하고 따라서 테스트 대상 시스템에서 구현된 대로 표준적인 동등성 정의를 사용할 수 없고, assertion 메소드에 제어를 제공하지 않는 Mock Object를 만드는 도구를 사용함

그 밖에도 외부 시스템과의 연결과의 테스트에 대해서도 Test Spy를 사용할 수도 있습니다. 단위테스트에서 Test Spy를 만드는 손쉬운 방법은 테스트 시작과 끝 부분, 즉 setUp(@Before)와 tearDown(@After)에 테스트 전 상황과 이후 상황을 캡쳐하는 로직을 만드는 것입니다. 그러한 장치를 만들면, 해당 테스트 오퍼레이션을 시작할 때마다 전후 상황이 캡쳐되어 축적되어 이를 보고 비교 검증을 수행해볼 수 있습니다. 이러한 유형의 테스트는 상당히 많은 유형들이 나타나기 때문에 이러한 부분을 상위 클래스에서 수행하도록 추상화시키셔 만들어 놓을 수도 있습니다. 전후의 비교를 캡쳐하는 방식들은 html 혹은 excel 의 형태로 생성하도록 만들 수도 있을겁니다. (FIT를 참조하는 것도 많은 도움이 됩니다.)

이러한 방식은 테스트에 대한 결과 검증에 대한 부분으로 사실 본격적인 테스트를 수행하려면, 그 무엇보다 다양한 경우(테스트 케이스)를 어떻게 만들어낼 것인가에 대한 고민이 더 큰 영역인 것 같습니다. 테스트 데이터는 모든 테스트에서 출발이 되는 지점이며, 이 테스트 데이터를 어떻게 만들 것인가에 따라서 테스트의 범위(커버리지)가 다르게 됩니다. 테스트 데이터는 단위테스트의 입장에서 보면 해당 시스템의 작동 시점의 스냅샷 데이터이며, 그 스냅샷 데이터의 다양성 확보가 중요합니다. 구현된 비즈니스 로직의 구조가 이를 외부에서 주입이 쉽고, 다양한 변수의 객체 모델이 상대적으로 쉽다면 이러한 다양한 테스트 데이터를 마련하고 생성하는 것이 상대적으로 쉽습니다. 이러한 비즈니스 로직 구현의 구조를 테스트하기 쉬운 구조 형태로 만드는 것이 결국은 테스트 데이터에 대한 생성 노력을 줄여주고, 비즈니스 검증을 쉽게 할 수 있도록 만듭니다.

하지만, 대부분의 시스템에서는 복잡한 비즈니스를 대변하듯이 구현 로직 자체도 상당히 복잡하고 어렵게 문제를 푼 시험지처럼 코드가 만들어져 있습니다. 이러한 구현 구조와 코드를 대상으로 이러한 테스트를 수행하기 위해 테스트 데이터를 자동으로 만들어내기란 여간 어렵지 않습니다. 또한, 이러한 복잡한 구조의 특징은 단순히 몇개의 테이블이 아니라, 로직 내에서 사용되는 테이블 갯수도 보통은 수십가지 정도가 되며, 상당히 많은 컬럼값들의 조합을 사용합니다. 이러한 상황이라면, 테스트에 대한 스냅샷 데이터(DB 데이터)를 다양하게 확보하는 것이 제일 관건이 될 듯합니다. 즉, 복잡한 테스트 데이터를 자동 혹은 임의로 만드려는 노력보다는 시스템이 동작하는 임의의 시간별로 스냅샷 데이터를 축적하도록 하는 메커니즘을 만들어서 이 데이터를 테스트에서 재사용하려는 형태로 만드는 노력이 더 나을 것 같습니다.

테스트 데이터를 생성하는 방식에는 뚜렷하게 어떤 것이 좋을지는 없습니다. 다만, 현재의 테스트 대상 시스템의 구조가 테스트 데이터 생성에 영향을 미치며, 최악의 순간까지는 라이브의 데이터를 그대로 사용하는 형태로 테스트를 진행할 수 밖에 없는 상황에 부딪힐 수도 있습니다. 어찌되었든 간에 테스트 데이터는 테스트를 하는 순간에는 그 데이터로만 해야하며, 다음 테스트를 할때에는 그 이전에 한 결과를 항상 clean하게 만들어야 하는 원칙하에서 데이터를 마련해야 합니다.

비즈니스 로직의 거대화만이 IT의 목적이 되어서는 안됩니다. 그에 대한 결과까지도 책임져야 올바른 시스템을 만들었다고 볼 수 있습니다. 서브프라임 사태에서도 보았듯이, 무조건적으로 상품을 만들어서 시스템에 해당 로직을 우겨넣는 상황보다는 이를 어떻게 검증하고, 부수적인 효과를 어떻게 모니터링할 것인가에 대한 책임이 점점 더 커지는 것 같습니다.

이제는 점점 시스템을 만드는 주체도 그 내부 로직의 실행결과를 모르는 비즈니스가 만들어지고 있습니다. 이러한 비즈니스 로직 덩어리들을 효과적으로 테스트하고 규명할 수 있는 체계적인 방법이 필요할 것 같습니다.


반응형