QA=테스트라는 잘못된 인식이 불러온 오해 (2)
상태바
QA=테스트라는 잘못된 인식이 불러온 오해 (2)
  • 데이터넷
  • 승인 2018.03.06 08:31
  • 댓글 0
이 기사를 공유합니다

테스트만으로 품질 향상 어려워…품질 목표 설정 후 모든 개발 단계서 노력해야
▲ 홍성호 투비소프트 품질보증그룹장(sunny418@tobesoft.com)

테스트는 품질을 향상시키기 위한 여러 활동들 중 하나일 뿐, 테스트만 잘 한다고 해서 품질이 높아질 수는 없다. 오히려 테스트를 통해 발견된 결함들도 경우에 따라서는 수정하지 않고 넘어가는 경우도 다반사다. 완벽한 소프트웨어를 추구하며 테스트에만 몰두하는 것보다는 먼저 품질 목표를 설정하고, 그에 따른 효율적인 개발 방안을 설정하는 것이 소프트웨어 품질 향상에 도움이 될 것이다. <편집자>

연재 순서

1. 테스트라는 잘못된 인식이 불러온 오해
2. 실효가 있었던 경험 위주의 QA에 대한 진실들(이번호)

지난 호에서 ‘QA=테스트라는 잘못된 인식이 불어온 오해’에 대해 알아봤다. 이번 호에서는 테스트가 품질 향상으로 귀결되지 않는 이유를 알아보고, 품질에 실효가 있었던 활동에 대해 사례 중심으로 알아보겠다. 먼저 지난 호에서 다뤘던 ‘QA=테스트’라는 오해의 예를 좀 더 상세하게 짚어보자.

테스트를 잘 하면 품질이 좋아지는가?
질문을 바꿔서 “품질에 영향을 미치는 활동에는 어떤 것들이 있는가?”라고 묻는다면 아마도 다양한 대답이 나올 것이다. 코딩, 설계, 테스트, 요구분석, 형상관리, 프로젝트 관리, 이슈관리, 위험관리 등 여러 활동들을 나열할 것이다. 어찌 보면 모두들 정답을 알고 있는 셈이다. 품질을 향상시키기 위해서는 이러한 활동들을 골고루 잘 해야 한다. 그러나 현실은 테스트만 잘하면 품질이 높아질 것이라는 희한한 기대를 품고 있다.

중소규모 조직의 소프트웨어 개발에서 테스트보다는 다른 활동이 미약해서 품질에 문제가 발생하는 경우가 대부분이다. 대개 요구분석이 미흡한 경우가 많고, 협업을 많이 하는 조직의 경우는 형상관리만 잘 해도 품질이 획기적으로 높아지기도 한다.

▲ <그림 1> 테스트만 강조하는 조직은 다른 활동이 약해져 소프트웨어 품질이 낮아지는 경우가 많다.

<그림 1>처럼 테스트는 소프트웨어 품질을 높이기 위한 여러 가지 활동들 중의 하나일 뿐이다. 다른 활동이 미약하다면 아무리 테스트를 잘 해도 고품질을 기대할 수 없다. 예를 들어 테스트를 잘해서 결함을 많이 발견해도 그것들을 수정하는 과정에 끊임없이 파생결함이 발생한다면 결국 소프트웨어 품질이 낮아질 수밖에 없는 것이다.

최근 소프트웨어 품질 관련 교육들을 보면 테스트 교육들이 대부분이다. 우리나라는 유독 ‘품질=테스트’라는 생각이 만연해 있다. 이러한 기조가 소프트웨어 개발 시장에 각인돼 있는 한 소프트웨어 품질은 끊임없는 결함들의 늪에서 빠져 나오지 못할 것이다. 그렇다고 테스트가 필요 없다는 뜻은 아니다. 품질저하 문제를 테스트 강화로만 풀려는 생각에서 벗어나야 한다는 의미다.

테스트는 품질향상에 도움이 되지만 품질을 위한 만능 키가 될 수는 없다. 테스트의 올바른 이해를 위해 테스트가 어떤 한계를 갖고 있는지 경험했던 사례 위주로 설명하겠다.

정확하게 테스트 할 수 없다.
만일 호텔 요리사에게 상한 식재료를 주면서 요리해 달라고 하면 어떨까? 아마 그 요리사는 음식 만들기를 거부할 것이다. 최고의 요리사는 최고의 재료를 고르는 것부터 시작한다는 것은 누구나 아는 상식이다.

▲ <그림 2> 뛰어난 요리사도 상한 재료로 맛있는 요리를 못 한다. 테스트도 마찬가지다.

