25
테테테 테테테테 테테 김김김 [email protected] 김김김 http://café.naver.com/architect1

테스트 자동화의 원칙

Embed Size (px)

Citation preview

Page 1: 테스트 자동화의 원칙

테스트 자동화의 원칙

김태우 [email protected]아꿈사 http://café.naver.com/architect1

Page 2: 테스트 자동화의 원칙

개요• 원칙은 패턴이라고 하기엔 고차원적

– 모두가 공감할 수 있는 가치 체계가 아니기 때문• 가치 체계가 다른 사람은

다른 패턴을 선택할 수 있다 .• 이런 가치 체계를 분명하게 하면

어디에서 의견이 다른지 , 그 이유는 무엇인지를 더 빨리 이해할 수 있을 것이다 .

Page 3: 테스트 자동화의 원칙

Test Automation Manifesto • Concise• Self Checking• Repeatable• Robust• Sufficient• Necessary• Clear• Efficient• Specific• Independent• Maintainable• Traceable

Page 4: 테스트 자동화의 원칙

원칙• 패턴보다 훨씬 ' 지시적 prescriptive‘• 원래부터 고차원적이다 .• 패턴과 달리 대안이 없다 .

– 대신 이런 식 ' 이렇게 하라 . 그 이유는 '

Page 5: 테스트 자동화의 원칙

테스트를 먼저 작성하라 • 단위 테스트는 디버깅에 드는 노력을

충분히 보상한다 .– 이런 노력은 테스트를 자동화하는 데 드는 노력을 충분히

벌충해준다 .

• 코드를 작성하기 전에 테스트를 작성하다 보면 저절로 코드를 테스트하기 쉽게 설계하게 된다 .– 이미 작성한 테스트 덕분에 ~

테스트를 쉽게 하기 위해 뭔가 따로 설계할 필요가 없다 .

Page 6: 테스트 자동화의 원칙

테스트하기 쉽게 설계하라 • 테스트를 먼저 작성하라는 원칙을

무시한 개발자에게는– 테스트 용이성을 고려하지 않고 작업한 후에

자동 테스트를 작성하기란 불가능할 수 있다 . – 그러므로 테스트하기 쉽게 설계하라는 원칙이

테스트를 먼저 작성하라는 것 보다 훨씬 중요하다 .

Page 7: 테스트 자동화의 원칙

정문을 먼저 사용하라 (1/2)• 픽스처를 설치하기 위해서나

기대 출력 값이나 테스트를 검증하기 위해 뒷문 조작을 하면 너무 결합된 소프트웨어가 돼 자주 테스트를 유지 보수 해줘야 한다 .

• 동작 검증의 잦은 사용과 모의 객체는 심하게 명세된 소프트웨어를 만들고 ,테스트를 깨지기 쉽게 해 개발자가 편하게 리팩토링을 할 수 없게 만든다 .

Page 8: 테스트 자동화의 원칙

정문을 먼저 사용하라 (2/2) • 왕복 테스트로 테스트

대상 시스템을 테스트해야 한다 .– public 인터페이스로 객체를 테스트하고 ,

상태 검증으로 제대로 동작했는지 확인 해야함• 더 견고히 확인하기 위해서는 ,

레이어 횡단 테스트를 만들고– 동작 검증으로 SUT 가 의존 컴포넌트에

호출한 결과를 검증할 수 있다 .

Page 9: 테스트 자동화의 원칙

의도를 드러내라 (1/2) ( 한 눈에 읽을 수 있는 고급 언어 )

• 완전 자동 테스트 , 스크립트 기반 테스트는 프로그램이다 .– 컴파일하려면 코드가 문법적으로 정확해야 함 – 제대로 실행하려면 코드가 의미상 정확해야 함

• SUT 로부터의 기대 결과 값을 검증하기 위해 그에 맞는 상세한 코드를 구현해야 한다 .테스트 유지 보수 팀을 신경썼는가 ?– 테스트에 코드가 너무 많은가 ? (10 줄 이상 ?) – 테스트 내 조건문 로직이 들어간

애매한 테스트인가 ? ( 이해하기 힘들다 )

Page 10: 테스트 자동화의 원칙

의도를 드러내라 (2/2) ( 한 눈에 읽을 수 있는 고급 언어 )

• 의도를 드러내면 테스트를 읽고 유지 보수하기 쉬워진다 .– 의도가 드러나는 이름의 테스트 유틸리티 메소드로

