Skip to content

Chapter 11 - 테스트 개요

  • '버그 잡기'는 테스트를 하는 여러 이유 중 하나일 뿐입니다.
  • 예를들어 '소프트웨어가 변화할 수 있도록 지원'하는 역할 역시 버그 잡기에 못지않게 중요합니다. 새로운 기능을 추가하거나, 코드가 더 건실해지도록 리팩터링하거나, 대규모 재설계를 진행하는 상황에서 자동 테스트는 실수를 빠르게 잡아주므로 안심하고 소프트웨어를 변경할 수 있게 해줍니다.
  • 어떻게 해야 테스트를 잘할 수 있는지는 여전히 많은 이에게 의문으로 남아 있습니다.

11.1 테스트를 작성하는 이유

11.1.1 구글 웹 서버 이야기

  • GWS는 구글 검색 쿼리를 제공하는 웹 서버로, 구글 검색에 있어서는 마치 공항의 관제 시스템만큼 중요했습니다. 이 프로젝트의 규모와 복잡성이 커지면서 생산성이 급격히 떨어졌습니다. 릴리스 때마다 버그가 넘쳐났고 다음 릴리스까지의 기간도 점점 길어졌습니다. 서비스를 수정해야 할 때면 팀원들은 불안해 했고 프로덕션 환경에서만 기능들이 작동하지 않는 일도 잦았습니다.
  • 이 문제들을 해결하고자 GWS의 테크 리드(TL)는 엔지니어 주도의 자동 테스트를 정책 차원에서 도입하기로 했습니다. 정책 도입 1년 만에 긴급하게 코드를 수정해 배포하는 건수가 '절반'으로 줄었습니다. 반영된 변경 개수 기록을 매 분기 갈아치우는 와중에 달성한 수치입니다.
  • 훌륭한 엔지니어로만 구성된 이 팀도 매일(근무일 기준) 5개의 버그를 양산합니다.

11.1.2 오늘날 개발 속도에 맞는 테스트

  • 하루에도 몇 번씩 새로운 버전을 릴리스해야 하죠
  • 해법은 단 하나, 바로 '자동화'뿐입니다.

11.1.4 테스트 코드가 주는 혜택

  • 디버깅 감소
  • 자신 있게 변경
    • 모든 소프트웨어는 변경됩니다. 좋은 테스트들로 무장한 팀은 자신감을 가지고 변경들을 리뷰하고 수용할 수 있습니다.
  • 더 나은 문서자료
    • 마치 실행 가능한 문서와 같습니다.
  • 더 단순한 리뷰
  • 사려 깊은 설계
    • 코드의 테스트를 작성하는 일은 실질적으로 해당 코드의 API가 잘 설계되었는지를 시험하는 행위입니다.
  • 고품질의 릴리스를 빠르게

11.2 테스트 스위트 설계하기

  • 더 작은 테스트가 더 빠르고, 안정적이고, 평균적으로 고통이 적다는걸 깨우쳤죠.
  • 논의 끝에 우리는 두 가지 독립된 요소가 있다는 결론에 이르렀습니다. 바로 크기와 범위입니다.
  • 크기는 테스트 케이스 하나를 실행하는 데 필요한 자원을 뜻합니다. 메모리, 프로세스, 시간 등이죠. 한편 범위는 검증하려는 특정한 코드 경로를 뜻합니다.
테스트 스위트 설계하기를 설명하기에 앞서서 테스트의 크기에 대해서 먼저 정의

11.2.1 테스트 크기

  • 쉽게 설명하면 이렇습니다. 작은 테스트는 프로세스 하나에서 동작하고, 중간 크기 테스트는 기기 하나에서, 큰 테스트는 자원을 원하는 만큼 사용해 동작합니다.
  • 작은 테스트: 단 하나의 프로세스에서 실행되어야 합니다. 또한, sleep, I/O연산 같은 블로킹 호출을 사용해서는 안됩니다. 이러한 제약들의 목적은 테스트를 느려지게 하거나 비결정적으로 만드는 주요 원인들로부터 작은 테스트를 떼어 놓는 것입니다.
  • 중간 크기 테스트: 여러 프로세스와 스레드를 활용할 수 있고, 로컬 호스트로의 네트워크 호출 같은 블로킹 호출도 이용할 수 있습니다. 단, 외부 시스템과의 통신은 여전히 불허합니다. 웹 UI와 서버 코드의 조합도 테스트할 수 있습니다.
    • 원격 호출은 대부분의 시스템에서 속도를 떨어뜨리고 비결정성을 높이는 가장 독보적인 원흉입니다.
  • 큰 테스트: 코드 조각이 아닌 설정을 검증하는 게 주된 목적입니다.
  • 테스트 크기와 무관한 공통 특성: 테스트 자체를 검사해주는 테스트는 따로 없으므로 정확성이라는 중요한 검사는 사람이 직접 해야 합니다. 테스트는 오직 실패했을 때만 다시 들여다본다는 사실을 기억하세요. 지금껏 한 번도 들여다본적 없는 테스트가 어느날 실패하여 바로잡아야 한다고 생각해보세요.
이런 엄밀한 구분 자체가 많은 시간과 경험이 녹아든 결과물 같다.

