정환타 개발노트

[조대협 대용량 아키텍처] 소프트웨어 테스트 본문

DevOps

[조대협 대용량 아키텍처] 소프트웨어 테스트

JungHwanTa 2020. 1. 28. 14:33

소프트웨어 테스트

 

소프트웨어를 개발한다는 것은 프로그램 언어와 개발환경만 갖추어져 있다면 누구나 가능하다.

하지만 개발을 할 수 있는가 없는 가의 문제가 아닌, 개발된 소프트웨어가 제대로 된 기능을 하는가에 집중해야 한다.

예를들어 얼마나 제대로 작동을 하는지, 성능은 만족할 만 한지, 안정성과 확장성이 충분한지 이다.

 

따라서 위의 판단은 테스트를 통해서 검증을 할 수 있는데 기존의 전통적인 테스트 방식은 소프트웨어 개발이 종료된 후 출시 전에 테스팅을 하는 방식을 사용하였다. 하지만 문제점은 초기에 발견하여 해결 하는 것이 더 비용절감이 되고 효율적이기에

최근에는 개발 단계별로 테스트하는 방식을 사용하여 개발시에도 품질을 다듬어가는 개발 모델을 선호하고 있다.

 

테스트 모델

V-모델

V-모델은 폭포수 모델의 확장형으로 폭포수 모델의 개발 단계를 대칭으로하는 4가지 단계를 테스팅 모델로 정의하여 테스트 절차를 강화한 모델이다. 

 

https://ko.wikipedia.org/wiki/파일:V-model.JPG

 

V-모델은 좌측의 검증 영역과(폭포수 모델의 4단계) 개발이 된 시스템을 검수하는 영역 두가지로 나누어 진다.

 

죄측 부분에 대한 테스트를 검증이라고 하는데, 검증맞는 제품(Right Thing)을 만들고 있는가에 대한 것이고, 우측 부분 테스트인 검수제품을 맞게(Right way) 만들고 있는가이다.

 

검증 작업은 대부분 문서를 기반으로 이루어 진다. 실제로 작동하는 시스템이 아닌 문서와 같이 정적인 것을 활용하여 테스트를 하기에 정적 테스트라고 하며 검증작업에서 소스 코드, 설계 문서, 요구 사항 정의서와 같은 산출물이 나오게 된다.

 

검수 작업은 작동이 가능한 시스템 기반으로 테스트를 하기에 동적 테스트라고 하며, 좌측 내용에 대응하는 각 단계별로 검증을 진행한다. 단위 테스트로 진행을 하며 각 단계별로

  • 단위 테스트 단계 - 신뢰성 검증
  • 통합 테스트 단계 - 유효성 검증
  • 시스템 테스트 단계 - 설계에 대한 검증
  • 인수 테스트 단계 - 요구사항 만족도 검증

을 수행하게 된다.

 

테스트 환경

테스트 과정에서 중요하지만 가장 간과되기 쉬운 부분은 전용 테스트 환경을 구축하는 것이다.

일반적으로 테스트는 개발 환경에서 진행하거나 오픈 전 운영 환경에서 진행한다.

 

전통적인 폭포수 모델에서는 이 방법이 나쁘지 않으나, 에자일 방법론을 사용한다면 개발자와 테스트 엔지니어의 리소스 낭비를 줄이기 위해서 테스트 환경을 분리하여 운영하는 것이 효과적이다.

 

따라서 개발, 서비스 환경을 개발 환경, 테스트 환경, 실제 운영 환경 세 가지로 나누어 운영하는 것이 좋다.

이 세 가지환경은 물리적으로 분리하는 것이 좋은데, 그 이유는 독립적으로 분리되지 않는다면 하나의 환경에서 다른 환경에 영향을 줄 수 있기 때문에 각 기능에 영향을 줄 수 있다.

 

추가적으로 연동 시스템이 필요하다면 연동 시스템에 대한 테스트 환경을 따로 구성하여야 한다. 만약 개발 중이거나 배포가 불가능한 경우에는 목업(Mock-up)환경을 만들어 사용하는데, 목업 환경은 기존의 시스템과 같은 환경을 복제하여 특정 입력에 대해서 결과를 내도록 만들어진 테스트 전용 환경이다.

 