테스트 픽스처를 설치 또는 기대 결과 값을 검증 – 풍부한 테스트 유틸리티 메소드 라이브러리를

이용하여 중복작업을 줄이고 , 테스트 작성을 쉽게 하자

Page 11: 테스트 자동화의 원칙

SUT 를 고치지 마라• SUT 를 변경하는 것은 위험하다

– 테스트 훅을 넣는다던가 , – 테스트용 하위 클래스에서 동작을 오버라이딩 한다던가 , – DOC 를 테스트 대역으로 바꾼다던가 ,,, 하는 변경

• 테스트 코드가 더 이상 제품에 들어가는 코드가 아니게 될 수가 있다 .– 제품 코드에서 사용되는 것과

똑같은 방식으로 돌아가는 상태임을 보장해야 함 . – X,Y,Z 테스트 한다면… .

• X -> Y -> Z 의존 • X 수정시 Y 와 Z 를 테스트 대역으로 바꾸는 건 문제 없다 . • Y 수정시 Z 를 Z 를 테스트 대역으로 바꾸는 건 문제 없다 . • 하지만 , Z 수정시 Z 를 테스트 대역으로 교체할 수 없다 .

Z 는 테스트 하려는 대상 그 자체이기 때문 .

Page 12: 테스트 자동화의 원칙

테스트를 독립적으로 유지하라 • 독립적인 테스트는 혼자 실행될 수 있다 . • 독립적인 테스트는 SUT 를 테스트 하려는

동작을 검증할 수 있는 상태로 만들기 위해 자신만의 신선한 픽스쳐를 설치한다 .

• 신선한 픽스처를 사용하는 테스트는 공유 픽스처를 사용하는 테스트보다 훨씬 독립적이다 .

• 공유 픽스처를 사용하는 테스트는 변덕스러운 테스트 상태가 된다 .

• 독립적인 테스트를 사용하면 단위실패가 결함 국소화를 제공해 , 실패의 원인이 무엇인지를 정확히 집어낼 수 있다 .

Page 13: 테스트 자동화의 원칙

SUT 를 격리하라 (1/2) • 대부분의 소프트웨어는

자신이나 다른 사람이 개발한 소프트웨어에 기반해 만들어진다 .– 문맥에 민감함 : 시간에 따라 변경되어

동작이 변경될 때 테스트가 갑자기 실패할 수도 . – 이런 문맥에 민감한 코드에 자신의 소프트웨어가

의존하는 경우모든 가능한 리턴 값에 대해 적절하게 동작하는지 여부를 검증하기 쉽지 않다 .

– 테스트 안 된 코드 / 요구사항이 생긴다 .

Page 14: 테스트 자동화의 원칙

SUT 를 격리하라 (2/2) • 어플 , 컴포넌트 , 클래스 , 메소드 등

테스트하지 않은 건 뭐든지 간에 ,소프트웨어의 테스트하지 않는 부분과는 최대한 격리시켜야 한다 .이렇게 격리 시키면…– 따로 테스트 가능 – 테스트를 서로 독립적으로 유지 가능 – 문맥에 민감함을 줄여줘

견고한 테스트를 만드는데 좋다

Page 15: 테스트 자동화의 원칙

겹치는 테스트를 최소화하라 (1/2) • 대부분의 어플리케이션에는

검증할 기능이 너무 많아서 ,모든 조합과 상호작용 시나리오를 다 테스트할 수는 없다 .– 작성해야 할 테스트를 선택하는 건

리스크 관리라 볼 수 있다 .

Page 16: 테스트 자동화의 원칙

겹치는 테스트를 최소화하라 (2/2) • 특정 기능에 의존하는 테스트의 수를

최대한 작게 만들어야 한다 .– 같은 기능을 검증하는 테스트는

보통 실패할 때 다 같이 실패한다 . – SUT 에서 그 기능이 변경될 때

모든 테스트를 전부 유지 보수 해줘야 한다 .

• 보통 모든 테스트 조건이 사용하는 테스트에서 전부 다뤄지길 바란다 .테스트 조건은 딱 하나의 테스트로 다뤄져야 한다 .

Page 17: 테스트 자동화의 원칙

테스트할 수 없는 코드를 최소화하라 • 어떤 종류의 테스트는

완전 자동 테스트로 테스트하기 어렵다 .– GUI 컴포넌트 – 다중 스레드 코드 – 테스트 메소드

