2023. 5. 2. 22:18ㆍ책/이펙티브 소프트웨어 테스팅
어떤 시스템은 테스트 하기 너무 힘들다!
테스트 가능성에 대한 설계 원칙에 대해 다루어 보자.
테스트가능성을 고려해야 할때는 언제일까? 답은 '항상' 고려 해야한다.
스파게티 코드를 작성하는일은 상호 협력적이고 응집력이 있고 테스트하기 쉬운 코드를 작성하는것보다 훨씬 쉽다.
테스트하기 쉽고 좋은코드는 비용은 많이들지만 품질을 보장하기 위한 유일한 방법이다.
1. 도메인코드에서 인프라 코드를 분리하기
간단하게, 도메인 코드에 데이터 베이스를 다루는 코드가 섞이면 어떻게 될까? 기본적으로 해당 클래스는 책임이 더 커질것이고 이는 버그가 발생할 가능성이 증가한다는뜻이다. 덜 응집된 클래스는 코드량이 많다.
인프라요소 외에도 사용자 인터페이스역시 마찬가지다, 비지니스 로직과 섞일때 이는 대부분 테스트 가능성을 해친다.
경험적으로, 응집력이 낮은 클래스를 테스트하는것보다, 단일책임을 지고 인프라코드가 전혀 없는 클래스를 테스트하는것이 훨씬 쉽다.
소프트웨어 시스템의 아키텍처는 명확한 책임분리가 필요하다. 이를 간단하게 설명하면 포트와 어댑터(혹은 헥사고날 아키텍처) 패턴으로 설명할수 있다.
도메인은 인프라에 직접 의존하기보다는 포트를 사용한다.
포트 - 인프라가 할수 있는 일을 정의한 인터페이스이다. 인프라의 구현과 분리되어 애플리케이션은 포트를 통해 정보를 주고받는다.
어댑터- 포트와 달리 인프라에 매우 가까이에 있고, 포트의 구현체로서 데이터베이스나 웹서비스등과 통신하는 일을 한다. 인프라에 대해서 알고 있다.
이러한 구조는 테스트가 용이해지는데 그 이유는
1. 클래스가 생성자를 통해 의존성을 받는다 => 모의객체와 스텁을 클래스에 전달할수 있게 해줌
2. 비지니스 규칙만 다루고 인프라코드는 전혀 가지고 있지 않다.
다시말하면 포트(인터페이스)를 스텁이나 모의객체로 만들어서 비지니스로직의 주요 동작을 테스트하는데 집중하고
구현체인 어댑터가 제대로 동작하는지에 대해서는 신경쓰지 않는다.
물론 어댑터의 코드역시 테스트해야한다. 즉 DAO같은 요소들도 마찬가지이다.
이런 개념은 도메인주도 설계, 클린아키텍처 와 같은책에서도 소개되며 널리 퍼져있다.
보통 이런 개념을 접하면 '모든 포트에 대해 인터페이스를 만들어야하나요?' 라는 질문을 할수있는데
이에 대해서는 결국 실용적으로 케이스 바이 케이스이다. 구현체가 두개이상이 되는 포트에 대해서는 인터페이스를 만들거나 문맥에 따라 실용적으로 만들거나 만들지 말자
2. 의존성 주입과 제어 가능성
도메인 코드를 인프라로부터 분리하려면, 클래스를 쉽게 제어하고, 관찰할수 있어야한다. 이게 무슨소리일까?
클래스의 인스턴스를 직접 생성하는 대신, 생성자나 세터에서 의존성을 주입할수 있도록하면 여러면에서 코드를 개선할수 있다.
1. 확장성
2. 의존성을 명확하게 해줌
3. 관심사를 분리하기 좋다.
4. 테스트단계에서 생산성이 증대된다.
추가로 의존성 역전 원칙도 생각해보자
고수준 모듈은 저수준 모듈에 의존해서는 안되고, 모두 추상화에 의존해야한다.
추상화는 세부사항에 의존하면 안되고, 세부사항은 추상화에 의존해야한다.
만약 이 원칙을 지키지 않으면 저수준 모듈의 세부사항을 변경할때마다 코드를 변경해야 할것이다. 적절한 캡슐화를 해야한다.
3. 클래스, 메서드를 관찰 가능하게 하기
테스트 코드는 클래스의 행동을 쉽게 조사할수 있어야한다. 프로그램이 기대한대로 동작하는지를 관찰하기 어렵다면, 게터같은 것을 추가하는것을 두려워 하지 말자.
정확히는 단순히 관찰가능성 이슈를 해결하기 위해서 만들지말고, 테스트를 더 쉽게 만들어주는지에 집중하자.
테스트가능성을 개선해주는 작은 설계변경은 괜찮다는점만 기억하고, 실용주의적으로 판단하는것이 중요하다.
'책 > 이펙티브 소프트웨어 테스팅' 카테고리의 다른 글
이펙티브 소프트웨어 테스팅 - 테스트 주도 개발 (1) (0) | 2023.05.11 |
---|---|
이펙티브 소프트웨어 테스팅 - 테스트 가능성을 위한 설계(2) (0) | 2023.05.10 |
이펙티브 소프트웨어 테스팅 - 테스트더블과 모의객체(2) (0) | 2023.04.30 |
이펙티브 소프트웨어 테스팅 - 테스트더블과 모의객체(1) (0) | 2023.04.30 |
이펙티브 소프트웨어 테스팅 - 속성기반 테스트 (2) (0) | 2023.04.25 |