본문 바로가기

독서찰기(讀書札記)/단위 테스트

(7)
리팩터링할 코드 식별하기 모든 코드는 2차원으로 분류할 수 있다. 도메인 유의성(or 복잡도) 협력자 수 왼쪽 상단 사분면이 단위 테스트의 가성비가 가장 좋다. 왼쪽 하단 사분면은 테스트할 필요가 없다. 오른쪽 하단 사분면은 통합 테스트로 간단히 테스트해야 한다. 오른쪽 상단 사분면이 제일 문제다. 험블 객체 패턴을 사용해 지나치게 복잡한 코드 분할하기 우리가 테스트하려는 로직이 테스트하기 어려운 의존성과 결합되어 있을 때, 로직을 분리하여 의존성과 결합시켜주는 패턴이다. 험블 객체 패턴은 오케스트레이션을 수행하는 코드에서 복잡한 코드를 분리하도록 설계됐다. (함수형 아키텍처, 육각형 아키텍처에서도 이러한 분리가 이루어진다) e.g.1) MVC(Model-View-Controller) 패턴에서 Controller는 험블 객체로 ..
함수형 아키텍처 함수형 프로그래밍? 수학적 함수(mathematical function)를 사용한 프로그래밍이다. 수학적 함수는 숨은 입출력이 없는 함수(또는 메서드)다. 수학적 함수의 모든 입출력은 메서드 이름, 인수, 반환 타입으로 구성된 메서드 시그니처(method signature)에 명시해야 한다. 수학적 함수는 호출 횟수에 상관없이 주어진 입력에 대해 동일한 출력을 생성한다. ※ 사이드 이펙트: 메서드 시그니처에 표시되지 않은 출력(DB 저장, 예외 발생 등) 함수형 아키텍처? 어떤 사이드 이펙트도 일으키지 않는 애플리케이션을 만들 수는 없다. 함수형 프로그래밍의 목표는 사이드 이펙트를 완전히 제거하는 것이 아니라 비즈니스 로직을 처리하는 코드와 사이드 이펙트를 일으키는 코드를 분리하는 것이다. (결정을 내리..
단위 테스트 스타일 출력 기반 테스트(output-based testing) 상태 기반 테스트(state-based testing) 통신 기반 테스트(communication-based testing) 출력 기반 테스트 테스트 대상 시스템(SUT)에 입력을 넣고 생성되는 출력을 점검하는 방식이다. 사이드 이펙트 없는 코드 선호를 강조하는 프로그래밍 방식인 함수형 프로그래밍(functional programming)에 뿌리를 두고 있다. ※ 사이드 이펙트: 메서드 시그니처에 표시되지 않은 출력 상태 기반 테스트 작업이 완료된 후 시스템 상태를 확인하는 것이다. '상태'란 SUT, 협력자, DB, 파일 시스템 등 외부 의존성의 상태를 말한다. 통신 기반 테스트 목을 사용해 SUT와 협력자 간의 통신을 검증하는 것이다. 단위 테..
테스트 피라미드, 화이트박스 테스트 vs 블랙박스 테스트 테스트 피라미드 층의 너비: 테스트 스위트에서 해당 테스트가 얼마나 보편적인지를 나타낸다. 층의 높이: 최종 사용자의 동작을 얼마나 유사하게 흉내내는지 나타낸다. 상단은 회귀 방지에 유리한 반면, 하단은 실행 속도를 강조한다. 테스트 유형 간의 정확한 비율은 각 팀과 프로젝트마다 다를 것이다. 그러나 일반적으로 피라미드 형태를 유지해야 한다. 엔드 투 엔드 테스트가 적어야하는 이유는 회귀 방지, 리팩터링 내성, 빠른 피드백의 곱셈 규칙에 있다. 엔드 투 엔드 테스트는 빠른 피드백 지표에서 매우 낮은 점수를 받기 때문이다. 또한 유지 보수성이 결여되어 있다. 블랙박스 테스트 vs 화이트박스 테스트 블랙박스 테스트: 시스템의 내부 구조를 몰라도 시스템의 기능을 검사할 수 있는 소프트웨어 테스트 방법이다. 일..
이상적인 테스트를 찾아서 회귀 방지, 리팩터링 내성, 빠른 피드백, 유지 보수성 위 네 가지 특성의 수학적 곱이 클수록 이상적인 테스트이다. (하나라도 0이 되면 전체가 0이 된다) 각각의 특성에 상당히 높은 임계치를 설정하고 이 임계치를 충족하는 테스트만 테스트 스위트에 남겨라. 이상적인 테스트를 만들 수 있는가? 회귀 방지, 리팩터링 내성, 빠른 피드백. 이 세 가지 특성은 상호 배타적이다. 따라서 특성 중 어느 것도 크게 줄지 않는 방식으로 최대한 크게 해야한다. 한 가지를 아예 희생시켜, 결국 가치가 0에 가까워진 테스트 사례를 살펴보자. 극단적인 사례 1: 엔드 투 엔드 테스트 엔드 투 엔드 테스트는 많은 코드를 테스트하므로 회귀 방지를 훌륭히 해낸다. 또한 엔드 투 엔드 테스트는 거짓 양성에 면역이 돼 리팩터링 내성도..
회귀 방지와 리팩터링 내성의 관계 둘 다 정반대의 관점에서 테스트 스위트의 정확도에 기여한다. 두 가지 특성은 시간이 흐르면서 프로젝트에 영향을 다르게 미치는 경향이 있다. 테스트 정확도 극대화 테스트가 버그 있음을 얼마나 잘 나타내는가 = 거짓 음성이 잘 제외되는가 = 회귀 방지가 잘 되는가 테스트가 버그 없음을 얼마나 잘 나타내는가 = 거짓 양성이 잘 제외되는가 = 리팩터링 내성이 잘 지켜지는가 테스트 정확도 = 발견된 버그 수 / 허위 경보 발생 수 버그 못 찾음 & 허위 경보 안 울림 → 정확도 0에 수렴 (거짓 음성은 프로젝트 초반에 위험) 버그 다 찾음 & 허위 경보 다 울림 → 정확도 0에 수렴 (거짓 양성은 프로젝트 시간이 흐를수록 위험) 개발자 대부분은 회귀 방지에만 신경을 쓰는데, 프로젝트가 크고 오래 걸릴수록 리팩터링..
좋은 단위 테스트의 4대 요소 회귀 방지 리팩터링 내성 빠른 피드백 유지 보수성 1. 회귀 방지 회귀 = 소프트웨어 버그 : 코드를 수정한 후 기능이 의도한 대로 작동하지 않는 것 코드베이스가 커질수록 잠재적인 버그에 더 많이 노출되기 때문에 회귀에 대해 효과적인 보호를 개발하는 것이 중요하다. 회귀 방지를 위한 고려사항 테스트 중에 실행되는 코드의 양 코드 복잡도 코드의 도메인 유사성 실행되는 코드가 적을수록 회귀가 나타날 가능성이 낮다. 복잡한 비즈니스 로직을 나타내는 코드가 boilerplate code보다 훨씬 더 중요하다. 비즈니스에서 중요한 기능에서 발생한 버그가 가장 큰 피해를 입히기 때문이다. 우리가 작성하지 않은 코드(라이브러리, 프레임워크, 외부 시스템 등등)도 중요하다. 2. 리팩터링 내성 거짓 양성(false p..