출제기준 세세항목: 결함관리 도구 · 테스트 자동화 도구 · 통합 테스트
단위 테스트를 모두 통과한 모듈들을 합쳤는데 프로그램이 제대로 돌지 않는 일은 생각보다 흔합니다. 각 모듈은 혼자서는 정확했지만, 서로 주고받는 방식에서 어긋남이 생기기 때문입니다. 한쪽은 금액을 원 단위로 넘기는데 다른 쪽은 천 원 단위로 받는다거나, 날짜 형식이 다르다거나, 호출 순서를 서로 다르게 기대하는 경우입니다.
통합 테스트는 이런 모듈 사이의 경계, 즉 인터페이스에서 생기는 결함을 찾는 테스트입니다. 단위 테스트가 부품 하나하나를 검사하는 일이라면, 통합 테스트는 부품을 조립하면서 맞물리는 부분이 잘 맞는지 확인하는 일입니다. 이 항목에서는 통합하는 방법, 그 과정을 돕는 자동화 도구, 그리고 찾은 결함을 관리하는 방법과 도구를 차례로 봅니다.
통합 방식은 크게 두 갈래입니다. 빅뱅(Big Bang) 통합은 모든 모듈을 한 번에 합쳐 놓고 전체를 테스트하는 비점진적 방식입니다. 준비가 간단해 작은 프로그램에는 쓸 만하지만, 문제가 생기면 어느 모듈 사이에서 생겼는지 찾기가 매우 어렵습니다. 수십 개의 전선을 한꺼번에 연결하고 전원을 켰는데 불이 안 들어오는 상황과 비슷합니다.
점진적 통합은 모듈을 하나 또는 몇 개씩 붙여 가며 그때마다 테스트하는 방식입니다. 새로 붙인 부분에서 문제가 생기면 원인이 바로 그 근처에 있으므로 찾기 쉽습니다. 어느 쪽부터 붙여 가느냐에 따라 하향식, 상향식, 그리고 둘을 섞은 샌드위치 방식으로 나뉩니다.
모듈을 하나 새로 붙일 때마다, 이미 잘 되던 부분이 새 모듈 때문에 망가지지 않았는지도 다시 확인해야 합니다. 이렇게 앞서 통과한 테스트를 다시 돌려 보는 것을 회귀 테스트라고 하며, 점진적 통합에서는 회귀 테스트가 자연스럽게 함께 따라옵니다.
하향식 통합은 프로그램 구조의 맨 위, 즉 메인 제어 모듈부터 시작해 아래쪽 모듈을 차례로 붙여 내려가는 방식입니다. 위에서부터 붙이다 보니 상위 모듈이 부를 하위 모듈이 아직 없는 경우가 생깁니다. 이때 진짜 하위 모듈 대신 정해진 값만 돌려주는 임시 모듈을 끼워 넣는데, 이것이 스텁(Stub)입니다. 아래로 붙여 가는 순서에 따라, 한 가지 줄기를 끝까지 먼저 내려가는 깊이 우선 방식과 같은 층을 먼저 다 채우는 너비 우선 방식이 있습니다. 전체 흐름의 골격을 일찍 볼 수 있다는 장점이 있습니다.
상향식 통합은 반대로 맨 아래의 하위 모듈부터 시작해 위로 붙여 올라가는 방식입니다. 하위 모듈은 이미 있으니 스텁은 필요 없지만, 그 하위 모듈을 불러 줄 상위 모듈이 아직 없습니다. 그래서 테스트 데이터를 넣어 하위 모듈을 호출하고 결과를 받아 주는 임시 모듈을 만드는데, 이것이 드라이버(Driver)입니다. 하위 모듈 몇 개를 하나의 기능 묶음(클러스터)으로 모아 드라이버로 테스트한 뒤, 드라이버를 걷어 내고 진짜 상위 모듈과 합치는 식으로 진행합니다.
헷갈리지 않으려면 '없는 쪽을 대신한다'고 생각하면 됩니다. 하향식에서는 아래가 없으니 아래를 흉내 내는 스텁을, 상향식에서는 위가 없으니 위를 흉내 내는 드라이버를 씁니다. 스텁은 불려지는 쪽, 드라이버는 부르는 쪽을 대신합니다.
샌드위치(혼합식) 통합은 상위 부분은 하향식으로, 하위 부분은 상향식으로 동시에 진행해 가운데에서 만나는 방식입니다. 두 방식의 장점을 함께 얻을 수 있지만, 스텁과 드라이버를 모두 만들어야 해서 준비할 것이 많습니다. 규모가 큰 프로젝트에서 주로 씁니다.
통합 과정에서는 같은 테스트를 몇 번이고 다시 돌려야 합니다. 모듈을 붙일 때마다 회귀 테스트를 손으로 반복하면 시간도 오래 걸리고 사람이 실수하기 쉽습니다. 테스트 자동화 도구는 이런 반복 작업을 도구가 맡게 해, 빠르고 늘 같은 방식으로 테스트를 수행하게 해 줍니다. 대신 도구를 익히고 자동화 스크립트를 만들고 유지하는 데 비용이 들며, 사람이 직접 봐야 아는 사용 편의성 같은 부분까지 대신해 주지는 못합니다.
도구는 맡는 일에 따라 나눠 볼 수 있습니다. 정적 분석 도구는 프로그램을 실행하지 않고 소스코드를 읽어 코딩 규칙 위반이나 결함 가능성이 있는 부분을 찾습니다. 테스트 실행 도구는 미리 작성한 스크립트대로 테스트를 자동으로 실행합니다. 스크립트에 테스트 데이터를 따로 분리해 두고 데이터만 바꿔 가며 반복하는 데이터 주도 방식과, 동작을 나타내는 키워드를 정해 두고 그 조합으로 테스트를 짜는 키워드 주도 방식이 있습니다.
성능 테스트 도구는 가상의 사용자를 많이 만들어 시스템에 부하를 주고, 응답 시간이나 처리량, 자원 사용률을 측정합니다. 테스트 통제 도구는 테스트 계획과 관리, 테스트 케이스 관리, 결함 관리처럼 테스트 활동 전체를 관리하는 도구입니다.
테스트 하네스(Test Harness)는 테스트를 실행할 수 있는 환경을 갖춰 주는 도구와 데이터의 묶음을 말합니다. 앞에서 본 드라이버와 스텁이 여기에 들어가고, 테스트 케이스, 여러 케이스를 묶은 테스트 슈트(Test Suite), 실행 절차를 적은 테스트 스크립트, 그리고 사용자의 행위나 다른 객체의 동작을 미리 정해 둔 대로 흉내 내는 목 오브젝트(Mock Object)도 구성 요소로 꼽힙니다.
구체적인 도구 이름도 몇 가지 알아 두면 좋습니다. JUnit은 자바 단위 테스트 프레임워크이고, 이처럼 언어별로 만들어진 단위 테스트 프레임워크들을 통틀어 xUnit이라고 부릅니다. Selenium은 웹 브라우저를 자동으로 조작하며 웹 애플리케이션을 테스트하는 도구입니다. FitNesse는 위키 형태의 웹 화면에 표로 테스트를 작성하고 실행하는 도구입니다.
테스트에서 쓰는 말을 먼저 구분해 두겠습니다. 사람이 저지른 실수를 오류(Error)라고 하고, 그 실수 때문에 코드나 문서 안에 남은 잘못된 부분을 결함(Defect, Fault)이라고 하며, 결함이 실행 중에 드러나 기대와 다른 결과가 나오는 것을 실패(Failure)라고 합니다. 오류가 결함을 낳고, 결함이 실행되면 실패로 나타난다는 순서입니다. 넓은 의미로는 기대와 다른 동작 전반을 결함이라고 부르기도 합니다.
결함은 발견했다고 끝이 아닙니다. 같은 결함을 두 사람이 따로 고치거나, 고쳤다고 했는데 실제로는 안 고쳐진 채 출시되는 일을 막으려면 흐름을 정해 관리해야 합니다. 보통 결함 관리 계획을 세운 뒤, 결함을 발견하면 기록하고, 검토해서 분류하고 담당자를 정하며, 담당자가 수정하고, 테스트 담당자가 다시 시험해 고쳐졌는지 재확인합니다. 그동안 결함들의 처리 상태를 계속 추적·모니터링하고, 테스트가 끝나면 남은 결함과 처리 결과를 최종 분석해 보고서로 정리합니다. 이 과정에서 결함은 신규로 등록되어 담당자에게 할당되고, 수정된 뒤 확인을 거쳐 종료되는 식으로 상태가 바뀌며, 지금 고치지 않기로 한 결함은 보류 상태로 남깁니다.
결함을 기록할 때는 심각도와 우선순위를 따로 매깁니다. 심각도는 결함이 시스템에 미치는 영향이 얼마나 큰가이고, 우선순위는 얼마나 빨리 고쳐야 하는가입니다. 둘은 다를 수 있습니다. 회사 로고 철자가 틀린 것은 시스템을 멈추게 하지 않으니 심각도는 낮지만, 첫 화면에 바로 보이니 우선순위는 높을 수 있습니다.
모인 결함 기록은 분석에도 쓰입니다. 결함이 어느 모듈에 몰려 있는지 보는 결함 분포, 시간에 따라 발견·수정되는 결함 수가 어떻게 변하는지 보는 결함 추세, 결함이 등록된 뒤 해결되지 않고 얼마나 오래 머물러 있는지 보는 결함 에이징이 대표적입니다. 이를 보면 어디를 더 집중해서 테스트해야 할지, 출시해도 될 만큼 안정되었는지를 판단할 수 있습니다.
결함을 엑셀 파일이나 메신저로 관리하면 누가 무엇을 맡았는지, 지금 어떤 상태인지 금방 뒤죽박죽이 됩니다. 결함관리 도구는 결함 하나하나를 등록하고, 담당자를 지정하고, 상태 변화를 기록하며, 관련된 사람에게 알림을 보내는 일을 한 곳에서 처리해 줍니다. 이슈 추적 도구 또는 버그 추적 도구라고도 부릅니다.
대표적인 도구를 알아 두겠습니다. Mantis는 웹 기반의 버그 추적 도구로, 결함을 등록하고 상태를 추적하는 데 초점을 둔 비교적 가벼운 도구입니다. Trac은 결함 추적에 위키와 일정 관리 기능을 더하고, 버전관리 도구와 연결해 어떤 커밋이 어떤 결함을 고쳤는지 함께 볼 수 있게 한 도구입니다. Redmine은 결함 추적과 함께 일정·문서·위키 등 프로젝트 관리 기능을 폭넓게 갖춘 웹 기반 도구로, 여러 프로젝트를 한꺼번에 관리할 수 있습니다.
Bugzilla는 모질라(Mozilla) 프로젝트에서 만들어 지금은 모질라 재단이 관리하는 오래된 버그 추적 도구이고, Jira는 아틀라시안(Atlassian)의 상용 도구로 결함뿐 아니라 업무 전반을 이슈 단위로 관리하는 데 널리 쓰입니다. 어느 도구든 핵심은 같습니다. 결함마다 고유 번호를 주고, 앞에서 본 관리 흐름에 따라 상태를 바꿔 가며, 그 이력을 모두 남기는 것입니다.
주문 화면부터 위에서 아래로 통합하고 있는데 결제 모듈은 아직 개발 중입니다. 그래서 어떤 요청이 와도 '결제 성공'만 돌려주는 스텁을 대신 붙여 주문 흐름을 먼저 테스트했습니다. 나중에 진짜 결제 모듈이 완성되면 스텁을 빼고 교체한 뒤, 이전에 돌린 테스트를 다시 실행해 문제가 없는지 확인합니다.
아래에서 위로 통합하는 프로젝트에서 세금 계산 모듈이 먼저 완성되었지만, 이 모듈을 부를 정산 화면은 아직 없습니다. 그래서 여러 금액을 차례로 넣어 세금 계산 모듈을 호출하고 결과를 기대값과 비교하는 드라이버를 만들어 테스트했습니다.
테스트 담당자가 '쿠폰을 두 장 쓰면 할인이 두 번 적용된다'는 결함을 도구에 등록했습니다. 팀장이 검토해 심각도 높음, 우선순위 높음으로 분류하고 개발자에게 할당했습니다. 개발자가 고친 뒤 상태를 바꾸자 테스트 담당자에게 알림이 갔고, 담당자가 다시 시험해 고쳐진 것을 확인하고 종료했습니다. 이 모든 과정이 도구에 이력으로 남았습니다.