그런데 테스트는 어떤가? 테스터에게 제공되는 식재료를 점검해 요리(테스트)가 가능한 상태인지를 확인한 적이 있는가? 식재료가 상했다고 요리(테스트)를 거부하는 테스터를 본 적이 있는가? 혹시 테스트 결과가 실망스러웠을 경우, 그 식재료부터 확인해본 적이 있는가? 이 질문들에 대한 대답은 테스터의 식재료가 무엇인지를 파악하면 금방 알 수 있게 된다. 그리고 그 테스터가 정확하게 테스트를 할 수 없는 이유도 금방 알 수 있게 된다.

테스트를 위한 테스트 케이스를 작성하려면 테스트 베이시스라는 식재료가 있어야 한다. 일반적으로 많이 알려져 있는 테스트 베이시스(식재료)에는 요구사항 정의서, 설계서, 매뉴얼 등이 있다. 테스터들은 이 자료들을 분석해서 테스트 케이스를 작성하고 수행한다. 이 테스트 베이시스가 부정확하거나 일부 내용이 누락돼 있다면 그 내용을 토대로 작성한 테스트케이스 또한 부실할 수밖에 없다. 그리고 테스트의 정확성도 떨어질 수밖에 없다.

많은 프로젝트에서 요구사항 정의서, 설계서, 운영자 매뉴얼, 사용자 매뉴얼 등을 프로젝트 종료 시점에 급하게 작성하는 경우가 종종 있다. 그런데 이런 문서들이 바로 테스트 베이시스인 것이다. 결국 프로젝트의 종료 시점에 테스트 베이시스를 작성한 셈이라서 부정확한 테스트 케이스를 작성했다고 볼 수 있다. 그리고 이 부실한 테스트 케이스들을 토대로 테스트를 했다면 그 테스트 품질 역시 부실할 수밖에 없다.

만일 요구사항 정의서나 설계서보다 테스트를 더욱 강조하는 프로젝트라면 테스트를 부실하게 했음을 100% 보장할 수 있다. 왜냐하면 테스트 베이시스가 부실했을 것이 분명하기 때문이다. 정확한 테스트는 정확한 테스트 베이시스를 필요로 한다. 정말로 테스트를 잘 하고 싶다면 테스트 베이시스를 튼튼하게 작성하는 것부터 먼저 해야 한다.

테스트는 가장 비싼 품질 비용
소프트웨어 개발 과정에서 테스트는 후행 작업이므로 결함 유입을 예방할 수는 없다. 테스트는 먼저 구현을 완료한 후, 그 결과물에서 결함을 찾아내는 활동이다. 거꾸로 테스트를 먼저 한 후에 구현할 수는 없는 노릇이다. 예를 들면 도자기가 잘 만들어졌는지를 검사하려면 일단 도자기를 가마에 넣고 구워야 한다. 그리고 다 구워진 다음에야 결함을 찾는 활동을 할 수 있다.

마찬가지로 테스트는 구현 단계의 결함유입을 막을 수 없고, 이미 유입된 결함을 찾아내는 후행 작업일 뿐이다. 소프트웨어 품질은 결함 유입 예방을 첫 번째 타깃으로 삼아야 한다. 유입된 결함을 찾고 수정하는 것보다 결함 유입을 방지하는 것이 훨씬 비용이 저렴하기 때문이다. 테스트는 사후조치 활동이므로 예방활동에 비해서 비용이 비쌀 수밖에 없는 운명을 타고 났다.

소프트웨어 품질 향상을 위해 가장 비용이 적게 드는 방법은 결함을 유입시키지 않는 것이다. 하지만 테스트는 개발 단계상 결함 유입 방지 역할을 수행할 수 없는 위치에 있다. 그렇기 때문에 테스트로만 품질을 향상시키려는 노력은 결국에는 비싼 품질 비용만을 지불하겠다는 뜻이 된다.

추가로 테스트에서 결함을 많이 발견했다고 품질이 높아지는 것도 아니다. 결함이 많이 발견됐다는 뜻은 그만큼 발견되지 않은 더 많은 결함이 숨어있다는 뜻도 되기 때문이다. 그리고 테스트에서 발견한 결함들을 현실적인 이유(비용, 작업시간 등)때문에 모두 수정하지 못하는 경우도 많다. 이렇게 결함을 남겨두는 경우 일부의 테스트 활동은 불필요한 비용 지출이라고 볼 수도 있다.

리그레션 테스트의 무한루프에 빠질 수 있다
테스트로 발견한 결함은 수정해야 한다. 문제는 결함을 수정하는 과정에서 또 다른 결함이 발생한다는 것이다. 이렇게 소스를 수정하는 과정에 추가로 유입된 결함을 파생결함이라고 한다.