11.2.2 테스트 범위

  • 좁은 범위 테스트는 작은 테스트가 되고 더 넓은 범위 테스트들은 중간 크기나 큰 테스트가 되는 것이 일반적입니다. 하지만 꼭 그렇지는 않습니다.
  • 예를 들어 최신 웹 프레임워크들은 HTML과 자바스크립트를 묶어 배포되는 경우가 많습니다. 그래서 날짜 선택기 같은 UI 요소의 경우 실행 경로 하나만 테스트하려 해도 반드시 브라우저까지 실행해야 합니다.
  • 주의해야 할 안티패턴이 두 가지 있습니다. 바로 [그림 11-4]의 '아이스크림 콘'과 '모래시계'입니다.

아이스크림 콘 안티패턴

우리 회사의 경우 Manual Tests만 존재한다. 그러므로 조금씩 테스트 스위트를 만들어간다면 그것만으로도 엄청난 건실함이 생기는 것이다.

11.2.3 비욘세 규칙

  • 짧게 풀어보면 '네가 좋아했다면 (CI) 테스트를 준비해뒀어야지'라는 뜻입니다.
  • 예를들어 인프라가 수정되어 A팀의 제품이 제대로 동작하지 않는 일이 벌어졌다고 해보죠. 이 경우 A팀이 작성하여 CI에 등록해둔 테스트를 모두 통과했다면, 이 문제를 수정하고 문제를 검증하는 테스트를 추가할 책임은 전적으로 A팀에 있습니다.
이런 관점이 신기하다. 1차원적으로 생각한다면 인프라팀에 책임이 있어야할 것 같다.

11.2.4 코드 커버리지

  • 코드 커버리지는 어느 테스트가 기능 코드의 어느 라인을 실행하는지를 측정하는 수단입니다. 100라인짜리 코드가 있고 테스트가 90라인을 실행했다면 코드 커버리지는 90%입니다.
  • 테스트 스위트의 품질을 높이는 더 나은 방안은 무엇일까요? 바로 검사해야 할 행위에 집중하는 것입니다.
코드 커버리지리라는게 이런거였구나

11.3 구글 규모의 테스트

  • 모노 리포, 20억 라인이 넘는 코드가 한 곳에 담겨있다.
  • 매주 약 2천 5백만 라인이 변경된다.
  • 리포지터리 브랜치를 사용하는 팀이 거의 없다. 모든 변경이 리포지터리 헤드에 직접 커밋되어 변경 즉시 모두가 볼 수 있다. 나아가 모든 소프트웨어는 테스트 인프라가 검증한 가장 최신 커밋까지 반영해 빌드됩니다.
미쳤다..
의문: 구글 규모의 코드베이스를 구글만큼 잘 다룰 수 있는 곳이 구글밖에 없다면 구글이 소프트웨어 회사 중 가장 가치있는 회사여야할까? 위 사실들은 놀랍지만 결국 비즈니스가 성공해야하는 가정은 변하지 않는 것 같다. 맞나? 소프트웨어를 정말 잘 다루는 팀이나 개인이 있다면, 그건 성공의 지름길인가?

11.4 구글 테스트의 역사

  • 테스팅 그룹릿
    • 신규 입사자에게 마치 표준인 것처럼 테스트를 교육. 트로이목마로 이용
    • 테스트 인증과 레벨을 부여해 은근히 경쟁 분위기를 부추김
    • 화장실 벽면에 테스트 관련 포스트 부착
무언가를 옳다고 믿는 것과 그것을 밀고 나가는 것이 같은 것일까? 어떻게 무언가를 이렇게까지 확신에 차서 행동할 수 있을까?

11.5 자동 테스트의 한계

  • 사람의 판단이 개입되어야 하는 테스트. 쿼리를 날리고 결과에 관한 느낌을 기록하는 검색 품질 평가자 연구
  • 보안 취약점을 찾는 일은 자동 시스템보다 사람이 더 뛰어난 영역

11.7 핵심 정리

  • 자동 테스트는 소프트웨어를 변경할 수 있게 해주는 토대입니다.
  • 테스트를 확장하려면 반드시 자동화해야 합니다.
  • 테스트 커버리지를 건실하게 유지하려면 균형 잡힌 테스트 스위트가 필요합니다.
  • "네가 좋았다면 테스트를 준비해뒀어야지"
  • 조직의 테스트 문화를 바꾸는 데는 시간이 걸립니다.
wow 정말 그런가? 보안 취약점은 아주 복잡한 영역인가보다

느낀 점, 해소되지 않은 의문

  • 메타적으로 챕터를 정리하자면
    • 왜 필요한지를 설명하기에 앞서 테스트란 무엇인지를 간략하게 정의, 필요성 사례(GWS), 테스트 스위트 설계에서는 테스트의 크기와 범위라는 요소를 먼저 설명, 크기와 범위별 테스트 정의, 책임자 정의, 흔한 오류 방지 (커버리지가 목표가 되어버림), 이런 규칙들이 실제 어느정도 규모까지 유효한지 자랑 및 인증 신빙성 더하기, 문화를 퍼뜨리는 방법 공유, 이때까지 찾은 아주 적은 한계, 테스트는 아주 중요하다면서 마무리
  • 테스트 코드가 있어야 서비스가 더 건실해지는 것 같다. 그런 의미에서 테스트는 비즈니스에 있어서도 필수아닐까? 여러 구성원이 달려드는 QA로 마감을 지을 수 있긴 하지만, 다음번에도, 다음 릴리즈에도, 다음 QA에도 같은 작업을 반복해야한다. 그리고 자동화된 테스트가 없으면 엄밀히는 이전에 통과했던 QA도 망가졌을 수 있기 때문에 전체를 다시 테스트해야한다. 즉 점점 QA 작업은 커진다. 왜 그런데도 테스트를 안할까? 테스트가 오히려 발목을 잡는 경험을 해서?