티스토리 뷰


리그레션 다시 생각해보기 파트 4: 리스크 테스팅에서 잘못된 점은 무엇인가?

 

Anne-Marie Charrett 는 그녀의 포스트 새로운 리그레션, 리세션 테스팅(Recession Testing is the new Regression Testing)에서, 리그레션 테스트가 너무 자주 수행된다는 것에 대한 불만을 나타냈다. 이는 거의 모든 테스터들이 가지고 있는 불만이며, 이런 불만이 제기된다는 것 자체가 분명 여기에 어떤 문제가 있다는 것을 나타내는 것이다.

 

리그레션 리스크를 완화시키기에 앞서, 우선 리그레션 테스팅에서 잘못된 점은 무엇인지 알아볼 필요가 있다. 

 

우선 리그레션 테스팅이라는 단어를 통해 내가 의미하고자 하는 바를 명확하게 짚고 넘어가자. 여기서 말하는 블랙박스 리그레션 테스팅은 테스터들이 일반적으로 수행하는 블랙박스 리그레션 테스팅을 말하는 것이다.
이런 리그레션 테스팅은 흔히 다음과 같은 단계를 거쳐 수행된다.

 

1.      새로운 기능을 위해 테스트를 설계하고 수행함

2.      향후에도 재사용하기 위해 테스트들을 리그레션 팩에 저장함

3.      버그를 찾아내기도 함: 발견된 버그에 대한 수정사항을 전달받고 확실하게 수정되었는지 체크하기
위해 테스트를 작성하고 이를 리그레션 팩으로 저장함

4.      빌드가 변경될 때 일부 혹은 모든 테스트를 다시 한 번 수행함

5.      리그레션 팩의 일부 혹은 전부를 자동화함

 

, 이제 이런 일반적인 방식의 리그레션 테스팅을 앞서 설명한 리스크 완화 전략[1]이라는 관점에서 한 번 살펴보자.

 

예방(Prevention). 테스트 설계를 통해 리그레션 리스크를 어느 정도 완화할 수도 있다. 하지만 이 방법을 수행하기 위해서는 테스트 베이시스에 대한 세심한 조사가 필요하다. 앞서 설명한 방법은 어떤 것을 설계한다기보다는 오히려 단순한 반복적 수행에 가깝다. 리그레션 리스크라는 관점에서도 어떤 예방 효과도 가질 수 없다.

 

확인(Confirmation). 앞서 설명한 일반적인 리그레션 테스팅의 핵심은 바로 확인이다. , 이번 빌드에 대한 테스트가 가장 최근의 빌드와 동일한 결과를 내놓는다는 것을 체크하는 것이다. 이러한 테스트가 유용한 이유가 바로 이런 점 때문이다. Paul Gerrad Charrett 의 포스트에서 댓글로 지적했던 것과 같이, 이러한 종류의 리그레션 테스팅은 기능적으로 동등함을 보여주는데(about demonstrating functional equivalence)” 있어 효과적이다. 하지만 블랙박스 테스팅을 사용해 이런 기능적인 동등함을 보여주는 것은 유닛 테스팅을 사용할 때보다 더 어렵다.  

 

n         블랙박스 레벨의 테스트를 수행하는 테스터는 여러 기능이 동시에 수행되는 결과로 나타나는 증상만을 관측할 수 있으며, 이는 개별 기능에 대한 마스킹으로 작용할 수 있다.

n        그에 반해, 기능 자체는 유닛 레벨에서 정의되는 것이다. 변경에 따른 임팩트가 가장 확실하게 드러나는 것도 유닛 레벨이며, 개별 기능의 동작 역시 유닛 레벨에서 더 쉽게 격리되고 검증될 수 있다. 

 

반증(Disconfirmation). 이 방법은 버그가 발견되었을 때 중요한 의미를 가진다.

n         버그가 발견되었다는 것은 비용 대 효율성이 낮다는 것을 입증한다.
리그레션에 앞서 수행된 테스트에서 일반적으로 발견될 수 있는 모든 버그들이 발견되어야 한다. 리그레션 테스팅 역시 비용과 시간이 소모되는 일이다. 리그레션 팩은 점점 더 규모가 커져가고, 이를 수행하고 유지하는 것도 부담이 되기 시작한다. 나는 이에 관해 몇 가지 프로젝트를 대상으로 비공식적인 조사를 수행한 경험이 있다. 그 결과, 전체 테스팅 업무에 투입되는 리소스 중 70~90%가 리그레션 팩을 수행하고 유지보수하는데 소모되지만, 정작 발견된 모든 버그의 20% 정도만을 발견해낸다는 것을 알 수 있었다. 이러한 결과는 브라이언 매릭(Brian Marick) “How Many Bugs Do Regression Tests Find?” 에서 보고한 것과 다르지 않다.