테스트 조직 구조

테스트를 수행하는 팀의 구조는 테스트 방법론, 개발 방법론에 따라 모두 차이가 있지만, 일반적으로 적용되어지는 테스트 조직 구조가 존재한다. 일반적인 구조의 각각 역할들은 중첩이 될 수 있으나 생략이 되면 안된다.

 

출처 : https://bcho.tistory.com/663

1. 테스트 팀(Test Team)

테스트를 계획하고 수행하는 팀.

 

  1. 테스트 리더(Test Leader)
    1. 전략 수립 및 테스트 방법론 정의
    2. 테스트 프로세스 정의
    3. 테스트 프로젝트 관리
    4. 다른 팀과의 의사소통
    5. 팀에 대한 교육
    6. 매트릭스(품질지표) 정의
  2. 테스트 디자이너(Test Designer)
    1. 요구사항 분석 및 테스트 요구사항 디자인
    2. 테스트 케이스 디자인
  3. 테스트 오퍼레이터(Test Operator)
    1. 테스트 케이스 구현
    2. 테스트 결과 문서화
    3. 결함 리포트
    4. 결함 추적
    5. 테스트 도구 세트업
  4. 테스트 환경 관리자(Test Environment Manager)
    1. 테스트 환경 세트업
    2. 테스트 중 환경 모니터링

2. 외부 지원팀

  1. 개발팀(DevelopmentTeam)
    1. 테스트 환경 세트업 지원
    2. 결함 수정
    3. 테스트 과정 모니터링
  2. 세스템 엔지니어(System Engineer)
    1. 모니터링 및 최적화

테스트 케이스의 우선순위 결정 방법

위험도 기반의 우선순위 결정

테스트 케이스의 우선순의를 결정하는 방법으로 위험도 기반의 우선순위 결정 방법이 있다. 위험도는 발생 가능성과 발생 시 심각도를 기반으로 도출해 낸다.

 

Rist[위험도] = Likelyhood[발생 가능성] * Impact[발생 시 심각도]

발생 가능성의 측정 : 소스 코드의 복잡도, 구현 난이도, 테스트 대상 기능의 구현 크기, 개발자의 수준 등을 통해 도출

 

 

이엏게 발생한 리스크를 기준으로 4개의 영역을 구분할 수 있다.

  • STA(Servere Test Area) : 발생 가능성 +, 발생시 타격 +
  • SSTA(Strong Test Area) : 발생 가능성 -, 발생시 타격 +
  • ITA(Inrensive Test Area) : 발생 가능성 +, 발생시 타격 -
  • FTA(Fundamental Test Area) : 발생 가능성 -, 발생시 타격 -

따라서 로우 레벨 테스트 단계인 단위와 통합 테스트는 STA -> ITA -> SSTA -> FTA 순으로 진행하는 것이 좋으며, (발생 가능성 큰 문제)

하이 레벨 테스트 단계 인 시스템 테스트와 인수 테스트에서는 STA -> SSTA -> ITA -> FTA 순으로 진행하는 것이 좋다. (타격이 큰 문제)

 

복잡도 기반의 우선순위 산출

코드의 복잡도가 높을수록 결함의 발생률도 올라간다. 따라서 코드의 복잡도를 순환 복잡도(Ctclomatic Complexity) 측정을 통해 코드의 복잡도를 측정할 수 있다. 순환 복잡도는 "분기 조건의 수 + 1"(if, while, witch 등)으로 계산된다.

분기 조건을 일일히 계산하기에는 어려움이 있기에 아래와 같은 순환 복잡도를 계산해주는 툴이 있다.

  • Cyvis : 그래프로 자바 코드의 복잡도를 계산, 분석
  • PMD : 코드 복잡도 계산 + 정적 분석 기능 포함

 

테스트 커버리지

테스트 커버리지는 테스트 대상의 전체 범위에서 테스트를 수행한 범위이다. 

 

테스트를 얼마나 수행했느냐를 나타내는 지표이고, 테스트 정확성의 지표가 될 수 있다.

