본문 바로가기
버그 수치 개선

탐색적 테스트를 더 잘하기

by 도천수 2024. 1. 29.

 

제가 신입 계약직 테스터였던 시절에 무수히 많은 TC를 따라 테스트를 하는 도중 의문이 생겼습니다.

‘이 버그는 TC에 없는 행동을 했을 때 발생하네? 이런 버그들이 훨씬 많이 숨어있지 않을까?’

역시나 제 예상대로 TC에 없는 행동을 했을 때 많은 버그들이 발견되었고, 때로는 메모리 누수, 패스워드의 평문 전송 등 심각한 문제가 나타나기도 했습니다.

이쯤부터 저는 정해진 TC만을 따라 진행하는 테스트 보다 우리가 예상하지 못했던 영역으로 훌쩍 떠나는 테스트를 더 좋아하게 된 것 같습니다.

안녕하세요 원티드랩 QA팀 김명관 입니다. 업무 지식 만으로는 채울 수 없는, 진정한 QA의 육감을 발휘할 수 있는 탐색적 테스팅에 대해 공부하고, 업무에 적용해보며 배운 내용을 개인적으로도 잊지 않기 위해 리마인드 하는 글을 적어보겠습니다.

 

테스트를 하는 이유

우리는 왜 “테스트”를 할까요? 무수히 많은 TC를 모두 수행하고 찾은 버그가 모두 수정되었다면 테스트가 완료되었다고 할 수 있을까요? 만약 그렇다면 우리는 TC를 완료하기 위해 테스트를 하는 것일지도 모릅니다.

좀 더 본질적으로 생각해 보면 제품이 의도한 대로 동작하는지 확인하고 제품이 가지고 있는 위험 요소를 미리 발견하고 조치하기 위해 테스트를 합니다.

물론 잘 쓰여진 TC를 이용해 제품이 의도 대로 동작하는지 확인하고, 위험 요소를 제거할 수 있습니다. 하지만 아무리 잘 쓰여진 TC라도 놓치는 위험 요소는 생기기 마련입니다. 따라서 우리는 TC에서 발견하지 못한 또 다른 위험 요소는 없는지 탐색 해야만 합니다.

 

탐색적 테스팅

탐색적 테스팅은 일반적으로 TC 기반의 테스트 보다 효율이 우수하다고 합니다. 버그는 항상 정해진 대로 수행하는 TC보다 테스터가 제품을 직접 사용하며 느낀 이상한 부분들로부터 더 많이 발견되고는 하죠.

그렇다고 해서 버그를 많이 잡아낼 수 있는 TC를 작성하기 위해 너무 많은 양의 TC를 작성하는 것은 시간이 너무 많이 필요합니다. 따라서 개발 초기 단계부터 TC 작성에 많은 시간을 쏟아야 하는데, 개발 초기 단계에는 실제로 테스트 할 수 있는 제품이 구현되지 않아 상세한 동작의 경우 짐작하여 작성하게 되기도 합니다. 제품이 구현되고 나서는 TC를 수정하거나 제거해야 하는 상황도 발생하죠.

제품의 특정 파트가 다음 버전에서 많이 바뀌게 된다면 이전에 시간을 많이 들여 작성한 TC도 무용지물이 되는 경우도 있습니다. 따라서 너무 많은 TC를 작성하는 것 보다 TC기반의 테스팅과 탐색적 테스팅을 적절히 활용하는 것이 이상적이라고 할 수 있습니다.

탐색적 테스팅의 전문가 제임스 바크는 탐색적 테스팅을 이렇게 설명했습니다.

“탐색적 테스팅은 학습, 테스트 설계, 테스트 실행이 동시에 일어나는 테스팅 방법이다.”

제품을 직접 사용해 보며 얻은 경험과 결과를 토대로 다음 테스트를 설계하고 실행하고, 그 결과를 기록해 다음 테스트 설계에 반영하고 실행하는 연속적인 테스팅 활동입니다. 탐색적 테스트 설계, 탐색적 테스트 수행, 탐색적 테스트를 통한 학습은 상호간에 끊임없이 영향을 미치며 동시에 연속적으로 발생합니다.

이런 테스팅 활동을 성공적으로 해내 위해서는 다른 업무의 방해를 받지 않고 온전히 테스팅에 집중할 수 있어야 합니다.

테스트에 주어진 시간을 여러 세션으로 나누어 구성하고 해당 세션에서 제품에 대한 탐색적 테스팅을 진행하는 세션 기반 테스트 관리 기법은 우리가 온전히 테스팅에 집중할 수 있도록 도와줍니다.

하지만 무엇을 테스트 할 지 명확한 목적 없이 테스트 세션을 진행한다면 탐색적 테스팅에 집중하더라도 우리에게 정말 필요한 부분을 탐색하지 못하고, 유용한 정보들을 얻지 못한 채 시간만 허비할 수도 있습니다.

