# SQLite는 어떻게 테스트되는가

> Clean Markdown view of GeekNews topic #25168. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=25168](https://news.hada.io/topic?id=25168)
- GeekNews Markdown: [https://news.hada.io/topic/25168.md](https://news.hada.io/topic/25168.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-12-19T03:37:36+09:00
- Updated: 2025-12-19T03:37:36+09:00
- Original source: [sqlite.org](https://sqlite.org/testing.html)
- Points: 24
- Comments: 4

## Summary

SQLite는 **코드보다 590배 많은 테스트 코드**와 네 가지 독립 하니스를 기반으로, 상용 DB에 필적하는 신뢰성을 확보합니다. 수억 건의 자동화 테스트와 퍼즈·이상 상황 시뮬레이션을 통해 메모리 부족, I/O 오류, 크래시 등 극단적 조건에서도 일관된 동작을 검증합니다. 이러한 다층적 검증 체계 덕분에 SQLite는 오픈소스임에도 **미션 크리티컬 환경에서 안정적으로 동작하는 데이터베이스 엔진**으로 자리 잡았습니다.

## Topic Body

- SQLite는 **철저한 자동화 테스트 체계**를 통해 높은 신뢰성과 견고성을 유지하며, **코드보다 590배 많은 테스트 코드**가 존재함  
- 네 가지 **독립 테스트 하니스(TCL, TH3, SQL Logic Test, dbsqlfuzz)** 가 핵심 라이브러리를 검증하며, **수억 건의 테스트**를 수행  
- **이상 상황 테스트(OOM, I/O 오류, 크래시 시뮬레이션)** 와 **퍼즈 테스트(fuzz testing)** 를 통해 비정상 입력과 시스템 장애에도 안정적으로 동작함을 확인  
- **100% 분기 및 MC/DC 커버리지**, **리소스 누수 검출**, **Valgrind·정적 분석·체크리스트** 등 다층적 검증 절차를 유지  
- 이러한 체계적 테스트 덕분에 SQLite는 **상용 DB 수준의 신뢰성과 품질**을 확보한 오픈소스 데이터베이스로 평가됨  
  
---  
  
### 1. 개요  
- SQLite의 **신뢰성과 견고성**은 세밀한 테스트 과정에서 비롯됨  
  - 버전 3.42.0 기준, SQLite는 약 **155.8 KSLOC**의 C 코드와 **92053.1 KSLOC**의 테스트 코드로 구성  
- 테스트 체계는 **4개의 독립 하니스**, **100% 분기 커버리지**, **수백만 건의 테스트 케이스**를 포함  
  - OOM, I/O 오류, 크래시, 퍼즈, 경계값, 회귀, 비정상 DB 파일, 최적화 비활성화 테스트 등 다수 항목 포함  
  
### 2. 테스트 하니스  
- **TCL Tests**  
  - SQLite 개발 중 주로 사용되는 공개 테스트 세트  
  - 27.2 KSLOC의 C 코드와 1390개 스크립트 파일(23.2MB)로 구성  
  - 약 **5만여 개 테스트 케이스**, 매개변수화로 전체 실행 시 수백만 건 수행  
- **TH3**  
  - 상용 C 기반 테스트 세트로 **100% 분기 및 MC/DC 커버리지** 달성  
  - 임베디드 환경에서도 동작하며, 1055.4 KSLOC·약 5만여 케이스 포함  
  - 전체 커버리지 테스트 시 약 **2.4백만 건**, 릴리스 전 **2.48억 건 soak 테스트** 수행  
- **SQL Logic Test (SLT)**  
  - SQLite와 PostgreSQL, MySQL, SQL Server, Oracle 10g 결과를 비교  
  - **7.2백만 쿼리**, 1.12GB 데이터로 구성  
- **dbsqlfuzz**  
  - SQL과 데이터베이스 파일을 동시에 변형하는 **libFuzzer 기반 퍼저**  
  - 하루 약 **10억 번의 변이 테스트** 수행, 악의적 입력에 대한 견고성 검증  
- 추가 도구  
  - speedtest1.c, mptester.c, threadtest3.c, fuzzershell.c, jfuzz 등  
  - 모든 테스트는 **다중 플랫폼·컴파일 설정**에서 통과해야 릴리스 가능  
  
### 3. 이상 상황 테스트  
- **OOM 테스트**  
  - malloc() 실패를 시뮬레이션하여 메모리 부족 시 정상 복구 여부 검증  
  - 실패 시점 카운터를 증가시키며 반복 수행  
- **I/O 오류 테스트**  
  - 가상 파일 시스템(VFS)을 이용해 디스크 오류를 시뮬레이션  
  - 오류 후 `PRAGMA integrity_check`로 데이터 손상 여부 확인  
- **크래시 테스트**  
  - 전원 차단·OS 크래시 상황을 시뮬레이션  
  - TCL 하니스는 자식 프로세스 기반, TH3는 메모리 기반 VFS 사용  
  - 트랜잭션의 완전 롤백 또는 완전 완료 여부 검증  
- **복합 실패 테스트**  
  - 크래시 후 OOM 또는 I/O 오류가 연속 발생하는 상황까지 검증  
  
### 4. 퍼즈 테스트  
- **SQL Fuzz**  
  - 문법적으로 유효하지만 비정상적인 SQL을 생성해 SQLite 반응 검증  
- **American Fuzzy Lop (AFL)**  
  - 2014년 도입된 프로파일 기반 퍼저로, 새로운 제어 경로를 탐색  
  - SQLite의 assert 실패·크래시·잘못된 결과를 다수 발견  
- **Google OSS Fuzz**  
  - 2016년부터 Google 인프라에서 자동 퍼징 수행  
  - 신규 커밋에서 간헐적 문제를 탐지  
- **dbsqlfuzz / jfuzz**  
  - 2018년 이후 내부 퍼저로 도입, SQL과 DB 파일 동시 변이  
  - 하루 5억 건 이상 테스트, 외부 퍼저의 버그 리포트 거의 소멸  
  - 2024년부터 jfuzz가 JSONB 입력 검증 추가  
- **타사 퍼저 및 fuzzcheck**  
  - 외부 연구자(예: Manuel Rigger)가 잘못된 결과 계산 사례 다수 발견  
  - fuzzcheck 유틸리티가 과거 퍼즈 케이스 중 ‘흥미로운’ 수천 건을 재검증  
- **MC/DC와 퍼즈 테스트의 긴장 관계**  
  - MC/DC는 방어 코드 최소화, 퍼즈는 방어 코드 필요  
  - SQLite는 두 접근을 병행해 **정상·악의적 입력 모두에 견고한 코드** 유지  
  
### 5. 회귀 테스트  
- 보고된 버그는 수정 후 반드시 **새 테스트 케이스**로 추가  
  - 과거 버그의 재발 방지 목적  
  
### 6. 자동 리소스 누수 검출  
- TCL·TH3 하니스가 **메모리·파일·스레드·뮤텍스 누수** 자동 감시  
  - OOM·I/O 오류 후에도 메모리 누수가 없어야 함  
  
### 7. 테스트 커버리지  
- SQLite 코어는 **TH3 기준 100% 분기 커버리지** 달성  
  - FTS3, RTree 등 확장은 제외  
- **Statement vs Branch Coverage**  
  - 분기 커버리지는 문장 커버리지보다 엄격하며, 모든 조건 분기를 양방향으로 검증  
- **방어 코드 커버리지**  
  - ALWAYS(), NEVER() 매크로로 방어 조건을 명시  
  - 세 가지 정의 형태로 테스트를 반복해 일관성 검증  
- **경계값 및 불리언 벡터 테스트**  
  - testcase() 매크로로 조건의 양·음 결과 모두 검증  
  - 1184개 testcase() 사용  
- **MC/DC 달성**  
  - testcase() 매크로를 통해 모든 조건의 독립적 영향 검증  
- **gcov 기반 측정**  
  - `-fprofile-arcs -ftest-coverage` 옵션으로 커버리지 측정  
  - 결과 비교를 통해 **컴파일러 버그나 정의되지 않은 동작** 탐지  
- **Mutation Testing**  
  - 분기 명령을 변경해 테스트가 이를 감지하는지 확인  
  - 최적화 분기(`/*OPTIMIZATION-IF-TRUE*/`)는 예외 처리  
- **완전 커버리지 경험**  
  - 모든 분기 테스트 덕분에 코드 변경 시 부작용 최소화  
  - 유지 비용은 높지만, 광범위 배포되는 인프라 라이브러리로서 정당화됨  
  
### 8. 동적 분석  
- **Assert()**  
  - 6754개 assert 문으로 전·후조건 및 루프 불변식 검증  
  - `SQLITE_DEBUG` 빌드에서만 활성화  
- **Valgrind**  
  - 메모리 오류·스택 오버플로·초기화되지 않은 메모리 접근 탐지  
  - 릴리스 전 **veryquick 및 TH3 테스트**를 Valgrind로 실행  
- **Memsys2**  
  - `SQLITE_MEMDEBUG` 빌드 시 메모리 오류 감시용 래퍼 삽입  
  - Valgrind보다 빠르게 반복 검증 가능  
- **Mutex Asserts**  
  - `sqlite3_mutex_held()` 등으로 멀티스레드 동기화 검증  
- **Journal Tests**  
  - 롤백 저널이 DB보다 먼저 기록되는지 확인, 트랜잭션 원자성 보장  
- **Undefined Behavior Checks**  
  - `-ftrapv`, `-fsanitize=undefined`, `/RTC1` 등으로 비정의 동작 탐지  
  - 32/64비트, 엔디언, 다양한 CPU 아키텍처에서 반복 수행  
  
### 9. 최적화 비활성화 테스트  
- `sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS)`으로 최적화 끄기  
  - 최적화 유무에 관계없이 동일 결과를 산출해야 함  
  - 일부 성능 측정용 테스트는 예외  
  
### 10. 체크리스트  
- 릴리스 전 약 **200개 항목의 수동 체크리스트** 검증  
  - 일부는 수초, 일부는 수시간 소요  
  - 문제 발견 시 즉시 항목 추가, 지속적 개선  
  
### 11. 정적 분석  
- GCC·Clang·MSVC에서 **경고 없이 컴파일**  
  - Clang Static Analyzer에서도 유효 경고 없음  
  - 정적 분석은 실제 버그 탐지 효과가 제한적  
  
### 12. 요약  
- SQLite는 오픈소스임에도 **상용 수준의 품질과 낮은 결함률**을 유지  
  - 철저한 테스트와 코드 설계가 핵심 요인  
  - 모든 릴리스는 위 절차를 거쳐 **미션 크리티컬 환경에서도 신뢰 가능한 DB 엔진**으로 제공됨

## Comments



### Comment 48001

- Author: regentag
- Created: 2025-12-19T14:01:46+09:00
- Points: 2

함께 보면 좋은 글: [SQLite의 알려지지 않은 이야기](https://news.hada.io/topic?id=4558)  
  
SQLite 개발자 Richard Hipp의 인터뷰를 요약한 글입니다.  
  
SQLite의 개발자들은 록웰 콜린스와 일하던 시기에 Do-178을 알게되어 이 절차를 따르기 시작했다고 합니다. 그 중 하나가 100%의 MC/DC 달성이구요.  
  
Do-178은 정말로 쓸만한 지침서이니 개발자라면 누구나 읽어보시길 추천합니다.

### Comment 48023

- Author: roxie
- Created: 2025-12-19T21:55:48+09:00
- Points: 1
- Parent comment: 48001
- Depth: 1

이건가요? https://alm.parasoft.com/hubfs/ebook-DO-178C-Software-Compliance-Aerospace-Defense.pdf

### Comment 48024

- Author: regentag
- Created: 2025-12-19T22:26:37+09:00
- Points: 2
- Parent comment: 48023
- Depth: 2

링크하신건 Do-178 교육자료인것 같아요.  
원 문서는 이 링크를 보시면 됩니다.  
https://studylib.net/doc/27132454/rtca-do-178b

### Comment 47971

- Author: neo
- Created: 2025-12-19T03:37:36+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=46303277) 
- 10여 년 전 SQLite의 유지보수자가 OSCON에서 **테스트 관행**에 대해 발표했음  
  특히 인상 깊었던 건 **체크리스트(checklist)** 의 힘이었음. 비행 전마다 파일럿이 사용하는 바로 그 도구임  
  그는 또한 **국경없는의사회(Doctors Without Borders)** 사례를 언급했는데, 의료진이 서로 이름도 모르고 언어도 달라서 수술 성과가 낮았다고 함  
  해결책은 간단했음 — 수술 전 체크리스트를 만들어 각자 이름과 역할을 말하게 한 것임. 이 작은 의식이 기술이 아닌 **소통 개선**을 통해 생존율을 높였다고 함  
  관련 자료: [SQLite checklist 예시](https://sqlite.org/src/ext/checklist/3070700/index)
  - 반면 이런 이야기가 **불필요한 관료주의**를 낳는다고 생각함. 항공, MSF, SQLite의 체크리스트는 훌륭하지만, 대부분의 조직은 쓸모없는 체크리스트로 시간을 낭비함  
    좋은 체크리스트와 나쁜 체크리스트의 차이에 대한 논의가 더 필요함. 수학의 **아름다운 공식**처럼 단순해 보이지만 발견하기는 어려운 것 같음
  - 항공 운영과 공학에서 배울 점이 많다고 느껴왔음. 이런 원칙을 **군대식 리더십**과 결합한 IT 조직을 상상해봄  
    특히 미 육군의 FM22-100 문서를 여러 번 읽었는데, 놀라울 만큼 현대적이고 영감을 줌  
    [FM22-100 문서 보기](https://armyoe.com/wp-content/uploads/2018/03/1990-fm-22-100.pdf)
  - 좋은 체크리스트를 만드는 방법을 알고 싶다면 **The Checklist Manifesto**를 강력히 추천함  
    [책 링크](https://atulgawande.com/book/the-checklist-manifesto/)
  - 대부분의 개발자들이 **비프로그래밍적 단순한 일**을 회피하려는 게 이해되지 않음  
    나는 테스트와 CI 외에도 Markdown으로 된 **배포 체크리스트**를 따라감. 결과를 저장하지도 않지만, 단계별로 수행함  
    이렇게 간단한 일을 왜 다른 사람들은 안 하는지 모르겠음
  - 의식이 성과를 높인다는 점이 흥미로움. 요즘 회의에서도 참가자 소개 라운드를 하면 참여도가 확실히 높아짐  
    MSF 사례를 다룬 공식 페이지가 있다면 꼭 보고 싶음. 구글링으로는 찾지 못했음

- SQLite의 테스트 관련 과거 토론들을 모아둠  
  [2009~2024년 HN 스레드 목록](https://news.ycombinator.com/item?id=38963383)  
  재게시가 1년 간격으로 반복되는 듯함

- SQLite 같은 소프트웨어를 완벽하게 다듬는 과정이 부럽고 경이로움  
  장인정신이 느껴지는 작품임
  - 사실 누구나 그렇게 할 수 있음. **천천히, 제대로** 만드는 걸로 해고된 적은 없음  
    시간이 지나면 품질 기준이 높아지고, 같은 노력으로 더 큰 보상을 얻게 됨  
    자신이 손댄 부분을 조금이라도 더 깨끗하게 남기는 사람을 싫어하는 이는 없음

- SQLite는 정말 훌륭한 소프트웨어임. 공식 웹사이트도 **마케팅 대신 정보 중심**이라 좋음  
  다만 최근 HN에 공식 사이트의 페이지들이 하나씩 올라오는 게 흥미로움
  - 아마 어제 **simonw의 LLM 포팅 글**이 화제가 되면서 관련 링크가 다시 주목받은 듯함  
  - HN에서는 이런 일이 주기적으로 반복됨. 예전엔 Haskell이 그랬고, 요즘은 Zig가 그 주기를 도는 중임  
    이런 링크들을 모아두면 재밌을 것 같음

- SQLite가 **공개 소프트웨어**이면서도 **비공개 테스트**를 사용한다는 점이 흥미로움  
  오픈소스 프로젝트가 폐쇄형 테스트를 갖는 게 가능하다는 걸 이제야 깨달음  
  이런 모델이 **오픈코어(open-core)** 와 비슷한 새로운 비즈니스 모델이 될 수도 있을 것 같음
  - 실제로 **테스트 스위트가 코드보다 더 가치** 있는 경우가 많음. 예를 들어 Excel 같은 소프트웨어의 수많은 엣지 케이스를 문서화하는 건 구현보다 어렵기 때문임  
  - 나도 회사 프로젝트에서 비슷하게 함. GPL 이중 라이선스와 함께 **테스트 및 데이터 생성기**는 상용 라이선스 사용자에게만 공개함  
    [예시: railgunlabs/unicorn 라이선스](https://github.com/railgunlabs/unicorn?tab=readme-ov-file#license)

- SQLite의 **100% 브랜치 커버리지**는 프로젝트 자체만큼이나 인상적임  
  지속적으로 유지한다는 게 특히 대단함

- 테스트가 비공개라는 점이 흥미로움. LLM 기반 코딩이 발전하는 지금, **테스트가 구현보다 중요**해지는 시대가 오고 있음  
  최근 simonw가 justHTML 엔진을 Python에서 JS로 거의 자동 변환한 사례를 보며 SQLite의 테스트 전략이 떠올랐음
  - 오픈소스 제품의 **비즈니스 모델** 관점에서 보면, 방대한 테스트 스위트는 효율적인 변경과 가치 창출의 핵심 자산이 됨  
  - SQLite의 *How SQLite Is Tested* 문서는 말 그대로 **테스트의 성서**처럼 느껴짐

- 최근 SQLite와 DuckDB 간 호환성을 고려하며 LLM과 논의했는데, **동시성 처리** 측면에서는 SQLite가 더 낫다는 결론을 얻었음

- SQLite의 테스트 문서에서 **성능 회귀 테스트(performance regression)** 에 대한 언급이 적은 게 의외였음  
  정확성도 중요하지만, 특정 쿼리 경로에서의 성능 저하는 치명적일 수 있음
  - HFT 분야에서 일했지만, **성능 보증**을 내세우는 오픈소스 프로젝트는 거의 본 적이 없음  
    혹시 이런 목표를 핵심 사명으로 삼는 프로젝트가 있는지 궁금함

- SQLite의 안정성을 보면 **이상(anomaly) 테스트**가 어떻게 이루어졌는지 더 알고 싶었음  
  하지만 글에서는 거의 언급이 없었음. 그럼에도 불구하고 SQLite는 모든 기기에서 쓰이는 **가장 견고한 소프트웨어** 중 하나임
  - 테스트 스위트 접근권이 연간 15만 달러 수준이라, 내부 내용을 공개할 가능성은 낮을 것 같음