소프트웨어가 인수테스트 단계나 유지보수 단계에 있다면 당연히 리그레션(회귀) 테스트를 하고 있을 것이다. 그리고 리그레션 테스트에서 발견한 결함을 수정하면서 소스 변경(유입)이 발생한다면 그로 인한 파생결함의 여지가 있으므로 필히 추가 리그레션 테스트를 수행해야만 한다.

만일 이 리그레션 테스트에서 또 다른 파생결함이 발견됐다면 그 결함을 수정해야 하고, 또 리그레션 테스트를 수행해야 한다. 파생결함이 계속 발생한다면 <그림 3>과 같은 상황이 무한 반복된다.

▲ <그림 3> 리그레션 테스트 무한 루프

소스 유입은 항상 파생결함의 위험에 노출될 수밖에 없고, 결함 수정은 당연히 소스 유입을 필요로 한다. 게다가 최근의 개발 트렌드가 ‘영원한 베타’이므로 지속적인 핫픽스나 업그레이드를 요구한다. 즉 끊임없는 소스 수정(유입)을 요구하고 있는 것이다. 이는 곧 끊임없는 파생결함의 위험에 노출돼 있다는 뜻이기도 하다.

소프트웨어의 규모가 방대할수록 이런 파생결함의 늪에 빠질 위험도 높아진다. 이런 경우는 아무리 테스트를 잘 해도 그 문제가 해결되지 않는 경우가 많다. 계속된 소스 수정은 스파게티코드를 만들게 되고, 파생결함의 범위와 강도가 갈수록 커지게 될 것이다. 이렇게 소스가 엉킨 상황이 되면 리그레션 테스트가 결함을 아무리 많이 발견해도 품질이 좋아지지 않는다. 이런 경우는 리그레션 테스트로 소프트웨어 품질을 높이는 것이 아니라 그 외의 활동이 필요하다. 보통은 소스를 리팩토링하거나 아예 재개발하는 것이 해결책이 되는 경우가 많다.

결론적으로 테스트에서 발견된 결함을 수정했다고 해서 품질이 높아진다는 생각은 버려야 한다. 항상 리그레션 테스트를 생각해야 하고 파생결함을 관리해야 한다. 리그레션 테스트는 결함을 발견하지 않아야 고품질의 소프트웨어를 보장할 수 있다. 리그레션 테스트에서 많은 결함을 발견했다면 수정할 결함을 미리 많이 발견했다고 좋아할 일이 아니다. 이때는 ‘리그레션 테스트 무한루프’의 징조인지를 검증해야 하는 경고불이 켜졌다고 판단해야 한다.

발견한 결함을 모두 수정할 수는 없다
고객(또는 경영진)은 ‘테스트를 한다’는 뜻을 ‘테스트에서 발견한 모든 결함을 수정한다’는 의미로 생각한다. 너무나도 당연한 말처럼 보인다. 하지만 개발자는 그렇게 생각하지 않는다. 개발자는 알면서도 어쩔 수 없이 수정하지 못하는 결함들이 있음을 알고 있다. 품질이 더 악화되는 것을 막기 위해서, 시간이 없어서, 또는 고객이 발견할 확률이 낮아서 등 여러 가지 이유로 발견한 결함을 모두 수정하지는 않는다는 뜻이다.

다음은 발견한 결함을 수정하지 못하는 몇 가지 사례이다.

● 테스트 비용에 수정공수를 감안하지 않으면 수정하지 못할 수 있다.

보통 테스트 일정은 소프트웨어 개발 라이프사이클에서 거의 마지막 단계다. 프로젝트의 막판에 가면 할당된 테스트 공수가 계획보다 짧아진 경우가 많다. 게다가 대부분의 테스트 공수는 결함수정 공수를 포함한다. 결함을 발견하기도 빡빡한 일정에 발견된 결함을 수정할 시간이 턱없이 부족할 수밖에 없다. 결국 결함을 수정하기보다는 결함을 보유한 기능 자체를 삭제하거나 결함을 우회하도록 기능을 변경하는 방법을 선택하게 된다. 또는 문제 해결을 위해 추가 인력을 투입하는 어려운 결정을 내리기도 한다.

▲ <그림 4> 계획보다 테스트 공수를 적게 사용하는 경우가 많다.

● 파생결함이 계속 발생하는 경우에 수정하지 못할 수 있다.

