본문 바로가기

dev story

[번역글] 종단간 테스트 (end to end test) 는 이제 그만

아래는 구글 테스팅 블로그에 올라온 포스트를 제가 번역한 글입니다. - 원글 : http://googletesting.blogspot.kr/2015/04/just-say-no-to-more-end-to-end-tests.html

오역과 수준낮은 번역이 (다수) 포함되어 있을수 있습니다. 제보해주시면 수정하도록 하겠습니다. 

 

종단간 테스트 (end to end test) 는 이제 그만 - by Mike Wacker

 

당신의 삶에 어떤 시점에서, 아마 당신과 친구 모두가 보고 싶었던 영화를 보고난후 모두가 후회를 한 기억을 회상할수 있을 것이다.
아니면 당신은 당신의 팀들이 "킬러피쳐"라고 생각된 기능을 만들고, 그것이 출시된후 "킬러폭탄"이 된 기억을 가지고 있을 것이다.

좋은 아이디어는 종종 실제, 테스트의 세계에서 실패하는 경우가 있고, 그런 의미의 "좋은 아이디어" 가 바로 종단간 테스트 중심의 전략이라고 할수있다.

테스터는 그들의 시간을 자동화테스트, 단위테스트, 통합테스트, 그리고 종단간 테스트등을 작성하는데 투자할수 잇지만 이 전략은 전체적인 제품 또는 서비스를 확인하는데 종단 간 테스트에 주로 투자한다. 
일반적으로 이러한 테스트는 실제 사용자 시나리오를 시뮬레이션 할 수 있다.

이론에서의 종단간 테스트 (End-to-End Tests in Theory )

종단간 테스트에 주로 의존하는 것은 좋지는 않지만, 하나 확실히 것은 있다.

우리가 알고있는 "Google이 발견한 10가지 진실" 중 첫번째는 "사용자에게 초점을 맞추면 나머지는 저절로 따라옵니다" - "focus on the user (and all else will follow)," - 이다.
따라서, 실제 사용자 시나리오에 초점을 둔 종단간 테스트는 좋은 아이디어로 들린다. 또한 이 전략은 많은 지지를 받는다.

  • 개발자들은 부담이 없어서 좋아한다. 이 테스트의 대부분은 본인이 하지 않기 때문일 것이므로.
  • 관리자와 의사 결정자는 유저 시나리오를 시뮬레이션하기 때문에 사용자가 받을 영향을 직접 확인하는데 도움이 되므로 좋아한다.
  • 테스터는 실제 동작을 확인하지 않는 테스트를 작성하거나 버그를 놓치는 걱정을 덜수 있으므로 좋아한다. 
    - 사용자의 관점에서 테스트를 작성하는 것은 종종 두 문제를 방지하고 테스터에게 성취의 큰 의미를 준다.


실제의 종단간 테스트 (End-to-End Tests in Practice )

이 테스트 전략이론이 정말 좋은 소리로 들린다면, 그럼 그것은 실제로 잘못일까? 
이것을 설명하기 위해, 나 자신과 다른 테스터 모두에게 익숙한 실제 경험기반으로 다음 복합 스케치를 제시한다. 이 스케치에서, 팀은 온라인 문서 편집을위한 서비스 (예를 들면 구글 문서 도구) 를 구축하고있다.

이 팀은 이미 일부 환상적인 테스트 인프라를 가지고 가정하자. 매일 밤 :

  1. 이 서비스의 최신 버전이 빌드되어 있습니다.
  2. 이 빌드 버전은 팀의 테스팅 환경에 배포됩니다.
  3. 모든 종단간 테스트가 이 테스트 환경에서 실행됩니다.
  4. 이메일로 시험 결과가 요약되어 팀으로 전송됩니다.

다음 릴리스를 위한 새로운 기능을 담은 우리팀의 새 코드의 마감일은 빠르게 다가오고 있다.
제품 품질에 대한 높은 수준를 유지하기 위해, 또한 기능이 완료된 것으로 판단하기 위해서는 종단 간 테스트는 90 % 이상이 통과하는 것이 필요하다. 
현재, 그 데드라인은 단 하루가 남아있다.