n        더 안 좋은 것은, 리그레션이 상당한 기회비용을 가질 때다.
궁극적인 테스팅은 불가능하다. 이는 곧 모든 테스팅 행위가 특정한 부분만을 골라 수행된다는 것을 의미한다. 리그레션을 많이 수행할수록, 다른 것을 테스팅할 기회가 줄어들기 마련이다. , 우리가 선택할 수 있는 부분이 더 줄어드는 것이다. 이런 유형의 리그레션 테스팅은 테스트 커버리지를 효율적으로 높이지도 못할뿐더러 버그 역시 발견하지 못한채로 지나갈 수 있다.

n        리테스트를 여러 번 다시 수행하는 것은 불합리한 일에 가깝다.
소잃고 외양간 고친다는 속담을 한 번 생각해보자. 도망쳤던 소가 다시 돌아오고 외양간을 수리했다고 가정하자. 그 이후에 아무도 외양간 근처에 가지 않았다면, 그 소가 다시 도망갈 가능성은 얼마나 될 것인가? 마찬가지로, 버그가 발생했던 코드가 수정된 이후 변경되지 않았음에도 불구하고 해당 버그가 재발할 가능성은 얼마나 될 것인가? 제로(Zero). 버그를 유발한 코드에 변경사항이 없음에도 불구하고 습관적으로 리테스트를 반복하는 것은 합리적이라고 볼 수 없다. 

n        이전에 수행하던 테스트로는 새로운 문제를 발견할 수 없다.
우리는 두 가지 방법으로 테스트를 설계한다. 하나는 수행되어야 하는 기능이 제대로 수행되는지를 점검하기 위한 긍정적 테스트(confirmatory test) 설계이며, 다른 하나는 문제를 찾을 목적으로 수행하는 부정적 테스트(disconfirmatory test) 설계이다. 후자는 우리의 생각이 잘못될 수 있다는 것을 전제로 하고 있다. 코드가 변경된다면 코드가 처음 작성되었을때와는 완전히 다른 것들이 잘못될 수 있다. 새로운 문제를 찾기 위해서는 새로운 테스트가 필요하다. 오래된 테스트와 행운이 필요한 것이 아니다.

n        지금까지 수행하던 테스트가 같은 버그를 계속 놓치고 있을 수도 있다.
모든 테스트가 버그를 찾아낼 수도 있고, 어떤 버그들을 놓칠 수도 있다. 끊임없이 반복되는 동일한 테스트라면 지속적으로 동일한 버그를 놓치고 있을 수도 있다. 소프트웨어 테스팅 기법에서 보리스 바이저(Boris Beizer) 가 말한대로 살충제 패러독스(Pesticide paradox)” 가 발생하고 있는 것이다.

n         자동화도 도움을 주지 못한다.
자동화는 개발과 유지보수에 많은 비용이 든다. 어떤 경우는 수동으로 테스트를 수행하는 것에 비해 10배 가까운 비용이 더 들기도 한다.[2] 하지만 그 결과는? 불행하게도 자동화라는 개념 자체가 영리한 행위는 아니다.[3] 테스터들이 테스트를 수행하는 동안에는 발생한 장애를 인지하고 조속하게 처리할 수 있지만, 자동화는 단지 기대한대로 자동화가 수행되는 지에 대해 관심이 집중될 뿐이다. 자동화된 GUI 리그레션 테스트를 수행할 때는 아무런 버그도 찾아내지 못했던 테스트를 상당 부분 수동 리그레션 팩으로 대체한 팀도 있었다. 버그 발견과 관련해 이정도 비용효율을 가지고 있는 자동화라면 수동으로 수행하는 리그레션보다 낫다고 할 수는 없을 것이다.

 

앞서 살펴본 바와 같이 블랙박스 리그레션 테스팅은 리그레션 리스크를 완화한다는 측면에서는 심각한 결함을 가지고 있는 것이 명백하다. Charrett 이 말한 바가 옳다. 이제 다른 패러다임이 필요할 때다.

 

그럼 어떻게 이 모든 것들이 달라질 수 있는가? 향후 리그레션 리스크를 완화하는 전략을 선택하는 방법과 어떻게 우리가 처한 컨텍스트가 이러한 선택에 영향을 미치는지에 대해 다음 포스트에서 논의하고자 한다.       

   

 



[1] 역자 주: 앞선 포스트에서 저자는 리스크 완화 전략으로 예방(Prevention), 확인(Confirmation) 그리고 반증(Disconfirmation)의 방법을 제시했다.

[2] : Kaner, Bach and Pettichord: Lessons Learned in software Testing

[3] 역자 주: 원문은 “Unfortunately, automation is fundamentally stupid”. 직역하자면 불행하게도, 자동화는 기본적으로 어리석은 짓이다정도가 될텐데, 여기서 의미하는 바는 자동화가 창조적인 행위라기 보다는 동일한 행위를 단순 반복하도록 만드는 것이라는 의미라고 해석됨.