Digital Transforamation & Software Testing
오늘날 기업은 디지털 트랜스포메이션을 통해 초일류 기업으로 도약하려고 하고 있고, 소프트웨어는 그 중 필수적이고 중요한 부분이 되고 있습니다. 혁신의 속도를 빠르게 하려면 고품질의 소프트웨어를 보다 빨리 제공하고 제대로 동작하는지 확인할 수 있는 방법이 필요합니다. 그래서 소프트웨어 테스트가 중요한데, 개발된 소프트웨어가 요구사항대로 되었는지, 기능이 제대로 동작하는지, 안정적인지, 확장 가능한지 등 다양한 면에서 검증되어야 합니다.
테스트 자동화의 중요성
전통적으로 소프트웨어 테스트는 애플리케이션을 테스트 환경에 배포 후 사용자 인터페이스 또는 UI를 클릭해서 문제를 찾는 수동적인 방식으로 진행했습니다. 모든 변경 사항을 수동으로 테스트하는 것은 시간이 오래 걸리고 반복적이며 지루한 작업으로 자칫 실수로 이어질 수 있습니다.
소프트웨어 개발이 성숙해짐에 따라 테스트 방식도 성숙해지고 있습니다. 개발자의 수동 테스트 방식에서 테스트 작업의 가장 큰 부분을 자동화하는 방법으로 소프트웨어의 오류 여부를 금방 알 수 있도록 바뀌고 있습니다.
애플리케이션의 수작업, 반복적 작업 방식은 계속 증가하는 소프트웨어의 구축, 테스트, 배포가 불가능해집니다. 생산성에 직접적인 영향을 주는 피드백 주기와 디버깅 시간을 감소시키고 반복적인 테스트를 자동화 하게 되면, 소프트웨어가 제대로 작동하는지 확인하기 위해 반복적으로 테스트를 할 필요가 없고, 코드 베이스를 변경하는 것도 더 쉬워집니다.
또한 지속적인 전달 방식의 빌드 파이프라인을 사용하여 소프트웨어를 자동으로 테스트하고 테스트 및 운영 환경에 배포할 수 있습니다. 즉, 기존의 애플리케이션의 수작업 및 반복적인 작업을 빌드, 테스트, 배포 및 인프라에 이르기까지 자동화하는 것이 혁신을 가속화 시킵니다.
테스트의 종류
이제 테스트의 개념부터 살펴보겠습니다. 테스트의 종류에는 크게 2가지 방식이 있습니다. 블랙 박스 테스트는 요구사항 명세서대로 소프트웨어가 동작하는지에 초점이 맞추어진 테스트로 소프트웨어 컴포넌트나 시스템의 내부 구조를 참조하지 않고 요구사항/명세 기반으로 기능/비기능 테스트를 합니다.
반면 구조 테스트라고도 하는 화이트 박스 테스트는 구현된 소스 코드 내부 구조를 분석하여 미리 정의된 오류를 찾아내는 테스트를 말합니다.
V-모델
V-모델은 기존 폭포수 모델의 확장된 형태의 테스팅 모델입니다. 개발 모델 상의 구현을 수행하는 좌측의 검증 영역과 테스트를 하는 검수 영역으로 되어 있어 개발 각 단계와 각각 매칭되는 테스팅 모델로 정의하여 테스트 절차를 강화한 모델입니다.
테스팅 사분면
각 종류별 테스트는 각 사분면에 위치합니다. 핵심은 테스트하는 방법의 측면에서 상황에 맞는 선택을 해야 하는 것입니다. 최근 추세는 가능한 많은 자동화를 추구해 대규모 수동 테스트를 탈피하고 있습니다. 1사분면과 2사분면은 팀을 지원하는 테스트입니다.
좌측 하단 Q1, 1사분면은 단위 테스트나 TDD라고 하는 테스트 주도 개발 영역으로 프로그래머가 자신의 코드를 잘 설계하도록 돕는 데 목적이 있습니다. 보통 애플리케이션과 동일한 프로그램 언어로 작성하고 xUnit 프레임워크 등을 사용하여 자동화가 가능합니다.
좌측 상단 Q2, 2사분면은 테스트도 개발팀의 작업을 지원하지만 더 높은 수준의 인수 테스팅 영역입니다. Agile의 Product Owner 주도로 외부적 품질과 특징을 정의 후 기능 수준에서 테스트하고 고객이 요구한 비즈니스 조건을 충족하는지 확인하게 됩니다. 테스트는 비즈니스 전문가가 비즈니스 도메인 언어로 쉽게 이해할 수 있는 방식으로 작성하고 FitFinesse 등을 사용하기도 합니다.
1, 2 사분면의 자동화된 테스트가 제공하는 빠른 피드백은 코드 변경을 포함한 기능 개발 후 자동화 되었을 때나 리팩토링 등 새로운 코드의 도입으로 인한 예상하지 못한 버그를 예방하는 안전망 역할을 합니다. 3사분면과 4사분면은 제품을 평가하는 테스트입니다.
우측 상단 Q3, 3사분면은 소프트웨어가 기대에 만족하는지 알기 위해 동작하는 소프트웨어를 사용해 보는 고객 주도의 비즈니스 중심 탐색 테스팅 영역입니다. 제품 평가 시 실제 사용자가 애플리케이션을 작업하는 방식을 평가합니다.
자동화된 스크립트를 사용해 필요 데이터를 설정할 수 있지만, 고객이 요청한 비즈니스 가치 제공 여부를 확인해야 하기 때문에 사람만이 가능한 수작업 테스트입니다. 우측 하단 Q4, 4사분면의 기술 중심 테스트로 응답시간 등 성능, 보안과 같은 제품 특징을 평가하는 속성 테스팅 영역입니다.
테스트 피라미드
화면은 마이크 콘(Mike Cohn)의 테스트 피라미드 모델입니다. 피라미드 위로 올라갈수록 소프트웨어 기능들의 연계성이 높아지면서 비즈니스 관점이 되고, 아래로 내려갈수록 기능 독립적이고 기술 관점이 됩니다.
피라미드를 이해할 때 중요한 것은 피라미드 위로 올라갈수록 테스트된 기능들의 동작에 대한 확신이 커지는 것처럼 테스트 범위도 늘어난다는 것입니다.
즉, 테스트 시간이 늘어나면서 피드백 순환 시간도 증가해서 테스트가 실패할 때 어떤 기능이 망가졌는지 밝혀내는 것이 더 어려울 수 있습니다.
반면에 피라미드 아래로 내려오면 일반적으로 테스트가 휠씬 빨라지므로 더 빠른 피드백을 얻을 수 있습니다. 따라서 테스트 코드 작성 및 테스트 자동화를 고려할 때 피드백이 빠른 테스트를 자동화하여 자주 수행하도록 하는 것이 효과적입니다.
추가로 피라미드 위로 올라갈수록 시간, 자원적 비용이 증가하기 때문입니다. 단위(메소드) 테스트의 경우 자원접근 레이어의 테스트 등이 될 수 있고, 서비스 테스트는 퍼블리쉬 레이어의 테스트, UI 테스트는 프리젠테이션 레이어의 테스트가 될 수 있습니다.
대부분의 프로젝트에서 테스트하기 어려운 씨퀄(SQL)과 트랜잭션 스크립트 개발방식을 사용하기 때문에 단위 테스트보다는 UI 중심의 테스트를 선호합니다. 테스트는 소프트웨어 아키텍처와 밀접한 관계를 가집니다.
MSA
최근 대두되는 마이크로 서비스 아키텍처는 SRP, 즉 단일 책임 원칙을 적용하여 기존 모놀리틱 아키텍처에 비해 독립적인 배포 가능하고, 다양한 구성 요소에 대한 플랫폼 및 기술 독립성, 유연한 확장 가능성을 가지는 이점이 있습니다.
일반적으로 팀은 하나 이상의 마이크로 서비스에 대한 책임을 담당하고, 각 관련 모듈 간은 요청과 응답을 메시지 교환을 통해 이루지는 느슨한 연결 형태를 가집니다.
대규모 시스템에서는 서로 다른 바운디드 컨텍스트에 대한 책임이 있는 여러 팀이 있습니다. 외부 서비스에 대한 테스트 관심사는 외부 팀 서비스의 인터페이스 및 가용성에 대한 보장이 거의 없기 때문에 팀의 통제 하에 있는 서비스의 테스트 문제와는 다를 수 있습니다.
데이터 교환 방식은 다른 대안이 많지만 JSON이 가장 많이 사용되고 있고, 마이크로서비스 간 메시징 패러다임은 동기식보다는 비동기식 발행-구독 패턴이 더 적합한 형태로 점차 대중화되고 있습니다.
비즈니스 요청은 네트워크로 구분된 다양한 곳에 산재해 있으므로 시스템의 실패 가능성을 고려하는 것이 중요합니다. 타임아웃, 서킷 브레이커, 벌크 헤드와 같은 기술은 마이크로서비스가 장애가 있을 경우 전체 시스템 가동을 유지하는 데 도움이 됩니다.
MSA - Resources
리소스는 서비스에서 공개하는 응용 프로그램 프로토콜과 도메인을 나타내는 객체 간의 Mapper 역할을 합니다. 즉, 수신 받은 요청의 유효성을 검사한 후 내부를 호출하는데, 일반적으로 가벼운 요청/응답의 형태이고, 비즈니스 트랜잭션의 결과에 따라 프로토콜별 응답을 제공합니다. HTTP를 통한 JSON 형태의 REST 방식이 많이 사용되나 Thrift, Protocol Buffer 같은 직렬화 바이너리 스트림 방식을 사용하기도 합니다.
MSA - Service/Domain/Repo
거의 모든 서비스 로직은 비즈니스 도메인을 담고 있는 도메인 모델에 있습니다. 하지만 단일 도메인 모델만으로는 복잡한 비즈니스 트랜잭션 경계를 결정짓기 어렵기 때문에 서비스 레이어를 통해 여러 도메인 안의 객체 간 협력을 조율하고, 리포지토리는 여러 도메인 객체들을 대상으로 데이터 영속성 계층을 유지시키는 인터페이스 역할을 합니다.
MSA - Gateways
외부 서비스로의 연결은 네트워크를 사용하기 때문에 특별한 주의가 필요하고, 외부 연동 실패 시 복원력, 즉 대비책이 있어야 합니다.
게이트웨이는 이런 오류 상황을 처리하는 로직을 가지고 있고, 도메인 간 요청과 응답을 마샬링(Marshalling), 즉 데이터 형태를 변환하고 원격 서비스로 전달하는 메시지를 캡슐화 합니다.
일반적으로 API 간 통신 횟수 감소와 지연 시간을 줄이기 위해 굵게 나뉜 통신 형태를 가집니다. 여기서 굵게 나뉜 통신 형태라는 것은 예로써 시/구/동/우편번호 등 개별로 요청하기보다는 주소라는 큰 단위로 나눈 형태를 말할 수 있습니다.
MSA - Data Mappers/ORM
다른 서비스가 소유한 리소스를 크게 걸쳐 있는 어그리게이트나 특별한 경우를 제외하고 마이크로 서비스는 비즈니스 복잡성을 알고리즘에서부터 분리한 후 도메인 객체 간의 관계로 풀어내는 도메인 모델을 유지할 수 있는 구조가 좋습니다.
또한 DB와 연결되는 Repository 층에서 도메인 객체 모델과 DB 스키마 간 패러다임이 달라서 생기는 임피던스 불일치로 인해서 객체 관계 매핑 또는 더 가벼운 Data Mapper를 사용합니다.
앞에서 언급한 마이크로서비스 외부 연계 부분으로 네트워크나 DB는 통신 대기시간 지연 등으로 오래 걸리거나 중단되어 테스트가 실패할 수도 있습니다.
SW 개발/ 테스트 프로세스
최근에 많이 언급되는 소프트웨어 개발 및 테스트 프로세스 중에 TDD와 BDD가 있습니다. TDD는 아키텍처와 코드 로직에, BDD는 비즈니스 요구사항에 좀 더 집중하는 데 차이가 있습니다.
JUnit 3, 4 버전의 여러 단점을 개선한 TDD 계열의 TestNG 툴도 많이 사용되고 있고, 현재 TestNG의 장점을 수용하여 JUnit 5도 발전하고 있습니다. 또한 BDD 계열의 다양한 도구도 테스트에 많은 도움을 주고 있습니다.
'SW > DevOps' 카테고리의 다른 글
DevOps : UnitTest와 JUnit 개념 및 사용법 (0) | 2019.12.17 |
---|---|
DevOps : UnitTest 개요, 방법 (0) | 2019.12.16 |
DevOps : 리팩토링 기법 (3) (0) | 2019.12.14 |
DevOps : 리팩토링 기법 (2) (0) | 2019.12.13 |
DevOps : 리팩토링 기법 (1) (0) | 2019.12.12 |