탐색적 테스팅을 더 잘 하기 위해서는 [명확한 목적]과 그것에 온전히 [집중할 수 있는 시간] 두 가지 모두 필요합니다.

 

테스트 차터

탐색적 테스팅의 주요 요소 중 [테스트 차터]는 탐색적 테스팅 세션 동안 테스터가 집중해서 탐색해야 할 목적을 설정해 놓은 짧은 참조 문서입니다. 우리가 함께 도착해야 할 목적지를 적어둔 쪽지라고 할 수 있는데요, 이 쪽지가 잘 쓰여질 수록 우리의 탐색적 테스팅은 성공적일 확률이 높아지겠죠.

좋은 테스트 차터를 작성하기 위해서는 3가지 요소가 필요합니다.

  1. 정보 : 기능성/비기능성, 보안성, 사용성, 일관성 등 탐색적 테스트를 통해 찾고자 하는 정보.
  2. 자원 : 도구, 데이터, 기술 등 정보를 찾기 위해 사용할 수 있는 자원.
  3. 대상 : 기능, 요구사항, 모듈 등 테스트의 대상.

위 요소를 식별하여 간단한 양식의 테스트 차터를 작성할 수 있습니다.

<테스트 차터 양식> [정보] 를 찾기 위해 [자원] 을 가지고 [대상] 을 탐색해 보자.

<예시> [유저 정보 유효 입력값 범위] 를 찾기 위해 [다양한 입력값의 조합] 을 가지고 [회원가입 양식] 을 테스트 해 보자.

아래는 좋지 못한 차터의 예시입니다.