결함 수정 이후에 파생결함이 발생한다고 해서 파생결함이 완전히 없어질 때까지 리그레션 테스트를 무한 반복할 수는 없다. 왜냐하면 프로젝트 기간은 유한한데 파생결함이 계속 나오기 때문이다. 결국은 결함 수정이 아닌 다른 방법(예. 회의를 통해 고객과 협상)으로 우회하는 경우가 많다.

이런 경우 앞에서 얘기한 리그레션 테스트 무한루프에 빠질 확률이 높다. 이때는 결함을 수정해 봐야 파생결함이 또 나올 테니 수정하는 것이 의미 없게 된다.

● 기능 충돌로 수정하지 못할 수 있다.

요구사항이나 설계가 잘못돼 서로 모순된 기능을 요구할 수가 있다. 이 경우는 결함을 발견해도 고칠 수 없다. 예를 들어 자동문을 제어하는 소프트웨어에 다음과 같은 기능 설계가 정의됐다고 가정하자.

- 자동문 작동 제어 기능 설계
1) 출입자가 문 앞에 서면 센서가 사람을 인식하고, 자동으로 문을 열어준다.
2) 출입자가 문을 열기 위해서는 지문인식을 해서 신분을 확인해 줘야 한다.

이 경우 테스터가 문 앞에 섰는데 문이 자동으로 열리지 않는다면, ‘1)번 기능’에 대한 결함이 발생한 것이다. 하지만 이 결함을 수정할 경우 ‘2)번 기능’에 대해서는 결함이 된다. 왜냐하면 신분 확인도 하지 않았는데 자동으로 문이 열려버렸기 때문이다.

이런 상황에서는 결함을 수정하지 않고 설계서를 수정해야 한다. 설계나 요구사항에서 모순이 발생하면 단순히 모순된 문서만 수정한다고 해결되는 것이 아니라 시스템의 일부를 완전히 재개발하는 경우가 많다. 그리고 실제의 설계서나 요구사항 정의서는 위의 예시처럼 간단하지 않고 복잡하고 방대해서 그 모순된 부분이 설계/구현 단계에서는 발견되지 않고 테스트 단계에서 발견되는 경우가 종종 있다. 이러한 요구사항 모순의 발견은 개발자나 프로젝트 관리자에게는 재앙으로 여겨질 것이다. 물론 이 문제도 테스트로 해결할 수 있는 부분이 아니다.

● 수정 비용이 너무 높아서 수정하지 않을 수 있다.

‘빙산의 일각’이라는 말이 있다. 결함도 그런 거물급들이 있다. 겉으로 보기에는 평범한 결함으로 보이는데, 이 결함을 수정하려면 시스템 전체를 건드려야 하는 경우가 있다.

▲ <그림 5> 겉으로 보기에는 평범한 결함이지만 실제로 수정할 분량은 많은 경우도 존재한다.

특히 아키텍처 설계의 실수로 인해 발생한 결함은 알면서도 그 수정 범위가 너무 넓어서 수정하지 못하는 경우가 많다. 프로젝트 종반부에 바닥부터 다시 개발할 수는 없지 않은가?

그러나 대한민국의 위대한 개발자들은 정해진 기간 내에 기어이 수정하는데 성공한다. 항상은 아니지만 그런 경우가 허다하다. 이처럼 어렵게 짧은 시간에 전체 시스템을 수정하는 경우 파생결함으로 인한 리그레션 테스트 무한루프에 빠지기 쉽다. 왜냐하면 그 소스가 정교하게 수정되기가 어렵기 때문이다.

가장 좋은 방법은 이런 결함을 유입시키지 않는 것이다. 그래서 아키텍처 설계 시 다양한 방법(또는 뷰)으로 미리 검증을 해야 한다. 물론 아키텍처가 단순해 바닥 프레임이 정교할 필요가 없는 소프트웨어를 개발한다면 이 부분은 걱정하지 않아도 된다.

품질 향상에 실효가 있었던 활동들
이번에는 실제로 소프트웨어 품질을 높였던 활동들을 언급하고자 한다. 물론 테스트를 배제하지는 않았다. 당연히 테스트도 잘 해야 한다. 단지 좋은 테스트 방법들은 이미 많이 알려졌기 때문에 여기서는 언급을 적게 했을 뿐이다.

● 품질 목표를 설정한다.

무결점의 제품이 좋은 제품인가? 그렇지 않다. 무결점 제품을 위해서는 제품 개발에 엄청난 비용이 투입돼야 한다. 즉 제품개발비가 높아진다는 뜻이다. 이런 비용과 품질의 연관관계에 대한 이론은 품질 관련 업종의 종사자라면 누구나 알고 있을 것이다.

