소프트웨어 테스팅 및 검증 — Week 7: 임베디드 SW & 신뢰성 있는 SW
과목명: 소프트웨어 테스팅 및 검증
담당교수: 이우진 (경북대학교 IT대학 컴퓨터학부, SW Testing 연구실)
강의자료: 2026_SWTesting7EmbeddedSW
참고문헌: Jim Cooling, Software Engineering for Real-Time Systems, 2002
Part A. 임베디드 소프트웨어 (Embedded Software)
1. 소프트웨어의 유형 복습
1.1 정보 시스템 (Information Systems)
- 대량의 데이터 분류·저장·검색에 관심
- 예시: 신용카드 인증 서비스, 항공 예약 시스템, 온라인 쇼핑몰
- 특성: 데이터 설계 비중 큼, 제어 구조 단순, 개발·운용·유지보수 비용 높음, 문서 중요
1.2 임베디드 시스템 (Embedded Systems)
주 기능이 계산이 아닌 더 큰 시스템에 논리적으로 통합된 시스템이다.
특성: 대규모·장기 운용, 실시간 응답, fail-safe 신뢰성, 비동기·고도 병렬·분산 경향
예시: 공정 제어, 비행기 유도 시스템, 교환기 시스템
2. 컴퓨터 시스템 분류 — 응답 속도 기준
| 유형 | 응답 요구 |
|---|---|
| Batch | 응답 시점에 구애받지 않음 (합리적 범위 내) |
| Interactive On-line | 상당히 짧은 시간 내(수 초) 응답 원함 |
| Real-time | 명확한 시간 제약 내 응답 필수, 아니면 시스템 동작 불가 |
실시간 시스템 예시: 자동 크루즈 컨트롤 시스템 (Control Panel + Vehicle Sensors + Power Unit Control System)
3. 시간과 중요도 (Time and Criticality)
3.1 2차원 분류
| 구분 | Soft | Hard |
|---|---|---|
| Slow | Machine condition monitoring | Airbag control system |
| Fast | Man-machine interfacing | Missile point defense system |
3.2 카테고리별 속성 가중치
| 카테고리 | 실행 시간 | SW 크기 | 데드라인 | SW 복잡도 |
|---|---|---|---|---|
| Hard-Fast | ★★★★ | ★★★★ | ★ | ★ |
| Hard-Slow | ★ | ★★★★ | ★~★★★ | ★~★★★★ |
| Soft-Fast | ★★★★ | ★★ | ★~★★★ | ★~★★★ |
| Soft-Slow | ★★ | ★★ | ★~★★★★ | ★~★★★★ |
4. 임베디드 시스템의 특성
임베디드 컴퓨터는 시스템 내의 한 컴포넌트로 사용되는 컴퓨터를 의미하며, 세 가지 측면으로 특성화된다.
4.1 환경적 측면 (Environmental Aspects)
환경 요소는 하드웨어 설계와 운영자 상호작용에 영향을 미친다.
| 환경 유형 | 요소 |
|---|---|
| 물리적 (Physical) | 온도, 충격·진동, 습도, 크기·무게 제한 |
| 전기적 (Electrical) | 전원 변동, 전기적 간섭 (산업·군용 환경에서 특히 심각) |
| 운영적 (Operational) | "Fit and Forget" 설계, 유지보수 고려 설계 |
온도 사양 범위:
| 범위 | 온도 (°C) |
|---|---|
| Industrial | 0 ~ +85 |
| Extended Industrial | −40 ~ +85 |
| Military | −55 ~ +125 |
| Oil Exploration | −55 ~ +200 |
| Space Exploration | 극단 조건 |
4.2 성능 측면 (Performance Aspects)
설계자는 임베디드 시스템의 실제 성능을 예측해야 한다.
| 태스크 유형 | 설명 |
|---|---|
| 동기 태스크 (Synchronous) | 규칙적·사전 정의된 간격으로 작업 수행 (주기적) |
| 비동기 태스크 (Asynchronous) | 무작위로 발생하는 외부 이벤트에 응답 (비주기적) |
동기 태스크 시간 구성: Te(실행 시간) + Ti(유휴 시간) = Tsam(샘플 시간)
다중 비동기 태스크: 여러 이벤트가 동시에 발생하면 일부는 대기(W) 시간 발생 가능
4.3 실패 모드 (Failure Modes)
모든 시스템은 HW·SW·또는 양쪽의 장애로 인해 언젠가 오류가 발생한다. 모든 실시간 소프트웨어는 예외 처리를 고려해야 한다.
장애 대응 방법:
- 복구 조치 없음 (No-recovery action)
- 서비스 축소 (Graceful degradation)
- 고장 허용 운용 (Fault-tolerant operation)
Part B. 신뢰성 있는 소프트웨어 (Dependable Software)
5. 신뢰성 있는 SW의 품질 요소
| 품질 | 성격 | 정의 |
|---|---|---|
| Correct (정확성) | 정적 · 이상적 | 프로그램이 명세와 일치한다는 정적 속성 (Fault-free SW) |
| Reliable (신뢰성) | 동적 · 현실적 | 요구되는 정밀도로 의도된 기능을 수행할 것으로 기대되는 정도 (Failure per se) |
| Safe (안전성) | 결과적 | 정상·비정상 작동 중에 인명 피해나 환경 손상 없이 운영할 수 있는 능력 (Consequence of failure) |
6. 장애 하의 시스템 행동 (System Behavior under Faults)
장애에 대한 응답은 크게 계속 작동 vs 작동 중단으로 나뉜다.
| 대응 방식 | 설명 |
|---|---|
| Fail-operational | 장애가 있어도 완전한 서비스 제공 |
| Fail-soft | 장애 상태에서 계속 작동하되 성능 저하 |
| Fail-hard | 전체 시스템을 중단(halt) |
| Fail-safe | 정상 운영을 포기하고, 장애로 인한 위험·손상 제한에 집중 |
7. 소프트웨어 오류의 유형
소프트웨어 오류는 시스템 오작동을 유발하는 프로그램의 특징이며, 세 가지 범주로 나뉜다.
| 범주 | 설명 |
|---|---|
| (A) System Design Errors | 시스템 설계 단계의 잘못된 가정 |
| (B) Design and Coding Errors | 설계·코딩 단계의 오류 |
| (C) Environmental Effects | 운영 환경으로 인한 문제 |
7.1 시스템 설계 오류 (A)
시스템 설계 단계에서 시스템과 운영 환경에 대한 많은 가정을 하며, 이것이 잘못되면 이후 모든 것이 잘못된다.
역사적 사례:
- F18 전투기 날개 장착 미사일의 점화 후 분리 실패 — 소요 시간에 대한 잘못된 가정
- 포클랜드 전쟁(1982) HMS Sheffield — 아르헨티나 Exocet 미사일을 비소련제로 식별하여 우군으로 판단, 경보 없이 격침
7.2 설계 및 코딩 오류 (B)
개념을 물리적 제품 없이 컴퓨터 코드로 번역하는 과정에서 발생한다.
| 오류 유형 | 설명 |
|---|---|
| 구문 오류 (Syntactic) | 컴파일러가 잡아내는 문법 오류 |
| 의미 오류 (Semantic) | 소프트웨어가 해야 할 일을 잘못 이해하거나 잘못 번역 |
| 논리 오류 (Logical) | 설계·코딩 중 발생하는 논리 흐름 오류 |
| 알고리즘 오류 (Algorithmic) | 수학적 계산·연산의 실수 |
논리 오류 예시: Post-check 대신 Pre-check, 우발적 무한 루프, 변수 초기화 누락, Deadlock, 잘못된 논리 조건 검사
알고리즘 오류 예시:
| 오류 | 예시 |
|---|---|
| Overflow | 21,000 × 3 (max integer = 32,767) |
| 0으로 나누기 | 51/0 → 불확정 결과 |
| 정밀도 부족 | 3000.0 + 0.0001 = 3000.0 |
역사적 사례:
- Shuttle 레이저 실험 실패 — 피트가 아닌 해리 단위 사용
- Mars Climate Orbiter 파괴 — 영국 단위를 미터법으로 변환 실패
- 밴쿠버 증권거래소 지수 — 2년간 반올림 오류 수정 시 50% 상승
- Ariane 5 첫 발사 실패 — 수평 속도값의 숫자 오버플로
7.3 환경 요인 (C)
소프트웨어가 정상 작동 환경에서 어떻게 동작하는지와 관련된다. HW와 사람 모두 관련되며, 설계 단계에서 완전히 제거할 수 없다. 심층적 설계 분석으로 잠재적 문제 지점을 최소화하는 것만 가능하며, Murphy의 법칙을 수용해야 한다.
사례:
- Fly-by-wire 비행 제어 시스템의 기계적 오작동 → 비행 제어 컴퓨터가 프로그래밍되지 않은 가속 환경 → 추락
- F16 자동 조종 장치가 적도 통과 시마다 비행기를 뒤집음
- 62세 남성이 치료 중 사망 — 치료용 마이크로파 간섭으로 심박조율기가 재설정되어 분당 214회 박동
8. 좋지 못한 소프트웨어의 원인
부실한 소프트웨어는 부정확·신뢰할 수 없음·안전하지 않음·지연·고비용의 특징을 보인다.
| 근본 원인 | 세부 내용 |
|---|---|
| 회사 정신 (Company Spirit) | 고위 경영진 부실, 엄격한 SW 설계 부재, 부적절한 도구, 전문성 부족 |
| SW 팀의 설계 능력 | 복잡성 인식 부족, 공식 문서 부재, SW 설계 도구 미활용, 시스템 프로토타이핑 없음, 재사용 없이 처음부터 설계 |
| 특정 설계 구현 | 불명확한 요구사항, HW·SW 동시 개발 |
9. 테스팅의 한계
정확성 테스팅은 프로그램이 명세를 얼마나 잘 충족하는지만 보여줄 뿐, 요구사항을 검증하지는 않는다. 프로그램의 모든 경로를 확인하는 것은 경로 수의 폭증(path explosion)으로 인해 현실적으로 불가능하다.
10. 좋은 소프트웨어의 기초
10.1 품질 제품 생산 체크리스트
- 명확한 요구사항 기술서 개발
- 설계 솔루션이 이를 달성할 수 있도록 보장
- 프로젝트 관리 가능하도록 개발 조직화
- 일정 준수 가능하도록 조직화
- 주요 재작성 없이 설계 변경 가능하도록 구성
- **테스트 용이성(testability)**을 고려한 설계
- 검증된 방법으로 리스크 최소화
- 안전성에 적절한 우선순위 부여
- 특정 개인에만 의존하지 않도록 관리
- 유지보수 가능한 설계 생산
10.2 핵심 원칙
| 원칙 | 설명 |
|---|---|
| 명세의 정확성 | 명세가 정확한지 확인하는 유일한 방법은 사용자와 대화 |
| 실현 가능성·적합성 | "작동할 것인가", "얼마나 잘 작동할 것인가"에 대한 답 |
| 모듈화 | 프로젝트 관리·유연성 확보, 저수준 태스크를 1인 작업 규모로, 병렬 동작 설계 가능 |
| 이식성·재사용성 | 다양한 환경에서 활용 가능 |
11. 오류 회피와 방어적 프로그래밍
11.1 손상 제한 (Damage Limitation)
오류의 영향을 제한하도록 소프트웨어를 설계해야 한다.
| 장애 원인 | 예시 |
|---|---|
| 인적 요인 | 시스템 샘플링 주기를 너무 빠르게 설정 |
| 계산 문제 | 0으로 나누기 등 유효하지 않은 수학 연산 |
| 하드웨어 장애 | 노후화된 하드웨어의 오작동 |
11.2 방어적 프로그래밍 (Defensive Programming)
방어적 프로그래밍은 내부·외부에서 발생할 수 있는 오류를 인정하며, 다음을 목표로 한다:
- 애초에 장애가 시스템에 유입되지 않도록 방지
- 장애가 발생하면 탐지
- 시스템의 대응 결과를 제어
12. 잘못된 입력(Garbage Input) 보호
"Garbage in, garbage out" — 이상적으로는 "Garbage in, nothing out" 또는 "Garbage in, error message out", 나아가 **"No garbage allowed in"**을 지향해야 한다.
12.1 Garbage In 처리 3가지 방법
- 외부 소스에서 온 모든 데이터 값 확인
- 모든 루틴 입력 매개변수 값 확인
- 불량 입력 처리 방법 결정
역사적 교훈: 시애틀의 I-90 부유 다리 침몰 사건처럼, 작은 문제에 대한 자기 보호가 없으면 대형 참사로 이어질 수 있다.
13. 단정 (Assertion)
13.1 Assertion이란?
- 개발 중 프로그램이 실행되면서 자체 검사할 수 있도록 하는 코드
- 참(True): 모든 것이 예상대로 작동
- 거짓(False): 예기치 않은 오류 탐지
13.2 사용 목적
크고 복잡한 프로그램과 고신뢰성 프로그램에서 특히 유용하며, 불일치한 인터페이스 가정, 코드 수정 시 삽입된 오류 등을 빠르게 찾아낼 수 있다.
13.3 Java Assertion 문법
assert expression;
assert expression1 : expression2;
// 예: assert denominator != 0 : "Denominator is zero";
C++, Java, Visual Basic에는 Assertion 개념이 내장되어 있으며, 없으면 ASSERT 매크로로 쉽게 구현 가능하다.
13.4 Assertion 사용 가이드라인
| 가이드라인 | 설명 |
|---|---|
| 오류 처리 코드 | 발생할 것으로 예상되는 조건에 사용 |
| Assertion | 절대 발생해서는 안 되는 조건에 사용 |
| 실행 코드 회피 | Assertion 내부에 실행 코드를 넣지 말 것 — 컴파일러가 assertion을 끌 때 제거될 가능성 |
| 선행/후행 조건 문서화 | Pre-condition(호출 전 참이어야 하는 속성), Post-condition(실행 종료 시 참이어야 하는 속성) 검증 |
| 병용 | Microsoft Word 소스 코드는 항상 참이어야 하는 조건을 assertion으로 확인하고, assertion 실패 시에도 오류 처리 코드로 대응 |
14. 오류 처리 기법 (Error Handling Techniques)
| 기법 | 설명 | 주의사항 |
|---|---|---|
| 중립값 반환 | 무해한 기본값 반환 (숫자: 0, 문자열: 빈 문자열, 포인터: null) | 암 x선 데이터 표시 등 안전 중요 상황에서는 부적절 |
| 다음 유효 데이터 대체 | DB 레코드가 손상되었으면 유효한 레코드를 찾을 때까지 계속 읽기 | — |
| 이전 답과 동일 반환 | 온도계 소프트웨어가 이번 판독 실패 시 이전 값 반환 | 현금 인출기 거래 승인에는 부적절 |
| 가장 가까운 합법 값으로 대체 | 0~100°C 온도계에서 음수 감지 시 0으로 대체 | — |
15. 견고성 vs 정확성 (Robustness vs Correctness)
| 속성 | 정의 |
|---|---|
| Correctness | 부정확한 결과를 절대 반환하지 않음. 결과를 반환하지 않는 것이 부정확한 결과보다 나음 |
| Robustness | 결과가 때때로 부정확하더라도, 소프트웨어가 계속 작동하도록 항상 시도 |
| 애플리케이션 유형 | 우선순위 |
|---|---|
| 안전 중요 (Safety-critical) — 방사선 치료 기계 등 | Correctness > Robustness (잘못된 결과보다 결과 없음이 나음) |
| 소비자 애플리케이션 — 워드 프로세서 등 | Robustness > Correctness (종료되는 것보다 어떤 결과든 나옴이 나음) |
16. 예외 (Exception)
예외는 코드가 호출자에게 오류나 예외적 이벤트를 전달하는 특정 메커니즘이다. 한 루틴에서 코드가 처리 방법을 모르는 예기치 않은 조건을 만나면 예외를 throw한다.
Java 예외 구조:
try {
// 예외가 발생할 수 있는 코드
} catch (ExceptionType e) {
// 예외 처리
} finally {
// 항상 실행되는 코드 (선택)
}
핵심 키워드 정리
임베디드 시스템 실시간 시스템 Hard/Soft Real-time 동기 태스크 비동기 태스크 Fail-operational Fail-soft Fail-hard Fail-safe Correct Reliable Safe System Design Error Semantic Error Algorithmic Error Overflow Defensive Programming Assertion Pre-condition Post-condition Robustness vs Correctness Exception Handling