[유저 이름에 특수문자 입력 불가 처리] 를 확인하기 위해 [유저이름###] 을 가지고 [회원가입 페이지] 에 이름을 입력해보자. 위와 같은 차터는 너무 구체적이어서 테스터의 사고에 제한을 두게 됩니다. 자유롭고 더 많은 아이디어를 떠올리는 것을 방해하는 차터 입니다.

[서비스 중 보안에 취약한 부분] 을 찾기 위해 [해킹 프로그램] 을 가지고 [서비스] 를 공격해 보자. 위와 같은 차터는 너무 광범위하고 목적이 명확하지 못해 우리에게 정말 필요하고 유용한 정보를 찾아내기 어렵습니다.

좋은 테스트 차터는 <예시> 처럼 테스트 순서를 구체적으로 명시하지 않으면서, 테스트의 목적을 명확하게 알려줄 수 있어야 합니다.

좋은 테스트 차터를 작성하는데 숙련되어 양식을 사용하지 않아도 명확한 목적을 제공할 수 있다면 반드시 양식을 따라 작성할 필요는 없습니다. 아래와 같은 한 줄의 차터도 좋습니다.

”회원가입 양식의 유저 정보 입력값 범위를 테스트 하기.”

그렇다면 테스트 차터에 작성하기 위한 [명확한 목적]은 어떻게 식별할 수 있을까요?

 

최악의 상상을 해보기

좋은 목적을 찾는 첫 번째 방법은 우리 제품의 잠재적인 위험 요소를 찾는 것입니다. 우리 제품의 어떤 기능이 잘못 동작했을 때 가장 위험할까요? 어떤 사고가 터진다면 최악의 상황이 될까요?

금융 서비스를 예로 들어보겠습니다. 만약 고객의 인출 요청이 서버에서 2번 씩 수행된다면 최악의 상황일 겁니다. 송금 시 엉뚱한 사람의 계좌에 돈이 지급되어도 최악의 상황이겠죠. 은행 앱의 비밀번호를 정상적으로 입력했으나 로그인이 되지 않는다면? 비밀번호를 틀리게 입력해도 로그인이 되어 모든 기능을 사용할 수 있다면? 이런 위험이 예상되는 경우라면 로그인, 입금, 인출, 송금 등의 기능을 집중적으로 테스트 해야 할 것입니다.

기능 뿐 아니라 함께 일하는 개발자가 평소에 테스트 코드를 제거하지 않는 실수를 자주 보였다면 테스트 코드로 인해 일어날 수 있는 최악의 상상을 해볼 수도 있을 것입니다.

이렇게 우리가 할 수 있는 최악의 상상으로부터 집중해서 살펴봐야 할 목적을 찾을 수 있습니다.

 

해야 하는 것과 하지 말아야 할 것

이전 회사에서 OTP를 테스트 한 적이 있었습니다. 자체 개발한 OTP 시스템을 이용해 관리자 로그인이 가능한지 테스트를 했습니다. OTP를 이용해 정상적으로 로그인이 가능했고, 요청 시 또는 OTP 만료 시 새로운 OTP가 발급 되어 화면에 보여졌습니다. 물론, 새로운 OTP를 이용해서도 로그인이 가능했죠.

OTP를 이용한 로그인 기능에 대해 테스트를 완료했지만, 중요한 본질을 놓치고 말았습니다. OTP는 One Time Password의 약자로 한 번 사용했던 패스워드를 다시 사용할 수 없어야 했습니다. 하지만 이전에 발급 되었던 OTP를 이용해서도 로그인이 가능한 것을 나중에 알게 되었습니다.

저는 OTP의 본질을 이해하지 못한 상태에서 테스트를 마쳤고 그 결과 유효하지 않은 패스워드로도 관리자 로그인이 가능하다는 심각한 버그를 놓치게 되었습니다.

제가 테스트 해야 했던 기능은 [OTP를 이용한 로그인] 이었지만, [로그인] 에 너무 집중했기 때문에 발생한 일이었습니다. 테스트 할 대상의 본질을 이해하고 “해야 할 것”과 “하지 말아야 할 것” 을 명확히 식별하여 테스트 하는 것 또한 테스트의 목적을 설정하는데 도움이 됩니다.

 

마치며

위에서 언급한 방법들을 실무에 적용해보며 테스트 설계, 실행 시 위험 요소로 생각되는 부분을 테스트 차터를 작성해 테스트의 명확한 목적을 설정하고 탐색적 테스트를 진행해 보고 있습니다.

정량적으로 얼만큼 더 좋아졌는지 측정하기는 힘들지만, 그때 그때 생각나는 항목들을 간단하게 메모장에 적어두고 시간이 지난 뒤 어떤 메모였는지 잊어버렸던 전보다 많이 달라졌다고 느끼고 있습니다.

프로젝트 진행 간에 개발자 분들과 대화를 나누는 횟수가 더 많아지고 위험 요소를 분석하게 되었습니다. 또, 차터를 이용해 제가 테스트 해야 할 목적이 명확해 졌기 때문에 그로 인한 결과 역시 명확하게 정리해 기록되고, 결과를 토대로 새로운 테스트 설계가 이어지고 있습니다. 덕분에 제품을 좀 더 세심하게 살펴보는 능력과 그것을 만드는 사람들에 대한 관찰도 할 수 있게 되었습니다.

원티드랩 에서는 주 3일 재택근무를 하기 때문에 온전히 테스트에 집중할 수 있는 환경이 잘 구성되어 있어 배운 것을 실무에 적용해 보는데 도움이 많이 되었습니다.

아직 탐색적 테스트에 대해 배울 것이 한참 많지만, 한 번에 너무 많은 내용을 진행하기 보다 지금까지 배운 것을 실무에 잘 녹여낸 뒤 더 높은 레벨의 새로운 것을 받아들일 수 있게 되면 좋겠습니다.

감사합니다.


부록

탐색적 테스트 (Exploratory Testing)

  1. 정의: 탐색적 테스트는 테스트를 수행하면서 테스트 계획, 설계, 실행을 동시에 진행하는 방법입니다. 테스터가 시스템의 작동을 탐색하면서 발견된 문제를 기반으로 즉각적으로 대응하며 테스트를 수행합니다.
  2. 목적: 소프트웨어의 이해도를 높이고, 예상치 못한 버그를 발견하는 것이 주 목적입니다. 기능의 논리적 일관성, 사용자 경험, 경계값 등을 탐색하며 테스트합니다.
  3. 계획성: 테스터가 명확한 목표와 전략을 가지고 테스트를 진행합니다. 즉흥적이지만 어느 정도의 계획을 포함하며, 테스트 결과를 기록하거나 노트에 정리할 수 있습니다.
  4. 테스터의 전문성: 테스터의 경험과 지식이 테스트의 품질에 크게 영향을 미칩니다.

애드혹 테스트 (Ad-hoc Testing)

  1. 정의: 애드혹 테스트는 계획이나 구조 없이 즉흥적으로 수행되는 테스트입니다. 정해진 절차나 문서 없이 단순히 소프트웨어를 사용해 보면서 버그를 찾는 방식입니다.
  2. 목적: 빠르게 문제를 찾거나 기본적인 확인을 위해 사용됩니다. 공식적인 테스트가 아니라, 짧은 시간 내에 대략적인 문제를 식별하는 데 중점을 둡니다.
  3. 계획성: 거의 계획이 없으며, 자유로운 방식으로 수행됩니다. 정해진 기준 없이 테스트가 수행되기 때문에 일관성이 떨어질 수 있습니다.
  4. 테스터의 전문성: 모든 수준의 테스터가 수행할 수 있지만, 경험이 많을수록 효과적일 수 있습니다.