▲ <그림 6> 시간과 비용, 품질이 균형을 이루는 적정 품질을 찾아야 한다.

그런데 그 이론을 알고 있으면서도 실제 품질 업무에 적용하는 경우를 별로 본 적이 없다. 대부분 시간, 비용과 품질이 균형을 이루는 적정 품질을 찾는 작업을 하지 않고 무조건 고품질만을 목표로 하고 있기 때문이다.

비용, 품질, 시간이 서로 균형이 맞아서 회사에 최대 이익을 챙겨주는 적정품질을 ‘품질 목표’라고 한다. 소프트웨어를 개발하는 업체는 각 소프트웨어에 맞는 품질목표를 갖고 있어야 한다. 그래야만 허용하는 결함과 허용하지 않는 결함을 구분할 수 있다. 그리고 결과적으로는 적절한 품질 비용을 책정할 수 있게 된다.

만약 ‘일단 팔고 보자’가 회사의 제품 전략이라면 품질목표는 아주 낮을 것이고, 품질비용(요구관리, 설계, 형상관리, 개발자동화, 테스트 등)을 최대한 적게 쓸 것이다. 당연히 품질이 낮은 소프트웨어 제품이 나오겠지만 그렇다고 해서 나쁜 소프트웨어라고 보기 어렵다. 왜냐하면 그 소프트웨어의 품질목표는 원래 낮았기 때문이다. 일단 팔기만 한다면 그 소프트웨어의 목표는 달성한 셈이다.

제품의 품질을 높인다고 무턱대고 테스터를 뽑는 것은 잘못된 품질 전략이다. 품질 목표를 먼저 설정한 후에 이를 달성하기 위한 활동들을 나열하고, 그 활동에 필요한 자원(하드웨어, 소프트웨어 또는 작업자)을 구매하거나 뽑는 것이 올바른 수순이다.

품질 목표를 설정하는 가장 간단한 방법은 ISO 9126의 품질 특성을 활용하는 것이다. 품질 특성을 모두 나열한 이후에 회사의 제품 전략을 기반으로 핵심 품질 특성들을 선정하고, 그 품질 특성에 맞는 활동을 정하면 된다. 그렇게 한다면 무턱대고 테스터만 뽑는 오류를 범하지 않을 것이다.

모바일과 데스크톱 통합용 일정관리 앱(App)을 개발한다고 가정해보자. 예를 든 것이므로 실제와 다르겠지만 다양한 모바일 환경과 PC에서 작동해야 할 테니 다양한 환경의 설치 가능성이 매우 중요할 것이다. 또한 앱스토어를 통해 지속적으로 애플리케이션을 업그레이드해야 하므로 하위버전 호환성을 중요하게 여길 것이다. 대중을 위한 애플리케이션인 만큼 별도의 매뉴얼 없이도 직관적으로 사용법을 이해할 수 있어야 할 것 같다. 물론 기능의 정확성이나 적합성, 신뢰성, 효율성 등 모든 품질 요소가 중요하겠지만, 제품 전략에 맞게 중요한 요소들을 품질 목표를 세워야 할 것이다.

이번에는 ‘다양한 환경에서의 설치성’, ‘하위 호환성’, ‘학습성’을 우선시하는 품질 목표를 세웠다고 가정해보자. 다양한 환경을 지원하기 위해서는 모든 OS 버전에서 통용되는 표준을 준수해 구현하는 것이 중요할 것이다. 특정 OS에서만 작동하도록 개발한다면 다른 OS에서 작동을 안 할 수도 있으니, 가급적이면 표준기술만을 사용해야 할 것이다. 이를 위해 사전에 표준기술에 대한 검토를 해야 할 것이다.

하위호환성은 소스에 대한 버전관리, 형상관리가 중요할 것이다. 그리고 학습성을 높이기 위해서는 철저하게 고객의 사용 패턴을 연구한 후에 요구사항 개발을 해야 할 것이다.

이렇게 품질 목표를 설정하고 그에 맞는 핵심 활동을 규정하면 어느 활동에 집중해야 하는지를 알 수 있게 된다. 이번 예에서는 ‘다양한 환경에 작동하는 표준기술 검토’, ‘사용패턴 연구 및 요구사항 개발’, ‘버전관리’, ‘형상관리’가 중요한 활동이 됐고, 여기에 맞는 툴과 장비를 도입하고 인력을 구성하면 된다. 다시 한 번 강조하지만 품질을 높인다고 무턱대고 테스터를 뽑는 것은 좋은 방법이 아니다.