잔여일
 패쓰율
주의 사항
15%모든것이 동작불가! 서비스에 로그인하면 중단됨. 로그인이 실패되므로 거의 모든 테스트가 실패됨.
04%우리 소스에 의존하고 있는 유관팀이 어제 잘못된 소스로 빌드를 해서 테스트 불가.
-154%개발쪽에서 어제의 결과를 가지고 진행하면서 절반정도에서 중단. 개발팀은 버그가 프론트엔드인지 백엔드버그의인지의 여부를 확인하는데 하루의 대부분을 보냄.
-254%오늘 하루종일 어디에서 발생한 이슈인지를 확인후 프론트엔드 버그란것을 확인.
-354%취약점은 전일 확인완료. 아주 작은 실수였지만, 오늘 수정되어 코드 체크되었음.
-41%테스트 환경에서 하드웨어 장애 발생하여 테스트 불가됨.
-584%큰 버그 뒤에 숨어 많은 작은 버그가 숨어있음. 잔여 버그들은 여전히 동작중.
-687%우리는 90% 이상이어야하지만, 어떤 이유로 그냥 갈수도...
-789.54%(90%에 가까운만큼, 종료할만하다. ) 어제 어떤 패치도 새로 체킹되진 않았다. 그러므로 테스트 결과는 맨붕(flaky)이다..


분석

수많은 문제에도 불구하고, 테스트는 궁극적으로 실제 버그를 잡아냈다.

 

잘된점

  • 고객에 영향을 미치는 버그를 확인하고 고객에게 문제가 발생하기 전에 수정되었습니다.

잘못된점

  • 팀은 목표보다 일주일 늦게 마일스톤을 완수했다. (엄청난 초과근무와 함께)
  • 실패된 종단간 테스트의 근본원인을 찾는것은 인내와 오랜 시간소요를 가져왔다.
  • 유관팀의 오류와 테스트인프라 장애는 여러 날의 테스트 결과를 망쳤다.
  • 많은 작은 버그가 더 큰 버그 뒤에 숨겨져있었다.
  • 종단간 테스트는 맨붕(flaky)이다..
  • 개발자는 버그가 제대로 픽스되었는지를 확인하기 위해서는 다음날까지 기다려야만 했다.

그래서 지금 우리는 종단간테스트전략에 무엇이 잘못되었는지 알고, 우리는 이러한 많은 문제를 피하기 위해 테스트에 대한 우리의 접근 방식을 변경해야한다. 그러나 올바른 접근 방식은 무엇인가?

테스트의 진정한 가치 (The True Value of Tests) 

일반적으로 테스터의 일은 실패한 테스트를 찾으면 종료된다. 버그가 제출된 다음 버그를 해결하는건 개발자의 일이다. 종단간 테스트 전략이 실패되는 원인을 찾기위해선, 이 테두리밖에서 생각하여야 한다.

만약 우리가 위에서 말한 "사용자에게 초점을 맞추면 나머지는 저절로 따라옵니다" 를 생각하고 있다면, 실패한 테스트가 사용자에게 어떤 이익을 주는지를 물어봐야 한다. 

여기에 대한 답은 다음과 같다.

실패된 테스트검출은 사용자에게 직접적인 이득을 주지 못한다.

이 문장은 처음에는 충격적이겠지만, 그것은 사실이다. 제품이 동작을 하던 안하던, 장애가 나던 안나던 사용자에게는 실패된 테스트는 아무런 도움을 주지 못한다. 그럼 언제 사용자에게 이익이 돌아가는가?

 

버그수정은 사용자에게 직접적인 혜택을 제공한다.

사용자는 버그가 사라진 상태에 있을때 바로 그때만 행복해할 것이다. 

물론, 버그를 고칠려면, 당신은 버그가 존재하는지를 알고 있어야만한다.

