> [!abstract] Introduction
> 이번 글에서는 소프트웨어 공학의 테스트에 대해 알아봅니다.
# 테스트
> [!info] Definition
> - the process of executing program or system with intent of finding errors. \[The Art of Software Testing, 1979\]
> - set of activities conducted to facilitate discovery and evaluation of properties of test items. \[ISO/IEC/IEEE 29119-1:2022\]
테스트란, ==결함을 발견할 의도로 프로그램이나 시스템을 실행시키는 것== 혹은 ==테스트 대상의 특성을 발견하고 평가하기 위해 수행되는 일련의 활동==을 가리킨다. 과거의 테스트는 그저 프로그램을 실행시키고 그 프로그램이 잘 실행되는지 확인하는 것이 전부였지만, 이제는 아직 발생하지 않은 결함을 찾기 위해 테스트를 진행한다. 그 방법은 정적*static* 테스트와 동적*dynamic* 테스트로 나뉘는데, 두가지 테스트를 가르는 기준은 프로그램의 실행 여부다.
테스트를 수행하는 관점도 크게 두가지로 나뉘는데, 바로 검증*Validation*과 확인*Verification*이다. 두 단어 모두 실증, 입증, 검증과 같은 단어로 번역되지만, 적어도 소프트웨어 테스팅의 영역에서 Validation과 Verification이 가지는 의미는 명백히 구분된다. 명세서가 실제 사용에 맞게 쓰여졌다는 것만 보장된다면 Validation이 필요없겠지만, 샘플링과 시간의 문제로 인해 Verification(명세에 부합한지 판단)과 Validation(실제 사용에 적절한지 판단)이 모두 필요하다.
## 정적 테스트
정적 테스트는 프로그램을 실행하지 않고 테스트를 진행하는 것이다. 대표적인 방법으로는 사람이 직접 코드를 검토하는 방법과 정적 분석*Static Analysis* 도구를 통해 코드를 검사하는 방법이 있다.
## 동적 테스트
동적 테스트는 프로그램을 실행하면서 테스트를 진행하는 방법으로, 동적 분석*Dynamic Analysis*, 동적 테스팅*Dynamic Testing* 등의 방법이 있다.
## Verification
Verification은 ==명세서대로 제품이 만들어졌는지==를 테스트하는 관점이다. 그러니까 제품 자체를 평가하기보다는 요구사항에 맞게 제품이 제대로 만들어졌는지를 평가하는 것이다.
## Validation
Validation은 ==알맞는 제품이 만들어졌는지==를 테스트하는 관점이다. 즉 Verification과 달리 제품이 의도에 맞게 작동하는지를 평가하는 것이다.
# 테스팅 단계
테스트는 작은 영역부터 시작해 큰 영역으로 확장해 나아간다.
## 단위 테스트
우선 단위 테스트부터 시작한다. 단위 테스트는 유닛 테스트*Unit Test*, 컴포넌트 테스트*Component Test*라고도 부르며 소프트웨어의 단위 모듈이나 컴포넌트에 대한 테스트를 의미한다. 이 테스트는 주로 개발 당사자가 수행하며 각 모듈/컴포넌트가 제대로 작동하는지 테스트한다.
## 통합 테스트
통합 테스트*Integration Test*는 모듈/컴포넌트 단위의 개발이 끝난 후, 각 모듈/컴포넌트를 점진적으로 통합하는 단계에서 수행한다.[^integration-test-multiple] 이 테스트는 개발조직이 개발자의 관점에서 수행하고, 개발 환경 내지 통합 환경 하에 주로 기능의 완성도나 인터페이스의 정상 작동 유무를 확인하며 컴포넌트 간의 결합이 잘 이루어졌는지를 점검한다.
## 시스템 테스트
시스템 테스트*System Test*는 통합 작업이 모두 완료된 다음 실시하는 테스트다. 시스템을 구성하는 모든 컴포넌트가 시스템에 결합되고 이 시스템이 사용자에게 배포되기 전에 개발조직이 사용자의 관점에서 테스트를 수행하게 된다. 따라서 테스트가 이루어지는 환경도 실제 운영 환경 혹은 그에 준하는 환경으로 구성되며, 기능 검증뿐만이 아니라 사용자가 체감하는 성능, 보안, 사용성 등 비기능적 품질 속성이 중요한 평가 기준으로 떠오른다.[^non-functional-testing-timing] 그래서 시스템 테스트란, 시스템 전체가 요구사항대로 동작하는지 확인하는 것이다.
## 인수 테스트
시스템 테스트까지 통과하고 나면 테스트의 주체는 개발 조직에서 인수자, 즉 사용자로 넘어간다. 이 테스트는 시스템 인수 직전 사용자의 최종 점검이라고도 할 수 있으며 실제 운영 환경 혹은 그에 준하는 환경에서 사용자가 사용자, 고객 관점에서 요구사항 충족 여부, 실사용 적합성, 법/규제 준수 여부 등을 확인한다. 이를 통해 고객은 시스템 인수 여부를 최종 결정하며, 테스트는 최종 사용자 테스트, 필드 테스트, 베타 테스트 등 다양한 형태로 이루어진다.
[^integration-test-multiple]: 그래서 사실 통합 테스트는 하나일 수 없다. 통합 작업이 완전히 끝난 상태와 통합이 전혀 되지 않은 상태 사이에는 수많은 통합의 과정이 포함되어 있기 때문에, 통합 테스트는 각 컴포넌트를 하나로 통합하는 과정에 여러가지 형태로 존재한다.
[^non-functional-testing-timing]: 그렇다고 해서 앞선 단계에서 비기능적 품질 속성을 테스트하지 않았다는 뜻은 아니다. 다만 사용자가 체감하는 비기능적 품질 속성은 시스템 구성이 완료되고 나서야 테스트할 수 있다는 의미다.