programming4 MIN READ

[소프트웨어 테스트] 01. 효율적이고 체계적인 테스트

[소프트웨어 테스트] 01. 효율적이고 체계적인 테스트

소프트웨어 테스트 시리즈의 글입니다.

개발자는 시스템 품질에도 책임이 있음. 버그를 잘 찾아야함. 테스트는 버그를 찾는데 도움이 된다.
효율적이고 체계적인 테스트에 대해 알아보자

1.1 테스트를 하는 개발자와 하지 않는 개발자

  • 테스트시에는 체계적인 접근법을 사용하여 corner case 생길 확률을 줄이고, 테스트 자동화를 적용해 수동테스트에 너무 많은 시간을 쓰지 않도록 해야함
  • 속성기반 테스트 프레임워크를 통해 매번 임의의 조합의 속성을 테스트 할 수 있음.

1.2 개발자를 위한 효율적인 소프트웨어 테스트

  • 도메인테스트 : 요구사항을 작은 부분으로 나누어 테스트 케이스를 도출해내는 기법
  • 구조적 테스트 : code coverage (테스트케이스가 충분한지 평가)
  • 예시 기반 테스트 : 테스트를 위해 한가지 data point 사용
  • 속성 기반 테스트 : 특이한 data point 사용
  • 계약 + 사전조건 + 사후조건 검사

1.2.1 개발 과정에서의 효율적인 테스트

  1. 요구사항 분석
  2. TDD 반복
  3. 단위 (클래스, 메서드) 개발 (테스트 고려)
  4. 각 단위 테스트 (도메인, 경계, 구조적 테스트 기법 적용)
  5. 대규모 테스트
  6. 지능형 테스트 (테스트케이스생성, 돌연변이 테스트, 정적분석)
  7. 배포 ㄱ

1.2.2 반복 프로세스로서의 효율적 테스트

테스트 도중 버그발견 → 구현으로 다시돌아감 → 다시 테스트.. 자유롭게 앞뒤로 왔다갔다하면서 기법 순서를 바꿔서 적용. 자신에게 가장 적합하고 생산적인 방법을 스스로 찾아야함

1.2.3 개발에 먼저 집중하고 나서 테스트하기

개발과 테스트를 분리해서 집중

1.2.4 제대로된 설계에 관한 미신

단순하다고 결함이 없다? ⇒ X 잘 설계했다고 버그가 없다? ⇒ X

1.2.5 테스트 비용

상용 버전에서 발생하느 ㄴ버그의 비용은 예방에 드는 비용보다 더 크다 연습이 관건. 익숙해지면 빨리 작성하게됨.

1.2.6 효율적이면서 체계적이라는것의 의미

  • 효율적 : 올바른 테스트를 작성하는데 집중하는것. 목적은 버그를 찾는것.
  • 체계적 : 어떤 코드 조각에 대해 어느 개발자라도 같은 테스트 스위트를 만들어낸다는것.

1.2.7 테스트 자동화의 역할

자동화 = 효율적인 테스트 프로세스의 핵심. 작성만 하면 실행은 프레임웍이 알아서 해줌. 어려운건 테스트가 버그를 잘 드러내도록 설계하는것.

1.3 소프트웨어 테스트 원칙

테스트는 왜 어려운가.

1.3.1 완벽한 테스트는 불가능

프로그램을 완벽히 테스트하기는 불가능 ex. 플래그 300개 리눅스: 2\^300개 조합 테스트 해야함.. 개발자는 무엇을 테스트할지 선택해야함. ⇒ 효율적 테스트가 필요한 이유

1.3.2 테스트를 그만둘 때를 파악하기

비용을 최소화하면서 최대한 많이 버그를 찾아야함.

1.3.3 가변성이 중요하다

  • 다른 종류의 버그를 차즌ㄴ데는 다른 테스트 기법이 도움이 됨
  • 살충제 역설 : 벌레를 예방하고 잡으려고 사용하는 모든 방법은 그 효과가 닿지 않는 더 미묘한 벌레를 남김

1.3.4 버그는 다른곳에 비해 많이 발생하는 지점이 있다

몇 구성요소에는 다른 구성요소보다 더 많은 버그가 발생가능. ex. 결제 > 마케팅 ⇒ 결함 클러스터링 우리의 소프트웨어를 관찰하고 공부해야만.. → 어디가 결함클러스터링인지 알고 효율적인 테스트 가능

1.3.5 어떤 테스트를 하든지 결코 완벽하거나 충분하지 않다

프로그램 테스트하는 일은 버그가 존재하는지를 보여주는것이지 결코 존재하지 않는다는 걸 보여주려는게 아니다 by 다익스트라

  • 버그는 항상 발생함
  • 모든것을 테스트할수없다는것을 받아들여야함

1.3.6 맥락이 핵심

context 에 따라 항상 어떤 기법이 효율적일지 달라질수있음.

1.3.7 검증 ≠ 유효성검사

  • 검증(verification) : 시스템이 제대로 되어있는가 (기능이 요구사항에 부합하는가?)
  • 유효성검사(validation) : 올바른 시스템을 가지는 방법 (기능이 사용자에게 유용한가?) 둘은 함께 진행되어야함.

1.4 테스트 피라미드와 집중해야 할 부분

1.4.1 단위 테스트

단위를 격리해서 테스트하는것.

  • 장점
    • 빠름
    • 다루기 쉬움
    • 작성하기 쉬움
  • 단점
    • 현실성이 떨어짐
    • 잡을수없는 버그가 존재함
      • 멀티스레드
      • 외부시스템 호출

1.4.2 통합 테스트

우리 코드가 외부 요소간의 통합을 테스트할때 사용하는 테스트 수준. (ex. DB 의존)

  • 작성하기 더 어려움
  • 초기 환경구성에 노력이 필요함
  • 테스트목적만으로 격리된 인프라 필요함

1.4.3 시스템 테스트

시스템이 가진 모든 db, FE, 기타 구송요소를 포함한 전체 소프트웨어 시스템을 실행해 하는 테스트. 내부 동작은 관심없고 특정 입력을 하면 특정 출력이 나오는것에만 관심이 있음.

  • 장점
    • 테스트가 현실적
  • 단점
    • 느림
    • 작성하기 힘듬
    • 불안정한 경향
      • 외부시스템의 불확실성

1.4.4 각 테스트 수준을 언제 사용?

상황에 따라 다르다.

1.4.5 단위테스트 선호 이유

작은단위에 대해 효율, 엄격하게 테스트하는 일은 큰기능을 테스트하는것보다 쉬움 계약을 명확히하고 체계적으로 테스트하면 여러 단위를 합쳐도 잘 동작하겠다는 확신이 섬 정말 중요한부분에는 통합, 시스템 테스트 하면됨

1.4.6 각 수준에서 무엇을 테스트?

시스템 알고리즘, 단일비즈니스 로직 → 단위테스트 외부구성요소와 상호작용할때 → 통합테스트 소프트웨어에서 절대적으로 중요한부분 → 시스템 테스트

1.4.7 테스트 피라미드에 동의하지않는다면

테스트 피라미드 vs 테스트 트로피 맥락이 핵심이다. 각자의 개발팀에 적합한 방법을 스스로 찾아라.

1.4.8 이 책의 내용으로 버그 모두 찾기 가능?

불가능. 하지만 다양한 버그를 많이 발견하는 방법을 알려줄것임.