버그의 존재여부를 알기 위해 이상적으로는 버그를 잡기위한 테스트를 가져야만 한다. (테스트가 수행되지 않은 경우 사용자가 버그를 찾을 수 있기 때문에)

그러나 전체 과정에서 실패건테스트에서 버그를 수정하기 위해서는, 혜택은 맨 마지막 단계에 추가된다.

구역
실패건
발견 버그 오픈상태
버그 수정됨
부가가치NoNoYes

따라서, 모든 테스트 전략을 평가하기 위해, 그냥 버그를 찾는 방법만으로 평가해서는 안된다.

반드시 개발자가 버그를 찾고 (심지어 방지하는 ) 방법을 가능하게 하는 방법을 찾고 평가해야 한다.

 

이상적인 피드백 루프 생성하기 (Building the Right Feedback Loop)

테스트는 개발자에게 테스트 제품이 작동되는지 여부를 알리는 현상 피드백 루프를 생성한다.
이상적인 피드백 루프는 몇 가지 속성이 있다 :

  • 빠르다.
    • 어떤 개발자도 자신의 변경 작동 여부를 확인하기 위해 몇 시간 또는 며칠을 기다려야하고 싶어하지 않는다. 어떨때는 변경한 부분이 동작하지 않을수도 있고 - 아무도 완벽하지 않으므로 - 그래서 또한 피드백 루프는 여러 번 실행되어져야 한다.빠른 피드백 루프는 빠른 수정으로 이어니다. 루프가 충분히 빠르다면, 개발자들도 변경 작동 여부를 확인하기 전에 테스트를 실행할 수 있다.
  • 신뢰할수있다.
    • 어떤 개발자도 테스트 원인을 찾기 위해 몇시간을 헤매고 싶어하지 않는다. 이상한 (Flaky) 테스트 결과는 개발자의 테스트 신뢰도를 줄이게 될것이고 이는 실제 제품의 문제를 발견했음에도 종종 테스트 결과를 무시하는 결과를 초래할수도 있다.
  • 실패건이 격리되어있다.
    • 버그를 해결하려면, 개발자는 버그를 일으키는 코드의 특정 라인을 찾을 필요가있다.제품코드가 수백만 코드 라인을 포함하고 있다면, 이것은 건초 더미에서 바늘을 찾기 위해 노력과 같을 수가 있다.

 

크게 보지말고 작게 생각하자 (Think Smaller, Not Larger)

그렇다면 우리는 이상적인 피드백 루프를 만들려면 어떻게해야할까? 크게 보지말고 작게 생각하자.

 

단위 테스트

단위 테스트는 제품의 작은 조각을 가지고 테스트에 임하며, 그것들은 격리되어있다. 이것들은 이상적인 피드백 루프를 생성하는 경향이있다 :

  • 단위 테스트는 빠르다.
    • 우리는 단지 작은 테스트 유닛만을 구축 할 필요가 있고, 또한 테스트 또한 오히려 작아지는 경향이 생긴다. 사실, 10 분의 1초도 단위 테스트에서는 느린 것으로 간주된다.
  • 단위 테스트는 신뢰할수 있다.
    • 단순한 시스템과 작은 단위는 일반적으로 맨붕(Flakiness)에서 훨씬 쉽게 벗어날수있다. 또한, 단위 테스트를 위한 최상의 방법 - 밀폐 시험과 관련된 특정 관행은 - 완전히 혼돈을 벗어날수 있게 해준다.
  • 단위테스트는 실패건을 격리시킨다.
    • 제품이 수백만 줄의 코드를 포함하더라도 단위 테스트가 실패하면, 당신은 단지 버그를 찾기 위해 테스트중인이 작은 유닛만을 검색하면 된다. 
      효과적인 단위 테스트를 작성하는 것은 이러한 의존성 관리, 목업, 밀폐 테스트 분야의 기술이 필요하다.

