> [!abstract] Introduction
> 이번 글에서는 소프트웨어 품질 보증*Software Quality Assurance*에 대해 알아봅니다.
# Software Quality Assurance
[[소프트웨어의 표준#^0e8453|소프트웨어의 품질]]이 만족할 만한 수준이라는 확실한 증거를 얻기 위해서는 무엇이 필요할까? 소프트웨어 제품의 품질과 개발 프로세스의 품질을 연결하는 것도, 소프트웨어의 품질을 평가하기 위한 여러 지표도 그 질문에 대한 답을 얻기 위한 노력의 산물이다. 소프트웨어의 품질이 만족할 만한 수준이라고 확실하게 말하기 위해서는 소프트웨어의 품질을 보증하기 위한 활동, 소프트웨어 품질 보증이 필요하다. 아래에 그 정의가 적혀 있다.
> [!info] Definition
> - 소프트웨어 프로세스의 적합성을 정의하고 심사하는 일련의 활동으로, 소프트웨어 프로세스가 의도된 목적에 적합한 품질있는 소프트웨어 제품을 개발한다는 신뢰를 위한 증거를 제공하기 위함 (IEEE 730:2014)
> - 정의된 표준, 절차, 방법이 적용됨을 보증하기 위한 계획되고 체계적인 활동으로, 프로세스 및 제품의 품질 보증*Process and Product Quality Assurance, PPQA*의 목적은 프로젝트 구성원과 경영층에게 프로세스와 산출물에 대한 객관적인 통찰을 제공하기 위함 (CMMI-DEV 1.3)
## QA(Quality Assurance) vs QC(Quality Control)
품질 보증과 품질 통제*Quality Control*은 제조업에서의 품질 관리 개념이 진화하면서 등장하게 되었는데, 둘의 차이는 진화의 과정에서 설명된다.
장인의 역량 -> 1차 산업혁명, 근대적 생산 공장의 탄생 -> 작업 감독관 -> 감독관의 책임과 압박 상승, WW1 -> 정밀 검사, 독립적인 검사자 -> 제품 기능의 복잡도 향샹, WW2 -> 테스팅, 통계적 품질 관리 (여기서 품질 통제의 개념이 도입됨) -> 경쟁심화로 제조품질의 한계 봉착, 설계 품질 향상 필요 -> 표준과 가이드(여기서 품질 보증의 개념이 도입됨) -> 품절은 특정 부서의 책임이 아니라 조직의 문화임 -> 전사적 품질관리 활동(Total Quality Management 개념이 도입됨)
그래서 품질 통제는 댜음과 같이 정의된다.
> [!info] Definition
> 개발 또는 제조된 제품의 품질을 평가하기 위해 설계된 일련의 활동 (ISO/IEC/IEEE 24765:2017)
표로 비교하면 다음과 같다.
| | 품질 보증 (QA) | 품질 통제 (QC) |
| --- | ---------------------------------------------------------------------- | ------------------------------------------- |
| 목표 | 결함 방지 | 결함 발견 |
| 초점 | 프로세스 | 제품 |
| 방법 | 품질 개선 노력을 통한 지속적인 개발 경험의 향상과 함께 작업 방식, 프로세스의 개선을 도모함 | 소프트웨어 개발 산출물이 출시되기 전에 이에 대한 결함을 발견하고 수정함 |
| 필요성 | 결함을 최소화하고 조기에 결함을 발견해 불필요한 자원의 낭비를 최소화하거나 제거하고 소프트웨어 프로젝트의 신뢰성을 부여해준다. | 중요한 결함을 빠르게 발견하고 결함의 발생지를 추적해 원인을 분석할 수 있다. |
## SQA의 원칙
SQA 수행체계는 조직의 규모나 프로젝트의 개발 규모, 제품 특성, 고객 요구사항, 개발 라이프사이클 등을 고려하여 정의한다. 결함 유입을 최소화하고 유입된 결함은 가능한 일찍 발견해야 한다. 라이프사이클 전체를 고려하고 고객의 관점에서 프로젝트를 바라보아야 한다. 그리고 품질 보증 활동의 객관성을 확보해야 한다.
## QA In Production
![[QAInProduction.png]]
전통적으로 QA 활동은 배포 이전 활동에 중점을 두었지만, 복잡한 소프트웨어와 복잡한 운영 환경에서 수행 중인 소프트웨어를 모니터링하여 품질 이슈를 식별할 필요가 있게 되면서 프로덕션에서 바로 만들어지는 데이터를 통해 배우고 현실에 기반한 QA 접근이 가능하게 되었다.
이 혜택을 톡톡히 받아 CMMI에서 소프트웨어 품질 보증을 맡고 있는 프로세스 영역은 바로 프로세스 및 제품의 품질 보증이다. 이 프로세스 영역의 목표와 프랙티스를 살펴보자.
# Process and Product Quality Assurance
^0a76ec
프로세스 영역의 목표와 프랙티스는 아래 다이어그램과 같다.
![[ProcessAndProductQualityAssuranceDiagram.png]]
## Objectively Evaluate Processes and Work Products
프로세스 그리고 프로세스와 연결된 산출물이 프로세스의 기술, 프로세스의 표준, 그리고 프로세스의 절차에 충실한지 객관적으로 판단하는 것이 PPQA의 첫번째 목표다. 여기에는 두 개의 프랙티스가 존재한다.
### Objectively Evaluate Selected Performed Processes Against Applicable Process Descriptions, Standards, and Procedures
첫번째 프랙티스는 수행된 프로세스와 객관적으로 비교하는 방식으로 적용 가능한 프로세스를 평가하는 것이다. 이미 수행된 프로세스 그 자체를 두고 다른 대안을 적용하는 게 더 낫지 않았는지 비교하는 것이다.
### Objectively Evaluate Selected Work Products Against Applicable Process Descriptions, Standards, and Procedures
두번째 프랙티스도 첫번째와 비슷하지만, 이번에는 산출물이 평가의 대상이 된다. 프로세스의 결과로서 만들어진 산출물과 적용 가능한 다른 프로세스의 결과로 나왔을 산출물을 비교하게 된다.
## Provide Objective Insight
PPQA의 두번째 목표는 객관적인 인사이트를 제공하는 것이다. 기존의 계획이나 목표를 충족하지 못하면서 생긴 이슈*Noncompliance Issue*들은 객관적인 기준 아래에서 추적되고 소통되며, 이러한 이슈들은 반드시 해결되어야 한다. 이를 위한 프랙티스는 총 두 개다.
### Communicate quality issues and ensure the resolution of noncompliance issues with the staff and managers.
품질 이슈에 대해 프로젝트에 참여한 스태프들과 관리자들과 소통하고 기대치를 충족하지 못한 부분이 반드시 채워지도록 보장해야 한다.
### Establish and maintain records of quality assurance activities.
이러한 모든 품질 보증 활동은 기록되어야 한다.
# Quality Assurance Activities
그런데 품질 보증 활동에는 어떤 것들이 있을까? 기준은 Verification과 Validation이다. Verification은 내가 지금 일을 올바르게 하고 있는지 점검하는 것이며, Validation은 내가 지금 올바른 일을 하고 있는지 점검하는 것이다. 주요 방법으로는 검토[^1], 테스팅(정적 테스트 / 동적 테스트), 감사*Audit*, 제품 메트릭 수집/분석 등이 있다. 그렇다면 어떤 방법이 제일 좋은 방법일까?
## Test vs Pretest
소프트웨어의 품질을 추산하거나 실제로 품질을 측정할 때 중요한 주제 중 하나는 예비 검사*pretest*에서 오류를 제거하는 활동*removal activity*과 테스트 단계에서 결손 제거의 효율성*defect removal efficiency*이 어느 정도 수준인지 아는 것이다.
### Test
아래 표는 기능 점수가 10,000점이거나 자바와 같은 언어로 500,000개의 선언문이 작성된 정도의 크기를 가진 애플리케이션을 전제로 테스트 단계에서 일어나는 활동의 효율성을 분석한 것이다. 데이터는 결손 제거 효율성의 내림차순으로 정렬되어 있다.
![[SummaryOverviewOfMajorSoftwareTestingStages1.png]]
위와 아래에 표가 이어져 있는데, 이중에서 시스템 테스트*System Testing*와 새로운 함수 테스트*New Function Testing*, 회귀 테스트*Regression Testing*, 그리고 단위 테스트*Unit Testing*이 새로운 결손을 낳는 잘못된 수정을 주입하는 비율*Bad-Fix Injection Percent*이 유독 높은 편인 것을 확인할 수 있다.
![[SummaryOverviewOfMajorSoftwareTestingStages2.png]]
이것을 정리해보자면, 테스트가 결손을 아주 잘 찾아내거나 비용 측면에서 엄청 효율적이었던 적은 없는 셈이다.
### Pretest
그렇다면 예비 검사에서는 어떨까? 예비 검사에서의 결손 제거*Pretest Defect Removal*는 실제 테스트를 진행하기 이전에 결손을 제거하는 여러가지 활동을 뜻한다. 직접 코드를 읽어가며 코드를 검사*traditional desk checking*하거나 비공식적인 동료 리뷰*informal peer review*를 받는 것부터 설계와 코드에 대한 공식적인 정밀 검사, 그리고 소스 코드에 대한 정적 검사까지 포괄하는 개념이다. 버그를 잡는 데 효과적이고 비용 절감 효과도 같이 누릴 수 있다. 테스트 사이클 횟수가 줄고 테스트의 효율이 높아진다. 예비 검사 단계에서 정밀하게 검사하고 정적 분석을 하는 것이 테스팅보다 25% 더 효율적이고, 추가적인 정밀 검사와 정적 분석이 테스트의 효율 수준을 5% 가량 올려줄 수 있다.
![[DefectRemovalEfficiencyRanges.png]]
위 테이블을 보면 모든 테스트를 조합해도 누적 결손 제거 효율성이 85%를 넘기기가 힘들고 95%를 넘으려면 예비 검사 단계와 최소 8가지 이상의 정식 테스트를 모두 거쳐야 한다. 다행히 결손 제거 효율성이 95%를 넘어가면 테스팅만 하는 것보다 비용도 낮고 일정도 짧아서 품질도 높아지고 개발 속도도 올라간다.
예비 검사 단계에서 결손을 미리 제거하는 방법은 프로젝트의 규모에 따라 달라지는데, 작은 규모의 프로젝트에서는 스스로 직접 코드를 검토하거나 스크럼 세션을 가지거나 명세서에 대한 분명한 리뷰, 동료들의 비공식적인 리뷰, 코드의 정적 분석 등을 통해 찾을 수 있지만 더 큰 규모에서는 독립적인 검증과 인증*Independent V&V*, SQA(Software Quality Assurance) 리뷰, 페이즈 리뷰, 각종 형식적인 정밀 검사들이 추가된다.
---
[^1]: Peer Review, Walkthrough, Inspection 등을 포괄한다.