Upgrade to Pro — share decks privately, control downloads, hide ads and more …

단위 테스트 (3) - 단위 테스트 구조

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

단위 테스트 (3) - 단위 테스트 구조

단위 테스트 3장, 단위 테스트 구조

Avatar for Seongeun Yu

Seongeun Yu

November 24, 2023

More Decks by Seongeun Yu

Other Decks in Programming

Transcript

  1. 1. 단위 테스트를 구성하는 방법 2. 테스트 프레임워크 살펴보기 (pytest)

    3. 테스트 간 테스트 픽스처 사용 4. 단위 테스트 명명법 5. 매개변수화된 테스트 리팩토링하기 6. 검증문 라이브러리를 사용한 테스트 가독성 향상 목차
  2. 들어가며 이번 절에서 다룰 내용 • 주로…. – 단위 테스트

    명명, 코드 구성 방안 – 테스트 코드 재사용 – 픽스처 사용 – 단위 테스트의 관행 타파를 위한 방안 제시 – 단위 테스트 간소화 - 매개변수화된(parameterized) 테스트 소개
  3. 3.1 단위 테스트를 구성하는 방법 • AAA 패턴 사용 –

    Arrange(준비), Act(실행) 그리고 Assert(검증) – 아래와 같은 코드가 있다고 가정합시다. 단순한 계산기예요.
  4. 3.1 단위 테스트를 구성하는 방법 (cont’d) • AAA 패턴 사용

    – Arrange(준비), Act(실행) 그리고 Assert(검증) – 해당 패턴으로 테스트를 작성합니다 – 최대한 단순하고 균일한 구조 유지 → 테스트 운영에 유지보수 비용 감소 – 준비구절 작성부터… – …감이 안 오면 검증 구절부터 → 기대 동작으로 윤곽부터 잡기
  5. 3.1 단위 테스트를 구성하는 방법 (cont’d) • AAA 패턴 사용

    – Arrange(준비) • SUT와 해당 의존성을 원하는 상태로 만든다 – Act(실행) • SUT에서 메소드를 호출하고, 준비된 의존성을 전달한다. – Assert(검증) • 결과검증 – E.g., SUT와 협력자의 최종 상태 – SUT가 협력자에 호출한 메소드 – 등등….
  6. 3.1 단위 테스트를 구성하는 방법 (cont’d) • AAA 패턴에서 실수하기

    좋은 부분 (1) – 여러 개의 AAA가 겹치는 테스트 → 여러 동작을 검증하고 있다는 신호 → 테스트를 나누기 – 통합 테스트는? • 여러 동작단위를 검증 • 그런 테스트는 여러 실행-검증을 모아둔 단일 테스트로 빼기
  7. 3.1 단위 테스트를 구성하는 방법 (cont’d) • AAA 패턴에서 실수하기

    좋은 부분 (2) – if 문을 가급적 빼기 – if문? → 너무 많은 것을 검증한다는 뜻. 여러 테스트로 나누기 – 분기 없이 간단한 단계로 나눌 것
  8. 3.1 단위 테스트를 구성하는 방법 (cont’d) • AAA 패턴에서 실수하기

    좋은 부분 (3) – Arrange – 가장 큰 구절. 실행, 검증보다도 더 길 수 있다 – 하지만 코드 재사용이 필요할 수도 있음 → 아래 패턴 활용 • Object mother • Test data builder
  9. 3.1 단위 테스트를 구성하는 방법 (cont’d) • Object mother –

    테스트용 인스턴스를 만들어주는 클래스
  10. 3.1 단위 테스트를 구성하는 방법 (cont’d) • Test data builder

    – 테스트 데이터를 보다 세밀하게 컨트롤해서 만드는 패턴
  11. 3.1 단위 테스트를 구성하는 방법 (cont’d) • AAA 패턴에서 실수하기

    좋은 부분 (3) – Act – Act 가 한 줄 이상인 경우를 경계할 것 → 캡슐화가 깨지는 것을 경계하기 – 동작단위를 검증해야 유지보수가 쉬움 – 세부 구현을 검증하지 않도록 해야 – 캡슐화가 깨져서 모순이 생기는 경우 → 불변 위반(invariant violation)
  12. 3.1 단위 테스트를 구성하는 방법 (cont’d) • AAA 패턴에서 실수하기

    좋은 부분 (3) – Assert – 검증 구절은 동작의 결과를 평가할 정도로만 있으면 됨 – 너무 많으면 추상화가 깨지지 않았는지 검토하기 – 가장 좋은 경우: 동등 멤버(equality member)를 정의 → (🐍) 객체의 동일성 검증을 위해 __eq__() 매직 메소드를 정의하는 것을 의미 • 종료(teardown) 구문? – 단위 테스트는 프로세스 외부에 종속적이지 않기 때문에 사이드 이펙트가 적음 – 이는 통합 테스트의 영역. (3부에서 봅시다)
  13. 3.2 테스트 프레임워크 살펴보기 • 책에서는? – .NET 계열에서 쓰이는

    xUnit을 소개 – setup(), teardown() 메소드로 테스트 전/후의 상황을 설정하고 정리 – SUT에 대해 단독 케이스를 개별 명세처럼 남길 수 있음을 좋아함 • 파이썬 에서는? – unittest, pytest 모두 xUnit 스타일에 가까움 – unittest는 xUnit 스타일의 코드를 선보임 – pytest는 파이썬 스러운 스타일의 코드를 선보임
  14. 3.3 테스트 간 테스트 픽스처 사용 • 코드 재사용! –

    귀찮음을 줄임 • 테스트 픽스처 – 테스트 실행 대상 객체 – SUT로 전달되는 인수 – DB 데이터, 파일 → 고정상태가 유지된 객체
  15. 3.4 단위 테스트 명명법 • 단위 테스트 이름을 짓는 방법

    중 아래 관습이 있다고 합니다 – [테스트대상메소드]_[시나리오]_[예상결과] – 테스트 중인 메소드 이름 + 메소드 테스트 조건 + 시나리오 예상결과 – 이걸 따르면? • test_isdeliveryvalid_invaliddate_returnsfalse ???????????????
  16. 3.4 단위 테스트 명명법 • 단위 테스트 명명 지침 –

    엄격한 명명 정책을 없앱시다 – 다른 팀의 사람에게 시나리오를 설명하는 것 처럼 테스트 이름을 쉽게 가져갑시다 – 단어는 밑줄로 구분합시다
  17. 3.4 단위 테스트 명명법 • 이름 고치기 – 잘못된 날짜의

    배송을 올바르게 식별하는 코드니까 – Delivery_with_invalid_date_should_be_considered_invalid 이정도면? → invalid_date를 보다 정확하게 명시하자 – Delivery_with_past_date_should_be_invalid 이정도면? → should be 대신 is 를 쓰는 편이 나음 – Delivery_with_past_date_is_invalid 이정도면? → 영문법을 아는 만큼 맞춥시다 – Delivery_with_a_past_date_is_invalid 이정도면?
  18. 3.5 매개변수화된 테스트 리팩토링하기 • 하나의 동작이 여러 “사실”을 포함하는

    케이스? – Delivery_with_a_past_date_is_invalid에 대해… – 가장 빠른 배송일이 오늘로부터 이틀 후가 되도록 작동하는 기능이 명세라고 하면? – 오늘, 내일은 invalid, 이틀 후는 valid인 경우… – 테스트 케이스가 3개나 나오지만 – 사실 한 테스트에 대해 매개변수만 바꿔주면 됩니다
  19. 3.5 매개변수화된 테스트 리팩토링하기 • 하나의 동작이 여러 “사실”을 포함하는

    케이스? – 매개변수화(parameterized) 하여 처리 – pytest에서는 아래와 같이 제공합니다
  20. Q&A