나는 여기에 이러한 기술적인 사항을 모두 포함하고 싶진 않지만 , 새로운 구글 직원 (또는 Nooglers)에게 제공되는 how Google builds and tests a stopwatch 를 전형적인 예로 들수있다.

 

단위 테스트 대 종단간 테스트 (Unit Tests vs. End-to-End Tests)

종단간테스트에서는 먼저 제품이 빌드되고 배포되고 최종적으로 테스트가 실행될때까지의 과정을 기다려야만 한다.

테스트가 실행중일때 괴상한 테스트는 실제 어디에는 숨어있을 가능성이 있다. 그리고 테스트가 버그를 발견 한 경우에도, 그 버그는 제품 어디에든 있을 수 있다.

종단간 테스트가 실제 사용자 시나리오를 시뮬레이션하는 더 나은 작업을 수행하지만, 이러한 장점은 곧 종단간 테스트 피드백 루프의 모든 단점이 되어버린다.

 
단위테스트
종단간테스트
신속성

테스트 신뢰도
실패 격리성
사용자 시뮬레이션

 

통합 테스트 (Integration Tests)

단위테스트는 아주 큰 단점 하나를 가지고 잇다. - 이 단위가 격리되어 잘 작동하더라도 - 이것이 (제품으로써) 함께 잘 동작할지를 알수없다는 것이다.
하지만 그렇다하더라도, 당신은 반드시 종단간 테스트가 필요하지는 않다. 이를 위해서는 통합 테스트를 사용할 수 있다. 
통합 테스트 유닛은 종종 두 단위의 소그룹을 취해, 이것들이 함께 잘 동작하는지를 테스트하고 분석할수 있다.

이 단위건들이 제대로 통합하지 않는다면, 왜 통합테스트에서 동일한 버그를 찾기 위해 촛점을 맞추지 않고 종단간테스트의 TC를 작성하고 있는가? 
당신이 좀 더 넓게 생각해봐야 할 필요가 있다면, 단지 작은 유닛들이 함께 동작하는지를 좀 더 확장성있게 가져가면 된다.

테스트 피라미드 (Testing Pyramid)

심지어 단위 테스트 및 통합 테스트를 진행함에도, 당신은 아마도 여전히 소수의 전체 시스템의 종단간 테스트를 원할 것이다. 
세 가지 테스트 유형 간의 적절한 균형을 찾기 위해 사용하는 가장 시각적인 지원은 테스트 피라미드이다.
이것은 2014 년 구글 테스트 자동화 컨퍼런스의 기조 연설에서 발표된 테스트 피라미드의 단순화 된 버전입니다 :

 



테스트의 대부분은 피라미드 아래쪽의 단위테스트이다. 이 피라미드가 위로 올라갈때, 테스트 범위는 넓어져야 하지만, 동시에 테스트 숫자 ( 피라미드의 넓이)는 작아져야 한다.

올바른 가정으로 구글은 종종 70/20/10 분할을 제안한다. 70% 단위 테스트, 20% 통합 테스트 및 10% 종단 간 테스트.

정확한 비율은 각 팀에 따라 상이할 것이지만, 일반적으로는 그 피라미드 모양을 유지한다. 아래와 같은 안티 패턴을 피하여 보라 :

  • 역삼각형 피라미드 / 아이스크림 콘 형상. (Inverted pyramid/ice cream cone)

팀은 종단간 테스트에 주로 의지하고, 소수의 통합테스트와 더 극소소의 단위테스트에 의존한다.

  • 모래시계 (Hourglass)

팀은 많은 수의 단위테스트를 진행하고 그 후 통합테스트 대신에 종단간 테스트에 의존한다. 모래시계는 많은 수의 유닛테스트를 바닥에 깔고 있고 또한 다수의 종단간 테스트를 위쪽에 가지고 있지만, 소수의 통합테스트만이 가운데에 놓여져 있다.

일반적인 피라미드 구조가 실제 생활에서 가장 안정적인 것처럼, 테스트 피라미드는 가장 안정적인 테스트 전략의 경향을 띄고 있다.