요구사항 및 결함 추적 전산시스템을 구축한다
제품 품질에 있어서 요구사항 및 결함의 추적성을 확보하는 것은 매우 중요하다. 요구사항 및 결함의 추적은 그 내용들을 추적표에 기술하고, 산출물(주로 소스)에 적용됐는지를 확인하는 표 형태로 관리한다. 하지만 장기간의 신규개발 또는 유지보수 단계에 들어선 상태라면 일반 표 형태의 관리보다는 더 효과적이고 효율적인 관리가 필요하다. 왜냐하면 요구사항이나 결함의 기록을 누락하는 경우가 자주 발생하기 때문이다.

개발 기간이 긴 신규개발의 경우는 오랜 설계/구현/테스트 기간을 거치는 동안에 요구사항이나 결함의 내용을 잊거나 내용이 바뀌어서 추적표에 누락되는 경우가 많다. 유지보수의 경우는 고객이 불편사항에 대해 해소시간을 짧게 주기 때문에 요구사항 추적표의 기록을 무시하고 일단 코딩부터 하게 되는 경우가 많다. 그 이후부터는 요구사항 및 결함 추적이 엉망이 돼서 제품의 형상관리, 버전관리가 점점 엉키게 되고, 결과적으로 파생결함을 발생시키기 시작한다. 그때쯤 되면 유지보수 비용이 갈수록 늘어나면서 제품의 품질은 점점 나빠지게 된다.

▲ <그림 7> 요구사항 및 결함의 추적 관리는 개발 기간 내내 해야 한다.

그러므로 장기간의 신규개발 또는 유지보수 시에는 요구사항과 결함의 추적을 전산시스템에 관리하는 것이 좋다. 개발자는 요구사항 및 결함처리를 위한 코딩에 집중하면서 최소의 노력만으로 기록하고 추적하게 할 수 있어야 하고, 형상 및 버전관리가 자동으로 돼서 형상이 엉키거나 누락되는 문제를 사전에 방지해줘야 한다. 이를 수기로 처리한다면 장기간의 프로젝트나 유지보수 기간에 긴급한 요구사항 또는 결함이 발생할 때 개발자는 시간의 제약으로 인해 기록을 누락할 수밖에 없다. 그리고 이러한 누락은 또 다른 파생결함을 야기하게 된다.

그러므로 요구사항(결함 포함) 도출-분석-설계-구현-단위테스트-제품통합-통합테스트-빌드-인수테스트-버전관리-배포로 이어지는 전 과정에서 그 추적을 전산화해 자동으로 관리하는 것이 좋다.

또한 유지보수 단계에 들어가면 고객은 불편사항이 결함인지 요구사항인지 구분하지 못하는 경우가 많다. 대부분의 고객은 결함이라고 생각하지만, 그 내용을 분석해보면 요구사항(추가기능 요청)인 경우가 많다. 그러므로 불편사항을 분석해 요구사항과 결함을 분류하고, 그 분석 결과를 고객과 협의하는 역할을 수행하는 전담 부서를 두는 것이 좋다.

결함 수정여부의 기준을 수립한다
테스트로 발견한 결함을 모두 수정해야 할까? 그렇지 않다. 어떤 개발자도 무결한 소프트웨어를 개발할 수 있다고 생각하지 않는다. 또한 비록 테스트를 통해 결함을 발견했다 하더라도 수정하지 않고 놔두는 것이 낫다고 판단하는 경우도 있다.

예를 들어 프로젝트 종료 후 운영 단계에서 발생한 결함에 대해, 해당 결함을 수정한 이후 풀테스트나 리그레션 테스트를 할 수 없는 상황이라면 차라리 수정하지 않는 것으로 결정할 수 있다.

만일 제품을 개발하고 주기적으로 패치 버전을 제공하는 경우라면 수정여부를 결정해야 하는 상황이 더욱 자주 발생하게 된다. 패치 버전 배포시기에 임박해 파생결함이 발생했다면 배포시기 엄수를 위해 이 결함을 수정할 것이지 말지를 고민할 수밖에 없기 때문이다. 이런 경우에 수정 여부 판단을 신속하게 하고자 이를 결정하는 기준을 미리 갖고 있으면 좋다.

물론 결정할 때마다 리스크 분석을 하면 좋겠지만 패치 버전을 빈번하게 제공해야 하는 경우는 리스크 분석을 매번 하기 어렵다. 이에 대비해 판단기준을 미리 만들어 놓으면 좀 더 빠른 판단을 내릴 수가 있다. 예를 들어 <표 1>과 같은 지침을 만들어 놓고, 이 지침으로 판단하기 어려운 상황이 발생했을 경우만 리스크 분석을 통해 결정하는 것을 권장한다.