• 테스트 불가능한 코드의 양은 최소화하는 게 좋다 .– 테스트하고 싶은 코드를

테스트 용이성이 떨어지는 클래스로부터 옮기는 식으로 테스트 불가능한 코드를 리팩토링 .

– 코드의 전체 테스트 커버리지가 좋아진다 . – 코드에 대한 자신감 상승 -> 맘 놓고 리팩토링 -> 품질 향상

Page 18: 테스트 자동화의 원칙

테스트 로직을 제품 코드에 넣지 마라( 제품 코드에 테스트 코드 불가 )

• #ifdef ~#else ~#endif 이런 걸로 다른 로직의 실행을 방해하는 코드는 제품 코드에는 없어야 한다 .

Page 19: 테스트 자동화의 원칙

테스트별로 하나의 조건만 검증하라 (1/2) • 많은 테스트에서 SUT 를 특정 시작 상태로 만들어야 하고 ,SUT 의 기능 실행 후 SUT 의 상태가 변경된다 .– 그렇다고 하나의 테스트가 끝난 상태를

다른 테스트의 시작 상태로 재사용 하는 방법은 권하지 않는다 .•앞에서 단언문이 실패하면 남은 테스트가 제대로 동작하지 않기 때문 .

• 결함 국소화도 하기 어려움

– 자동 테스트는 한 가지 테스트 조건만 검증해야 한다 .

Page 20: 테스트 자동화의 원칙

테스트별로 하나의 조건만 검증하라 (1/2) – 각 테스트를 4단계로 나눠서 차례대로 실행하게 설계한다 .• 1 단계 . 픽스처 설치

– SUT 에게 원하는 동작을 시키기 위해 필요한 테스트 픽스처를 설치

– 실제 결과를 관찰하기 위해 필요한 무언가를 집어넣는 작업•2단계 . SUT 실행

– 검증하려는 기능을 실행하기 위해 SUT 와 상호작용 . 독립적인 동작이어야 함 .

– SUT 의 여러 부분을 실행하려 한다면 단일 조건 테스트를 작성하는 게 아닌 것이다 .

•3단계 . 결과 검증– 기대 결과가 나왔는지 확인하고 ,

결과 값이 예상과 다르다면 테스트를 실패시킨다 .•4단계 . 픽스처 해체

– 환경을 시작 전 상태로 돌려 놓는다 .

Page 21: 테스트 자동화의 원칙

따로 테스트하라 (1/3)• 복잡한 어플리케이션의 동작은

수많은 작은 동작들의 결합으로 이뤄진다 .– 같은 컴포넌트에서 여러 동작을 제공하기도 한다 .

동작마다 고민할 게 다르고 , 검증 시나리오도 엄청 많다 .

Page 22: 테스트 자동화의 원칙

따로 테스트하라 (2/3)• 하나의 테스트 메소드에서

여러 관심을 테스트하는 데 따른 문제는– 테스트 되는 관심 중 하나라도 변경되면

테스트 메소드가 깨진다– 더 나쁜 것은

어떤 관심이 실패를 유발하는지 분명하지 않다– 결함 국소화가 잘 안돼 있으므로 ,

수동 디버깅을 해야 함

Page 23: 테스트 자동화의 원칙

따로 테스트하라 (3/3)• 관심을 따로 테스트하면

실패가 발생했을 때 문제가 어디에서 생겼는지 알려주는 정도에 그치지 않고 ,시스템의 어디가 문제인지를 알 수 있다 .– 큰 노력 없이 테스트의 일부를

다른 테스트케이스 클래스로 옮길 수 있다 .

Page 24: 테스트 자동화의 원칙

효과와 책임을 적당하게 맞춰라 • 테스트를 작성하고 수정하는 데 드는 노력이

해당 기능을 구현하는 데 드는 노력보다 더 들어서는 안 된다 .– 노력 비용 작성 / 수정 < 구현

• 테스트 작성 , 관리에 필요한 도구가 기능 구현에 필요한 도구보다 더 어려워서는 안 된다 . – 도구 사용 작성 / 관리 < 구현

Page 25: 테스트 자동화의 원칙

정리 • 이전 장에서는

테스트 냄새의 형태로 나타나는 일반적인 함정과 테스트 자동화의 목표들을 살펴봤다 .

• 이번 5 장에서는 패턴을 선택할 때 사용하는 가치 체계를 구축할 수 있었다 .