[ python ] 08. 단위 테스트와 리팩토링_(1)

박찬영·2024년 5월 15일

파이썬 클린 코드

목록 보기
18/19
post-thumbnail

08. 단위 테스트와 리팩토링

디자인 원칙과 단위 테스트

단위 테스트는 다른 코드의 일부분이 유효한지를 검사하는 코드이다. 일반적으로 단위 테스트를 애플리케이션의 핵심 기능을 검증하는 것이라고 생각하지만 그것은 이 책에서 정의하는 방식과 달리 단위 테스트를 보조 수단으로만 생각하는 것이다. 단위 테스트는 소프트웨어의 핵심이 되는 필수적인 기능으로서 일반 비즈니스 로직과 동일한 수준으로 다루어져야 한다.

단위 테스트는 비즈니스 로직이 특정 조건을 보장하는지를 확인하기 위해 여러 시나리오를 검증하는 코드이다. 단위 테스트는 다음과 같은 특징을 가져야만 한다.

  • 격리(Isolation)
    단위 테스트는 다른 외부 에이전트와 완전히 독립적이어야 하며 비즈니스 로직에만 집중해야 한다. 때문에 데이터베이스에 연결하지 않아야 하고 HTTP 요청도 하지 않아야 한다. 격리는 또한 테스트 자체가 독립적이라는 것을 의미하고 테스트는 이전 상태에 관계없이 임의의 순서로 실행될 수 있어야 한다.
  • 성능(Performance)
    단위 테스트는 신속하게 실행되어야 한다. 반복적으로 여러 번 실행될 수 있도록 설계해야 한다.
  • 반복 가능성(Repeatability)
    단위 테스트는 객관적이고 결정적인 방식으로 소프트웨어의 상태를 평가할 수 있어야 한다. 이는 테스트에서 얻은 결과가 반복 가능해야 함을 의미한다. 단위 테스트는 코드의 상태를 평가한다. 테스트가 실패하면 코드가 수정될 때까지 계속 실패해야 한다.
  • 자체 검증(Self-validating)
    단위 테스트의 실행만으로 결과를 결정할 수 있어야 한다. 단위 테스트를 처리하기 위한 추가 단계가 없어야 한다.

단위 테스트를 작성한 .py 파일을 만들고 이 파일을 도구에서 호출하는 것이다. 이 파일에는 비즈니스 로직에서 필요한 것을 가져오기 위한 import 구문과 비즈니스 로직을 테스트하기 위한 프로그램이 있다. 그러면 도구에서 단위 테스트를 수집하여 실행한 다음 결과를 보여준다.

자동화된 테스트의 다른 형태

단위 테스트는 함수 또는 메서드와 같은 매우 작은 단위를 확인하기 위한 것이다. 단위 테스트 는 최대한 자세하게 코드를 검사하는 것이 목적이다. 클래스를 테스트하려면 단위 테스트가 아 니라 단위 테스트의 집합인 테스트 스위트(test suite)를 사용한다. 테스트 스위트를 구성하는 테 스트들은 메서드처럼 보다 작은 것을 테스트한다.

단위 테스트는 여러 방법으로 할 수 있으며, acceptance test, intergration test같은 것도 있다.
좋은 개발 환경을 구축했다면 개발자는 전체 테스트 스위트를 만들고 코드에 수정이 생길 때마다 반복적으로 단위 테스트와 리팩토링을 할 수 있어야 한다.

단위 테스트와 애자일 소프트웨어 개발

최근의 소프트웨어 개발은 가능한 한 신속하고도 지속적으로 가치를 제공하려고 한다. 이렇게 하는 이유는 더 빠르게 피드백을 받을수록 더 쉽게 코드를 수정할 수 있다는 생각이 있기 때문이다.

단위 테스트(혹은 자동화된 테스트)는 우리의 코드가 기대한 것처럼 동작한다는 확신을 줄 수 있는 안정망이 될 수 있다. 이 러한 도구로 무장한 코드가 있으면 보다 효율적으로 개발이 진행될 것이므로 궁극적으로 팀의 개발 속도(또는 범위)를 향상시킬 수 있다. 좋은 테스트를 가 질수록 버그에 의해 프로젝트를 중단하지 않고 신속하게 가치를 제공할 가능성이 높아진다.

단위 테스트와 소프트웨어 디자인

단위 테스트와 메인 코드는 동전의 양면과 같은 것이다. 이전 섹션에서 살펴본 실용적인 이유 외에도 좋은 소프트웨어는 테스트 가능한 소프트웨어라는 사실을 기억할 필요가 있다. 테스트의 용이성(소프트웨어를 얼마나 쉽게 테스트 할 수 있는지를 결정하는 품질 속성)은 단순히 있으면 좋은 것이 아니라 클린 코드의 핵심 가치이다.

단위 테스트는 기본 코드를 보완하기 위한 것이 아니라 실제 코드의 작성 방식에 직접적인 영 향을 미치는 것이다. 단위 테스트는 특정 코드에 단위 테스트를 해야겠다고 발견하는 단계에 서부터 더 나은 코드를 작성하는 단계 그리고 궁극적으로 모든 코드가 테스트에 의해 작성되는 TDD(test-driven design) 단계까지 여러 단계가 있다.

테스트를 위한 도구

단위 테스트 프레임워크와 라이브러리

  • unittest : 파이썬 표준 라이브러리
  • pytest : 외부 라이브러리

테스트 시나리오를 다루는 것은 unittest만으로도 충분하지만 더 복잡한 옵션이 필요한 경우는 Pytest가 적합하다.

unittest 모듈은 모든 종류의 테스트를 작성할 수 있는 풍부한 API를 제공하므로 단위 테스트를 시작하기에 훌륭한 선택이다. 그리고 표준 라이브러리에 포함되어 있으므로 다방면에 편리하게 사용할 수 있다.

unittest 모듈은 자바의 JUnit을 기반으로 한다, JUnit은 Smalltalk의 아이 디어를 기반으로 만들 어졌으므로 객체 지향적이다. 이러한 이유로 테스트는 객체를 사용해 작성되며 클래스의 시나 리오별로 테스트를 그룹화하는 것이 일반적이다.

단위 테스트를 만들려면 unittest.TestCase를 상속하여 테스트 클래스를 만들고 메서드에 테 스트할 조건을 정의하면 된다. 이러한 메서드는 test一로 시작해야 하며 본문에서는 unittest. TestCase에서 상속받은 메서드를 사용하여 체크하려는 조건이 참인지 확인하면 된다.

pytest는 훌륭한 테스트 프레임워크로 pip install pytest 명령어를 통해 설치할 수 있다. 차이점 은 unittest처럼 테스트 시나리오를 클래스로 만들고 객체 지향 모델을 생성하는 것이 가능하지 만 필수 사항이 아니 며, 단순히 assert 구문을 사용해 조건을 검人卜하는 것이 가능하기 때문에 보 다 자유롭게 코드를 작성할 수 있다는 점이다.

기본적으로 pytest에서는 assert 비교만으로 단위 테스트를 식별하고 결과를 보고하는 것이 가 능하다. 앞의 섹션에서 보았던 고급 기능도 사용할 수 있지만 패키 지에서 제공하는 특정 기능을 사용해야 한다.

멋진 기능 중의 하나는 pytest 명령어를 통해 탐색 가능한 모든 테스트를 한번에 실행한다는 점 이다. 심지어 unittest로 작성한 테스트도 실행한다. 이러한 호환성 때문에 unittest에서 pytest 로 점진적으로 전환하는 것도 가능하다.

profile
안녕하세요 박찬영입니다.

0개의 댓글