마이크로서비스 아키텍처의 테스트

Updated:

애플리케이션의 기능을 변경하게 되면 당연히 변경한 부분이 정상 동작하는지 테스트를 해야봐 한다. 예를 들어 회원, 상품, 주문, 배송의 4개로 구성된 마이크로서비스에서 주문 서비스를 변경했다면, 회원, 상품, 배송 서비스까지 다 실행을 시켜서 변경한 주문 서비스가 잘 동작하는지 테스트해야 한다는 것이다. 이런 방식은 수작업으로 테스트해야하고 또 이 이유로 인해 변경 내용 검증에 시간도 많이 걸리게 된다. 그래서 변경하면서 또는 변경사항을 commit 하면서 바로바로 테스트를 수행할 수 있도록 자동화가 필요한 것이다. 그래서 애플리케이션의 테스트, 특히 마이크로서비스 아키텍처를 적용한 시스템의 테스트에 대해 알아보고, 자동화 할 수 있는 테스트에 대해 알아보자.

테스트의 자동화

상자 속에 테스트케이스는어떤목표틀달성(예: 프로그램이특정경로를실행하는지. 지정된 요건에부 합하는지등을함인)하기위해개발된테스트입력. 실행조건. 기대결과의집합이다. <출처: https://en.wikipedia.org/wiki/Tesl_case>

자동화 테스트는 설정 > 실행 > 확인 > 정리의 단계로 구성된다.

  • 설정: 테스트 대상 시스템과 연관된 픽스처들을 테스트할 수 있는 상태로 초기화한다.
  • 실행: 테스트 대상 시스템을 호출한다.
  • 확인: 호출 결과 및 대상 시스템의 상태를 확인하고 예상값과 비교한다.
  • 정리: 테스트 결과 확인 후 테스트에 사용했던 픽스처 초기상태로 정리한다. (이 단계를 건너 뛰는 경우도 많지만, DB 롤백 등 반드시 필요한 경우도 있음)

테스트의 유형

단위 테스트 (Unit Test)

단위 테스트는 프로그램의 기반 단위인 모듈을 테스트하는 것으로 모듈 테스트라고도 한다. 단위테스트는 함수로 구현한 단일 기능이 정상 동작하는지 확인하는데 목적이 있다. 특히 이 테스트는 구현단계에서 수행하므로 코딩의 실수를 빠르게 확인하고 조치할 수 있게 해 준다. 방식으로는 화이트박스 테스트와 블랙박스 테스트를 사용할 수 있는데 함수의 내부구조를 볼 수 있는 화이트박스 테스트를 주로 사용하는 것이 좋다.

단위 테스트

단위테스트를 통해 아래의 문제를 조기에 발견할 수 있다

  • 자료형, 연산자 사용 오류
  • 알고리즘 오류
  • 틀린 계산식

서비스 테스트 (Service Test)

서비스 테스트는 여러개로 구성된 각 마이크로서비스를 서비스 단위로 테스트 하는 것으로 개발 서비스의 기능을 테스트 하는 방법이다. 이 테스트를 통해 각 단위 기능으로 구성된 마이크로서비스의 기능을 테스트 하는 것으로, 개별 서비스이 테스트를 통해 전체 시스템 테스트 보다 문제를 더 빠르게 발견하고 해결하기 위함이다. 서비스의 기능을 외부로 공개한 API를 대상으로 테스트를 수행하며, Swagger나 Postman 도구로 테스트 하는 경우가 많다.

서비스 테스트

통합 테스트 (Integration Test)

서비스 테스트 후 정상 동작을 확인한 각 마이크로서비스를 통합하는 과정에서 발생할 수 있는 오류를 찾는 테스트를 통합 테스트라고 한다. 서비스 테스트에서 오류가 발견되지 않았더라도 서비스간의 연계에서 발생할 수 있는 데이터 공유, 정합성 등 인테페이스나 상호작용에서 오류가 발생할 수 있다. 그러므로 통합 테스트가 반드시 필요하다.

통합 테스트