▲ <표 1> 수정 여부 결정 기준

빌드 및 소프트웨어 통합 자동시스템을 구축한다
결함은 사람의 실수(에러)에 의해서 유입된다. 그런데 이런 실수는 코딩할 때만 발생하는 것이 아니다. 요구사항 분석 및 개발, 설계, 구현, 테스트 등 전 과정에서 실수가 있을 수 있으며, 의외로 아주 소소한 부분에서의 실수가 큰 결함으로 확대되는 경우가 있다. 이 부분이 빌드 및 소프트웨어 통합(패키징) 부분이다.

한 예로 빌드 시 잘못된 소스로 빌드하거나 잘못된 라이브러리를 엮는 경우, 코딩상의 어떤 실수도 하지 않았는데 엄청난 결함이 유입되는 경우가 종종 발생한다. 만일 빌드 및 소프트웨어 통합 담당자의 실수로 소프트웨어가 시작부터 비정상 동작한다면 다행스러운 일이다. 왜냐하면 문제를 바로 발견할 수 있어서 빌드를 다시 하면 그만이기 때문이다.

하지만 미세한 결함이 유입되거나 속도가 느려지거나 메모리가 서서히 증가하는 결함이 유입된다면 쉽게 발견하지 못해 그냥 배포할 수가 있다. 이런 경우는 나중에 큰 문제가 될 뿐만 아니라 결함의 원인을 찾기도 어렵다. 나중에 결함 위치를 소스 내에서 찾을 것이 분명한데 코딩 실수를 한 것도 아니기 때문이다.

특히 시스템을 오픈하거나 제품을 출시하는 시점에 임박하면 마지막 결함수정과 기능수정으로 인해 빌드를 자주하는 시점이 도래하게 된다. 그럴 때 테스트 기간에는 정상적으로 빌드를 하다가 마지막 순간에 빌드 실수나 소프트웨어 통합 실수를 하는 경우가 종종 있다. 제품에 대해서 주기적으로 패치 버전을 제공하는 경우는 이런 위험에 더욱 노출돼 있다고 볼 수 있다.

이런 경우는 아예 빌드 및 소프트웨어 통합을 자동화하는 것이 좋다. 자동화 시스템을 구축하는 것은 왠지 낭비처럼 보일 수도 있지만 개발 기간이 길수록 또는 유지보수 기간이 길거나 테스트 기간이 길수록 그 효과를 톡톡히 보게 된다.

사람의 실수는 코딩이나 설계에서만 발생하는 것이 아님을 명심해야 한다. 또한 자동화를 통해 피할 수 있는 실수(에러)라면 가능한 자동화시켜 결함의 유입을 방지하는 것이 좋다.

매뉴얼 자동 생성 시스템 구축한다
소프트웨어 제품을 사용하는 고객은 제품이 매뉴얼과 다르게 동작하면 결함으로 간주한다. 너무나도 당연한 명제다. 그런데 개발 산출물 중에서 소스는 엄격하게 형상관리를 하면서 매뉴얼은 그렇게 하지 않는다. 실제로 매뉴얼 형상관리는 소스 형상관리보다 훨씬 비용이 저렴한데도 이를 소홀히 함으로써 소프트웨어 제품 자체의 품질을 떨어뜨리는 경우가 있다.

해외로 수출하는 제품의 경우 매뉴얼의 중요성이 더욱 강조된다. 한국은 대체로 고객들이 매뉴얼을 꼼꼼히 읽지는 않지만, 일본의 경우는 매뉴얼을 거의 정독한다고 봐도 무방하다. 그러니 매뉴얼의 품질도 매우 중요하므로 사람에 의한 실수(에러)를 최대한 막을 수 있도록 매뉴얼 작성을 자동화하는 것이 좋다.

매뉴얼 중에는 그 설명의 구성 요소가 동일한 것들이 많다. ‘화면 설명서’나 ‘Reference Guide Manual’처럼 구성 요소가 동일하고 그 내용만 서로 다르면서 물리적인 양이 엄청 많은 매뉴얼들이 있다. 이런 경우 개발을 종료한 이후에 매뉴얼을 작성하는 것보다 개발을 진행하면서 개발자가 직접 매뉴얼을 작성하는 것이 좋다. 그래야만 누락 없이 매뉴얼을 제대로 작성할 수 있다. 개발이 종료되면 방대한 기능들을 제대로 기억하기도 쉽지 않고, 글만 쓰는 작업이 너무 지루하고 힘들어서 대충 쓰게 된다.

