소프트웨어 테스트, 형상관리와 CI/CD
테스트 수준·기법·커버리지와 형상관리, Git, CI/CD, 리팩터링의 흐름을 학습한다.
1. 테스트의 목적
소프트웨어 테스트는 결함을 발견하고 요구사항과 품질 기준 충족 여부를 확인하며 릴리스 위험을 줄이는 활동이다. 테스트는 결함이 없음을 완전히 증명하기보다 주어진 범위에서 문제를 발견하고 신뢰 근거를 제공한다.
요구사항·위험
↓
테스트 계획
↓
테스트 설계·데이터 준비
↓
환경·코드 준비
↓
실행·결과 기록
↓
결함 분석·수정·재시험
↓
종료 기준·보고
2. 정적 테스트와 동적 테스트
| 구분 | 실행 여부 | 예시 |
|---|---|---|
| 정적 테스트 | 프로그램을 실행하지 않음 | 리뷰, 워크스루, 인스펙션, 정적 분석 |
| 동적 테스트 | 프로그램을 실행함 | 단위·통합·시스템·인수 테스트 |
정적 테스트는 요구·설계·코드의 결함을 조기에 찾는 데 유리하다.
3. 테스트 수준
단위 테스트
↓ 모듈·클래스·함수
통합 테스트
↓ 모듈·서비스 사이 인터페이스
시스템 테스트
↓ 전체 시스템의 기능·비기능 요구
인수 테스트
사용자·발주자의 수용 기준
- 단위: 작은 코드 단위의 로직
- 통합: 컴포넌트·DB·외부 시스템 연계
- 시스템: 전체 시스템의 기능·성능·보안·복구
- 인수: 실제 업무와 계약 기준 충족
- 회귀 테스트: 변경 후 기존 기능이 깨지지 않았는지 확인
빅뱅 통합, 상향식, 하향식, 샌드위치 통합의 특징도 구분할 수 있다. 하향식은 하위 모듈을 대신하는 stub, 상향식은 상위 호출자를 대신하는 driver를 사용할 수 있다.
4. 화이트박스 테스트
내부 제어구조와 코드 경로를 기준으로 테스트한다.
- 문장 테스트
- 분기·결정 테스트
- 조건 테스트
- 경로 테스트
- 루프 테스트
- 데이터 흐름 테스트
커버리지
문장 커버리지 = 실행된 문장 수 / 전체 문장 수 × 100
분기 커버리지 = 실행된 분기 결과 수 / 전체 분기 결과 수 × 100
조건 커버리지 = 각 개별 조건의 참·거짓 실행 여부
예시:
if (a > 0 && b > 0) {
result = 1;
} else {
result = 0;
}
분기 커버리지 100%는 if 전체 결과의 참·거짓을 모두 실행하면 달성할 수 있지만, 각 개별 조건 a>0, b>0의 참·거짓 조합을 모두 확인했다는 뜻은 아니다.
순환 복잡도는 독립 경로 수를 추정하는 데 사용한다. 제어흐름 그래프에서 대표 공식은 E - N + 2P이며, 연결된 단일 컴포넌트라면 보통 P=1이다.
5. 블랙박스 테스트
내부 구현보다 입력과 출력, 요구사항을 기준으로 테스트한다.
동등분할
비슷하게 처리될 것으로 예상되는 입력 집합을 유효·무효 클래스로 나누고 대표값을 선택한다.
나이 허용범위: 18~65
무효 클래스: x < 18
유효 클래스: 18 ≤ x ≤ 65
무효 클래스: x > 65
경계값 분석
결함이 발생하기 쉬운 경계 주변을 선택한다.
17, 18, 19, 64, 65, 66
결정 테이블
조건 조합과 행동을 표로 만들어 복합 업무 규칙을 테스트한다.
상태 전이 테스트
상태, 이벤트, 전이와 금지된 전이를 확인한다.
유스케이스 테스트
사용자 목표의 기본·대안·예외 흐름을 시나리오로 검증한다.
6. 테스트 더블
| 종류 | 목적 |
|---|---|
| Stub | 호출된 구성요소 대신 정해진 응답 제공 |
| Driver | 하위 구성요소를 호출하는 상위 역할 대체 |
| Mock | 예상 호출과 상호작용을 검증 |
| Fake | 단순하지만 동작하는 대체 구현 |
용어 사용은 도구·문맥에 따라 조금 다를 수 있으므로 핵심 목적을 이해한다.
7. 결함 생명주기
발견 → 등록 → 분류·우선순위 → 담당 배정
→ 수정 → 재시험 → 종료
└─ 실패 시 재오픈
심각도는 결함의 영향, 우선순위는 수정 시급성을 나타낸다.
8. 형상관리
형상관리는 소프트웨어 형상항목의 버전과 변경을 식별·통제·기록·감사하는 활동이다.
- 형상 식별
- 버전 관리
- 변경 통제
- 상태 기록·보고
- 형상 감사
- 빌드·릴리스 관리
변경 요청
↓
영향 분석·승인
↓
브랜치·수정·리뷰
↓
빌드·테스트
↓
기준선 갱신
↓
릴리스·기록·감사
기준선은 공식 검토·승인을 거쳐 변경통제 대상이 된 산출물 집합이다.
9. Git 기본 흐름
Working Tree
│ git add
▼
Staging Area
│ git commit
▼
Local Repository
│ git push
▼
Remote Repository
- commit: 변경 스냅샷과 이력
- branch: 독립적인 변경 흐름
- merge: 분기한 이력을 통합
- rebase: 커밋 기반을 다시 배치
- tag: 특정 릴리스 지점 표시
- pull request·merge request: 코드리뷰와 통합 절차
10. CI/CD 파이프라인
CI는 변경을 자주 통합하고 자동 빌드·테스트로 문제를 빠르게 발견하는 실천이다. CD는 Continuous Delivery 또는 Continuous Deployment 문맥을 구분해야 한다.
- Continuous Delivery: 운영 배포 가능한 상태를 지속적으로 만들되 운영 반영에 승인 단계가 있을 수 있음
- Continuous Deployment: 자동 검증을 통과한 변경을 운영까지 자동 배포
개발자 commit
↓
소스 저장소
↓ trigger
정적 분석·빌드
↓
단위 테스트
↓
통합·보안 테스트
↓
아티팩트 저장
↓
시험 환경 배포
↓
시스템·인수 검증
↓
승인 또는 자동화 정책
↓
운영 배포
↓
모니터링·롤백
파이프라인이 있다고 품질이 자동 보장되는 것은 아니다. 테스트 품질, 환경 일관성, 비밀관리, 승인·롤백 정책이 필요하다.
11. 배포 전략
- Rolling: 인스턴스를 순차 교체
- Blue-Green: 두 환경 중 새 환경으로 트래픽 전환
- Canary: 일부 사용자·트래픽에 먼저 배포
- Feature Flag: 코드 배포와 기능 노출을 분리
전략마다 비용, 롤백 속도, 동시 버전 호환성, DB 변경 문제가 다르다.
12. 리팩터링과 코드 스멜
리팩터링은 외부에서 관찰되는 기능을 유지하면서 내부 구조를 개선하는 활동이다. 안전한 자동 테스트가 변경 위험을 줄인다.
대표 코드 스멜:
- 중복 코드
- 긴 함수·클래스
- 지나치게 많은 매개변수
- 서로 다른 이유로 자주 변경되는 클래스
- 한 변경 때문에 여러 클래스를 함께 수정해야 하는 구조
- 원시 타입 집착
- 과도한 조건 분기
- 사용하지 않는 추상화
대표 리팩터링:
- Extract Method
- Rename
- Extract Class
- Introduce Parameter Object
- Replace Conditional with Polymorphism
- Move Method
코드 스멜은 곧바로 오류라는 뜻이 아니라 유지보수 위험을 알리는 신호이다.
13. 조건 조합과 MC/DC
분기 커버리지 100%만으로 각 원자 조건의 독립적 영향이 검증되지는 않는다.
if (A && B) action();
(A,B)=(T,T),(F,T),(T,F)의 세 테스트는 A와 B 각각을 하나씩 바꿀 때 결정 결과가 바뀌는 쌍을 제공해 이 식의 MC/DC를 만족할 수 있다. 복잡한 식에서는 단락 평가와 불가능 조합을 함께 고려한다.
14. 변이 테스트와 테스트 오라클
변이 테스트는 연산자 변경·조건 반전처럼 작은 인공 결함을 넣고 기존 테스트가 이를 검출하는지 본다.
변이 점수 = 죽인 비동등 변이체 수 / 전체 비동등 변이체 수 × 100
동등 변이체는 코드가 달라도 관찰 결과가 같아 테스트로 죽일 수 없으므로 분모에서 제외한다. 테스트 오라클은 실제 결과가 올바른지 판정할 기대값·규칙·비교 대상을 뜻한다.
15. 조합·위험 기반 테스트
입력 인자가 많아 모든 조합을 실행하기 어렵다면 pairwise 테스트로 모든 인자 쌍의 값 조합을 최소 집합에 포함할 수 있다. 이는 모든 3개 이상 상호작용 결함을 보장하지 않는다.
위험 우선순위 예 = 발생 가능성 × 영향도
위험이 큰 기능은 더 깊은 테스트, 조기 실행, 복구·보안 시나리오를 배정한다.
16. Git 변경 취소 구분
| 명령·개념 | 핵심 |
|---|---|
revert | 기존 커밋을 취소하는 새 커밋 생성, 공유 이력에 안전 |
reset | 브랜치 포인터와 작업·스테이징 상태 이동, 공개 이력 재작성 주의 |
rebase | 커밋을 새 기반 위에 다시 작성, 공유 커밋 사용 주의 |
cherry-pick | 선택한 커밋의 변경을 현재 브랜치에 새 커밋으로 적용 |
17. 불변 아티팩트와 점진 배포
CI에서 검증한 동일한 아티팩트를 시험·스테이징·운영으로 승격해야 “테스트한 것과 배포한 것”이 같아진다. 환경마다 다시 빌드하면 의존성·시간·설정 차이로 결과가 달라질 수 있다.
Rolling·Canary 배포 중에는 구버전과 신버전이 동시에 실행될 수 있으므로 DB 변경은 기존 코드와 함께 동작하는 확장-이행-축소 단계로 설계한다.
1. 새 열·테이블 추가(호환)
2. 양쪽 버전 지원·데이터 이행
3. 신버전 전환 확인
4. 구 구조 제거
확인 문제
A && B의 MC/DC를 만족할 수 있는 대표적인 최소 테스트 조합 3개는 무엇인가?- 죽인 비동등 변이체 18개, 전체 비동등 변이체 20개이면 변이 점수는 얼마인가?
- 공유 저장소의 잘못된 커밋을 이력을 보존하며 취소하는 데 적합한 Git 명령은 무엇인가?
- CI에서 검증한 동일 아티팩트를 환경별로 승격하는 이유는 무엇인가?
- Rolling 배포 중 DB 스키마 변경이 구버전과 신버전을 모두 지원해야 하는 이유는 무엇인가?