통합 테스트는 한번에 수행하는 빅뱅(Big bang) 방식으로 단위 테스트와 서비스 테스트가 끝난 서비스들을 동시에 실행시켜서 수행하는 방식으로 소규모 시스템을 대상으로 사용하는 경우가 많다. 그러나 오류 발생 시 어느 서비스, 어느 모듈, 아나면 연계를 위한 API호출이나 메시지 처리 등 어디에서 오류가 발생했는지 또 그 원인이 무엇인지 찾기가 어렵게 된다. 그래서 개발, 테스트, 통합을 반복적, 점전적으로 수행하는 것으로 이런 문제를 사전에 줄일 수 있다. CNAPS 방법론에서는 매 Sprint 마다 동작하는 코드를 코드 저장소에 commit 하면 소소크도의 통합/테스트/배포를 자동화 하는 것을 기본으로 한다.

엔드 두 엔드 테스트 (End to End Test, UI Test)

이 테스트는 시스템 전체가 정상 동작하는지 체크 하는 것으로 예전엔 시스템 테스트라고 불렀다. 이 엔드 두 엔드 테스트는 모든 시스템이 개발되고 통합된 후 사용자의 요구사항을 만족하는지 테스트하는 것이다. 즉 사용자에게 시스템 전달 전 개발팀에서 수행하는 마지막 테스트로 실제 사용환경과 유사한 테스트 환경에서 기능적, 비기능적 전체 시스템에 대해 수행하는 테스트로 기능 요구사항은 실제 사용자의 조작을 기반으로 한다. 즉 테스트 시나리오를 사용자가 화면을 통해 시스템을 조작하는 방식으로 정의해서 테스트를 수행한다. 비기능적 요구사항은 주로 시스템에 부하를 주고 시스템의 안정성과 가용성을 확인하고, 그 외 신뢰성, 보안성, 사용자 편의성 등을 테스트한다.

엔드 투 엔드 테스트

특히 마이크로서비스 아키텍처를 적용한 시스템에서는 엔드 투 엔드 테스트를 하는 것이 복잡하고 까다롭다. 이 테스트를 위해서는 모든 마이크로서비스가 동작하고 있어야 하고, 테스트 시나리오도 모든 서비스의 기능을 점검할 수 있도록 준비되어야 한다.

마지막 테스트의 끝판왕 인수 테스트

인수 테스트는 시스템이 예상대로 동작하는지 확인하고, 요구사항을 만족시키는지 확인하는 테스트로 시스템을 인수하기 전에 요구사항에 명시된 모든 기능, 비기능적 요구사항을 충족하는지 사용자가 직접 수행하는 테스트다. 인수 테스트는 적절한 이미지가 없네요 ^^

정리

소프트웨어의 테스트란 “소프트웨어의 결함이 있다는 걸 찾아내는 과정”이다. 개발한 소프트웨어가 오류나 문제가 없다는 것을 보여주는 것이 아니라 문제가 있다는 걸 밝혀내는 과정이다. 과거의 소프트웨어의 생명주기의 프로세스를 보면 “요구사항 분석 - 설계 - 구현 - 테스트 - 유지보수” 여기에서 테스트는 거의 마지막 단계로 테스터는 “이 소프트웨어는 완벽합니다.” 라고 하는것이 아니라 “이 소프트웨어는 어떤 결함도 없습니다.”라고 말해야 한다.. 고 한다.

테스트에서 찾아내서 조치해야 하는 “결함”이란 오류 뿐 아니라 설계와 다르게 동작하는 것, 사용자가 의도대로 동작하지 않는 것 모두를 포함한다. 따라서 이런 모든 것들을 마지막에 테스트 하는 것은 시간과 노력이 많이 든다. 아주 작은 결함이 어디에서 발생했는지, 어디를 수정해야 하는지 찾기 어렵다는 뜻이다. 그래서 개발 초기 단위 테스트와 매 스프린트마다 지속적 통합과 테스트를 통해 프로젝트 종료에 임박해서 발견될 결함을 미리미리 해결하는 방식이 많이 사용되고 있으며 이 테스트 과정을 자동화 하는 것이 각광받고 있다.

요즘 테스트 주도 개발(Test-Driven Development)도 뜨고 있길에 옛날에 샀던 책을 꺼내 혼자 두어달 해본 결과 생각보다 많이 어려웠다.

감사합니다..