분수로 표현하면 테스트 수행 범위 / 테스트 대상 전체 범위 로 나타낼 수 있는데 이 테스트 커버리지에서는 분수의 분모를 정하는 것이 가장 중요하다. 이 분모는 테스트의 범위를 무엇으로 측정할 것인가에 달려있다.

 

가장 쉬운 방법은 테스트 대상 기능을 분모로 정하는 방법이며 UI가 많은 시스템에서는 전체 화면 수를 분모로 사용할 수 있다.

하이 레벨 테스트인 시스템 테스트와 인수 테스트의 경우에는 기능이나 컴포넌트를 분모로 사용하는데, 기능 기반에는 테스트 커버리지를 100% 달성하는 것을 목표로 둔다.

 

라인 커버리지

로우레벨 테스트에서 단위 테스트의 경우 기능을 중심으로 테스트를 하는 것이 아니라 클래스와 메소드를 중심으로 테스트를 하기 때문에 기능 자체를 테스트 커버리지의 모수로 삼을 수 없다. 따라서 다음과 같은 분모를 사용하는 것이 일반적이다.

  • 테스트 대상 시스템의 전체 클래스 수
  • 테스트 대상 시스템의 전체 메소드 수
  • 테스트 대상 시스템의 전체 소스 코드 줄 수

전체 소스 코드 라인 수 대비, 테스트 시나리오가 거쳐가는 소스 코드의 라인수를 측정 한 것을 라인 커버리지라고 하는데, 단위 테스트에는 라인 커버리지를 척도로 삼는다.

 

고품질의 소프트웨어 개발팀에서는 라인 커버리지의 목표를 80%로 잡는다.

하지만 국내 환경에서는 현실적으로 전체 시스템중 40%를 중요 시스템으로 산정하여 이 시스템의 라인 커버리지를 80%로 잡는 것을 목표로 한다.

 

브렌치 커버리지

브렌치 커버리지는 분기 조건문에 대하여 테스트가 얼마나 커버하고 있는지를 나타내는 수지이다. 

간단히 두개의 중첩 if문에서 첫번 째 분기문의 2가지 경우와, 두번째 분기문의 2가지 경우를 합쳐 총 3가지의 경우의 수를 가져올 수 있다.

첫 번째 if 문 두 번째 if 문
True True
True False
False N/A

따라서 브렌치 커버리지의 분모의 수는 3이 된다. 하지만 복잡도가 너무 높기 떄문에 서버 어플리케이션에서는 왠만해서는 사용되지 않고 임베디드 시스템과 같은 소스코드가 작고 분기 조건이 중요한 시스템에서 주로 사용된다.

 

마이크로 벤치마크 테스트

마이크로 벤치마크는 소규모의 부하 테스트를 말한다.

소규모 부하에서 문제가 발생한다면 반대로 이야기해서 그 정도로 시스템의 완성도가 떨어진다는 것을 의미하기에 중대 결함이 발생될 경우가 대부분이다. 릴리즈된 시스템 뿐만 아니라 개발진행 중인 시스템에 대해 적용할 수 있으며 초기에 중대 결함을 찾기에 매우 유용하다.

 

마이크로 벤치마크 테스트는 소규모의 부하만 주면 되기 대문에 테스트의 비용이 적으며 오픈소스 부하 테스트 툴(SoapUI, Apache JMeter, nGrinderm Gatling) 또한 존재한다.

 

결함 관리 방법

결함 처리 프로세스

만약 결함이 발생하였다면 테스트 팀과 개발팀이 협업하여 해결하야 할 것 이다. 

결함을 처리하는 프로세스는 다음과 같다. 

 

  1. 결함 보고 : 테스트 팀에서 발견한 결함은 결함 관리 시스템에 기록됨
  2. 결함 접수 : 개발 팀에서는 자신의 팀에서 개발한 모듈에서 발생한 결함을 가지고 온다.
  3. 결함 지정 : 개발팀 리더는 결함을 개발팀의 일정, 리소스 등을 지정하며 결함을 개발자에게 할당한다.
  4. 결함 수정 : 결함을 할당 받은 개발자는 테스트 엔지니어와 함께 결함을 추적, 재현하여 수정한다.
  5. 결함 수정 확인과 테스트 케이스 추가 : 결함 수정 후, 결함을 검증하는 단위 테스트 케이스를 추가하고 수정된 코드와 테이트 케이스를 소스 관리 시스템에 저장한다.
  6. 결함 처리 상태를 '해결됨'으로 변경 : 결함 관리 시스템에 해당 결함 상태를 '해결됨'으로 변경한다.
  7. 확인 테스트 : 테스트 엔지니어는 해결된 결함을 다시 테스트한다.
  8. 결함 처리 종료 : 확인 테스트에서 문제가 없을 경우 해당 결함을 종료한다. 만일 문제 발생시에는 4번 단계부터 다시 반복한다.