문제는 개발자에게 코딩(또는 설계)하면서 글을 쓰라고 하면 절대로 말을 듣지 않는다는 것이다. 이공계 출신들에게 글을 쓰라고 하면 그들은 재앙처럼 받아들인다. 또한 코딩에 심취한 개발자는 당연히 매뉴얼 작성을 뒤로 미루게 된다. 생산성이 좋은 개발자일수록 그런 성향이 더 강하다. 그들에게 억지로 매뉴얼을 쓰게 하기 보다는 최소한의 내용만 기술해도 나머지는 알아서 완성시켜주는 매뉴얼 생성 자동 시스템을 제공해 주는 것이 좋다.

‘화면 설명서’의 경우라면 입력 및 출력 값들만 DB에 등록하면서 코딩하도록 유도하고, 이 입출력 값들을 이용해 HTML로 매뉴얼을 동적으로 생성하는 방법이 있을 것이다. 조금만 고민하면 패턴별로 매뉴얼 자동생성 시스템을 쉽게 개발할 수 있다. 비록 작가처럼 글을 멋지게 쓰기는 어렵겠지만 내용을 빼먹지 않고 정확하게 쓰게 될 것이다.

길목에서 테스트를 한다
삼국지에는 장비가 장판교에서 조조군을 홀로 막으면서 유비가 도주할 시간을 확보해주는 이야기가 나온다. 조조군을 결함이라고 간주한다면 이 결함들도 어딘가 지나가는 장판교가 있을 것이다. 만일 그 길목만 알아낼 수 있다면 적은 비용으로 중요한 결함들을 많이 잡아낼 수 있을 것이다.

그런데 실제로 잘 찾아보면 결함도 많이 발생하는 길목이 존재한다. 테스트를 많이 한다고 많은 결함을 찾아내는 것이 아니다. 테스트는 낚시와 같다. 물고기(결함)가 있을 만한 곳에서 낚시를 해야만 물고기(결함)를 많이 잡을 수 있다.

그렇다면 어디가 낚시 포인트일까? 이 포인트를 알아내기 위한 두 가지 방법이 있다. 첫 번째는 경험 기반으로 포인트를 아는 것이고, 두 번째는 구조 기반으로 포인트를 아는 것이다.

경험 기반은 동일 제품을 반복해서 테스트하는 경우에 능숙한 테스터가 경험을 토대로 결함이 발생할만한 포인트를 찾아내는 것이다. 구조 기반은 아키텍처 설계자나 핵심 개발자가 소프트웨어 아키텍처상의 약점들을 파악해서 그 포인트를 테스터에게 알려주는 것이다.

둘 다 중요한 방법이지만 대부분 경험 기반의 포인트 찾기를 많이 사용한다. 하지만 시스템이 커지고 코딩의 분량이 방대해질수록 결함이 발생하는 범위가 기하급수적으로 팽창하게 된다. 이런 경우는 구조기반으로 포인트를 찾아내는 것이 유리하다.

시스템이 방대해질수록 제품 테스트를 테스터에게만 맡길 것이 아니라, 아키텍처 설계자나 핵심 개발자가 합심해 결함 발생 포인트를 찾아야 한다. 이렇게 구현자와 테스터가 함께 구조 기반의 테스트 포인트를 찾아낼 때 그 테스트의 효과성과 효율성은 엄청나게 높아질 것이다.

품질 목표부터 설정해야
소프트웨어 품질을 높이기 위해서는 개발의 모든 단계에서 노력해야 한다. 테스트는 소프트웨어의 품질이 어떤지를 측정(확인)하는 센서일 뿐이다. 미세먼지 측정센서가 있다고 해서 공기가 깨끗해지지는 않는다. 공기청정기가 있어야 공기가 깨끗해진다. 테스트(미세먼지 측정센서)만이 아닌 실효 있는 활동(공기청정기)들을 해야만 소프트웨어 품질이 향상된다. 그런 활동들을 소프트웨어 공학에서 많이 알려주고 있지만, 실효성 있는 구체적인 방법들을 공유하는 경우는 많지 않다. 대부분이 테스트에 너무 심취해 있기 때문이기도 하다.

소프트웨어 품질을 높이기 위해 테스트에만 집중하는 시각에서 벗어나 보면 의외로 적은 비용으로도 큰 효과를 낼 수 있는 방안이 많이 보일 것이다. 우선 회사의 품질 목표부터 설정해 보기를 제안한다.



댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글 0
댓글쓰기
계정을 선택하시면 로그인·계정인증을 통해
댓글을 남기실 수 있습니다.