결함 보고

위의 결함 처리 프로세스에서 결함 관리 시스템에 결함을 등록하고 관리 하였는데, 결함들에 대해 아래와 같은 항목을 적용하여 관리한다.

 

  1. Number : 결함의 번호
  2. Title : 결함의 제목(결함의 내용을 간단하게 정의)
  3. Description : 결함에 대한 자세한 내용을 서술, 어떠한 결함인지 결함 발생 상황 분석 내용 등을 같이 작성한다.
  4. Module : 결함이 발견 된 컴포넌트 혹은 모듈명
  5. Version & Fixed Version : 결함이 발견된 버전과 해당 결함이 해결된 버전, 결함은 버전에 따라 다르게 발생할 수 있기에 중요한 항목
  6. Servinity, Priority : 시간상으로 빨리 처리해야 하는 경우 시급도(Servinity)가 높은 것을 의미하며, 결함의 우선순위(Priority)는 위험도를 의미한다. 결함의 우선순위가 높을수록 중대 결함이 되며, 우선순위가 낮을수록 가벼운 결함을 의미한다.
  7. Status : 현재 결함이 처리되고 있는 상태를 기록한다.
  8. Fixed Code : 근래에는 소스 코드 관리 시스템 툴을 이용하여 사용 수정되기 이전의 소스코드와 수정 된 소스코드를 기록한다.
  9. Attachment : 결함을 기록할 때 첨부 파일을 사용한다. 첨부 파일에는 결함 발생 당시 로그, 데이터(CPU 사용률, 네트워크 상황), 결함을 추적할 때 사용된 코드 등을 첨부한다.

결함의 상태 정의

위의 결함 관리 시스템에 작성하는 Status에서 결함 처리 과정에 따라 상태를 정의하는데 아래와 같이 상태를 정의한다.

 

  1. New : 테스트 과정중 결함이 발생되어 결함 관리 시스템에 등록됨
  2. Opened : 등록된 결함이 개발자에게 넘어감
  3. Assigned : 결함이 수정할 개발자에게 할당됨
  4. NMI(Need More Information) : 추가 정보가 필요한 상태로 개발팀에세 결함에 대한 원인과 증상을 확인할 수 없을 때 추가 정보가 필요한 경우 테스트 팀에게 추가적안 로그 등 재현 절차를 다시 요구하는 상태
  5. In process : 개발자가 결함을 확인 후 수정 중인 단계
  6. Postponed : 결함 처리 과정 중 중요도가 낮거나 다른 결함 수정 일정에 따라 우선순위가 조정된 상태
  7. Resolved : 결함이 해결된 상태, 결함은 해결되었으나 테스트 팀에서 재테스트를 하지 않은 상태
  8. Closed : 테스트 팀에 의해 결함의 수정 내용 확인과 시스템에 소스 코드까지 반영된 상태

 

결함 관리 도구

위에서 우리는 결함에 대해 결함 관리 시스템에 기록하며 결함을 관리하였다. 일반적으로 결함을 관리하는 도구를 결함 관리 시스템이라고 하는데 버그 추적 시스템 혹은 이슈 관리 시스템이라고도 한다. 

 

대표적인 상용도구는 HP QC(Quality Center), IBM Clear Quest 등이 있다.

또한 JIRA를 활용하여 개발 프로세스 관리 뿐만 아니라 결함 추적에 대한 기능을 사용할 수 있다.

 

오픈소스 제품으로는 모질라의 Bugzilla, Trac, Mantis 등이 있다.

 

Comments