본문 바로가기

기술

소프트웨어 품질 향상을 위한 소프트웨어 개발환경 구축


2002년부터 소프트웨어 개발자로써 경력을 쌓아오면서 소프트웨어를 잘 개발하는 것보다 소프트웨어의 품질을 유지하고 효과적으로 배포하는 것에 더 큰 어려움을 느껴왔다. 올해는 특히 스타트업을 설립하면서 이러한 어려움이 더욱 표면으로 드러나기 시작했다. 산업체에 근무할 때에는 소프트웨어의 품질을 유지하고 운영하는 별도의 인력이나 팀이 존재했었기 때문에 비교적 손쉬울 수 있었으나, 인력이나 자금면으로 제한이 큰 스타트업에서는 직접적인 어려움으로 다가올 수 밖에 없었다. 소프트웨어를 개발하는 노력에 더불어 품질 유지와 운영의 노력까지 적은 인원이 감당해야 했기 때문이다. 이미 성숙한 기업들에 비해 소프트웨어의 규모가 좀 더 작을지라도 이러한 노력의 크기는 그에 비례하여 줄어들지 않기 때문에 품질 유지운영에 필요한 노력의 크기를 줄이는 것은 스타트업이 조금 더 적은 인력으로 조금 더 빨리 고객들의 요구사항을 제품에 반영할 수 있는 여유가 생긴다는 점에서 중요할 수 있다.



소프트웨어의 품질은 작은 관점에서는 소프트웨어를 잘 테스트하고 발견된 오류를 잘 수정하여 오류가 적은 소프트웨어를 만드는 것이며, 큰 관점에서는 소프트웨어가 사용자의 요구사항을 지속적이고 연속적으로 잘 반영하여 좋은 사용자 경험을 갖는 소프트웨어를 만드는 것이라 생각한다. 특히 스타트업이 성공하기 위한 요건으로써 사용자의 의견을 빠르게 반영하는 것도 중요한 요소라는 점에서 수시로 소프트웨어가 변경되더라도 일정한 품질을 유질할 수 있도록 하는 개발 프로세스를 마련하는 것이 필요하다. 특히 소프트웨어는 국소적인 변경이 일어나더라도 그 영향 범위를 쉽게 추정할 수 없어 매번 전체 테스트를 반복해야 한다는 점 때문에 소프트웨어의 요구사항을 관리하고 새로운 요구사항이 반영된 소프트웨어를 자동으로 테스트해줄 수 있는 방법이 필요하다. 그림 1은 일반적인 소프트웨어의 개발 프로세스를 보여주고 있다. 작은 관점에서의 방법은 검증 단계에 적용될 수 있으며, 큰 관점에서의 방법은 전체 개발 프로세스에 적용될 수 있다.
우리는 위에서 언급한 문제를 해결하기 위해 나름의 작은 프로세스를 구축하였으며, 이를 활용해 매일 업무를 진행하고 있다. 다양한 해결 방법 중 하나의 사례로써 가벼운 마음으로 소개하고자 한다. 또한 우리가 구축한 프로세스를 앞으로 어떻게 개선할 것이지에 대해서도  소개하고자 한다. 


우리 프로세스의 궁극적인 목적은 새로운 요구사항이 반영된 새 버전의 소프트웨어를 즉각적이고 자동화된 방법으로 사용할 수 있도록 하여 소프트웨어의 품질을 높일 수 있게 하는 것이며, 표 1은 이러한 목적을 달성하기 위해 우리가 이루어야 하는 목표를 소개하고 있다. 현재 산업에서는 표 1에서 제시한 각각의 문제를 해결하는 다양한 솔루션이 존재한다. 우리는 이러한 여러 가지 솔루션들을 이용해보면서 가장 우리의 입맛에 맞는 것들을 선택했다. 그리고 전체의 문제는 하나의 제품으로 해결할 수 없기 때문에 각각의 작은 문제를 해결하는 여러 솔루션들을 결합하여 전체 문제를 해결할 수 밖에 없다. 이로 인해 여러 솔루션을 번갈아 오가며 작업을 진행하는 것은 효과적이지 않을 수 있다. 따라서 이러한 각각의 솔루션을 최대한 하나의 개발 환경에 집중시킴으로써 프로세스의 효율성을 높이는데 중점을 두었다. 

1. 소프트웨어의 요구사항을 효과적으로 관리할 수 있을 것
2. 소프트웨어의 테스트와 통합 빌드를 자동으로 수행할 수 있을 것
3. 소프트웨어를 자동으로 운영 환경에 배포할 것

우리는 위에서 제시한 각각의 목표를 달성하여 소프트웨어 품질을 효과적으로 유지할 수 있는 소프트웨어 개발 프로세스를 만들기 위해  그림 2와 같이 솔루션들을 선정하고 구성하였다. JetBrains 사의 IntelliJ는 Java를 기반으로 하는 소프트웨어를 개발하기 위한 통합 개발환경으로써 현재는 자바 이외에도 다양한 프로그래밍 언어를 지원한다. 자바 진영의 가장 대표적인 개발환경인 이클립스에 비해 좀 더 가벼웠고, UI가 직관적이서 IntelliJ 를 이용하고 있다. 우리는 우리 프로세스의 대쉬보드로써 IntelliJ를 이용할 수 있도록 설정하였다. 개발자들은 JIRA나 Bamboo를 이용하기 위해 웹 브라우저를 이용할 필요 없이 IntelliJ안에서 모든 것을 볼 수 있다. 


Bitbucket 무료로 사용할 있는 Git Repository 서비스이며 GitHub 유사하다. 그러나 Bitbucket GitHub와는 다르게 무료로 Private Repository 사용할 있다. Atlassian Bamboos Continuous Integration (CI) 툴로써 여러 개발자가 개발한 소프트웨어의 소스코드가 지속적으로 통합되어 테스트되고 빌드될 있도록 지원한다. JIRA Issue Tracking Tool로써 소프트웨어의 이슈 (버그, 기능, ) 등록하고 진행 상황을 관리할 있도록 도와준다. 소프트웨어 이슈 뿐만 아니라 요구사항 등도 관리할 있다.  마지막으로 Docker 복잡한 소프트웨어의 배포 과정을 단순화시켜준다. 소프트웨어와 소프트웨어를 구동하기 위한 복잡한 설정 과정을 Container 불리는 블랙박스로 만들고 배포하기 때문에 모든 과정이 단순해진다. 위에 설명한 모든 시스템은 Google Cloud 환경 위에 구축되고  운영되고 있다. 스타트업에게 있어서 클라우드는 직접 서버를 구축할 필요가 없고, 비교적 저렴한 가격에 손쉽게 서버를 확장할 있다는 점에서 매력적인 도구이다.

여러 명의 개발자들은 위의 프로세스를 따라 개발을 진행한다. 개발자가 IntelliJ 상에서 개발하고 소스 코드를 Git Commit & Push한다. Bamboo 새로운 소스 코드가 Git Commit 마다 자동으로 이를 Pull하고 스스로 컴파일, 빌드, 테스트를 진행한다. 그리고 수행 결과는 JIRA 연동되어 나타나며, 동시에 개발자들에게 이메일로 통보된다. 테스트가 완료되면 자동으로 Docker 이용해 소프트웨어를 배포하며, 때부터 버전의 소프트웨어를 바로 사용할 있게 된다.

새로운 소스 코드가 Git 제출될 마다 소프트웨어의 기능 테스트가 자동으로 수행되며, 결과는 이메일로 리포팅된다. 개발자들은 통합된 소프트웨어의 품질 결과를 곧바로 있으며, 무엇이 문제인지 신속히 파악할 있게 된다. 무엇보다 지루한 테스팅 과정과 통합 과정을 사람이 매번 하지 않아도 되기 때문에 편리하다.


목표1 소프트웨어의 요구사항의 관리

스타트업에게 있어서 중요한 활동중에 하나는 사용자들의 피드백을 수집하고 분석하여 요구사항을 도출하고 이를 매우 빠르게 반영하는 것이라 생각한다. 분석 과정에서 수많은 요구사항이 도출될 있으며, 모든 욕구사항은 한번에 반영될 없다. 그러므로 어떤 버전에서 어떤 요구사항을 반영할지를 계획하는 것이 필요하다. 이러한 요구사항을 관리하고 계획할 있도록 돕는 많은 훌륭한 솔루션이 있다. 그러나 우리는 이미 소프트웨어의 버그, 개발 내용 일정 등의 이슈를 관리하기 위해 JIRA 사용하고 있기 때문에, 요구사항 역시 JIRA 이용해 관리한다면 매우 편리할 것이라 판단했다.

우리는 새로운 이슈 타입으로써 요구사항 정의하였고, 여기에 어떤 버전에서 개발할 것인지를 기술하였다. 그림 3 이러한 과정을 보여주고 있다. ‘요구사항 1’ 새로운 요구사항으로 등록하면서 Alpha 버전에서 개발하는 것으로 표시하였다.




이렇게 각각의 요구사항을 등록하고나면 JIRA 이슈 검색 기능을 이용해 어떤 버전에서 어떤 요구사항을 구현해야하는지를 쉽게 파악할 있다. 또한 요구사항의 구현을 위해 개발자에게 할당하려는 경우 새로운 이슈를 등록하는 번거로움 없이 요구사항의 이슈 타입을 변경하거나 복제하고서 담당자를 설정함으로써 바로 할당할 있다.

부가적으로 IntelliJ JIRA 통합되어 자신에게 할당 이슈를 기반으로 작업을 진행할 있게 해주며, 이슈별로 투입한 시간을 자동으로 측정해준다. 이렇게 측정된 시간은 JIRA 기록되어 어떤 기능을 구현하기 위해 얼마만큼의 시간을 투여했는지를 확인해볼 있다.

 

목표 2 소프트웨어 테스트와 통합 빌드의 자동화

여러 개발자가 참여하는 소프트웨어 프로젝트에서 어려운점 하나는 개발자들이 작성한 소스 코드를 통합하는 것이며, 통합된 소프트웨어를 테스트하는 것이다. 이러한 활동을 단순화 하고 최대한 자동화하기 위해서 우리는 Gradle 도입했다.  Gradle 자바를 위한 빌드 시스템으로써 단순히 소스 코드를 컴파일 하는 것을 넘어서 빌드된 소프트웨어를 테스팅해주고 결과 보고서를 생성하는 등의 표준적인 소프트웨어 빌드 절차를 정의할 있도록 해준다. 비록 Ant Maven 같은 툴들이 널리 사용되고 있지만, 우리는 Gradle 제공하는 DSL 이용해 우리가 원하는 소프트웨어 빌드 프로세스를 정의할 있다는 때문에 Gradle 표준적인 빌드 시스템으로 사용하게 되었다.

Bamboo Ant Maven 기본적으로 통합된다. 그러나 Gradle 만들어진 소프트웨어를 통합하기 위해서는 유료 플러그인 추가적으로 설치해야만 한다. 하지만 우리는 이를 이용하지 않고, 직접 Gradle 빌드 시스템을 호출함으로써 통합하였다.

Bamboo 이용하려면 먼저 빌드 태스크를 정의해야 한다. 그림 4 우리가 정의한 기본적인 기본적인 빌드 태스크를 보여주고 있다. 왼쪽은 태스크들의 실행 순서를 나타내며, 오른쪽은 태스크의 상세 설정 화면이다. 기본적으로Source Code Checkout 태스크를 이용해 소스 코드를 Git으로부터 가져오며, Gradle Build 태스크를 이용해 소스 코드를 빌드한다. Script location Inline으로 설정해주고 아래의 그림처럼 스크립트를 입력한다. Gradle 빌드를 수행하기 위해서는 gradlew파일을 실행하면서 인자로 build 명령어를 주면 된다. Build 소프트웨어 빌드 과정의 모든 절차 (Build-Assemble-Testing) 모두 수행하도록 하는 명령어다. 빌드 과정의 마지막에서 JUnit 이용해 자동으로 테스트가 수행된다. 마지막으로 Docker 이용한 태스크들은 목표3 테스트 프트웨어의 자동 배포 운영에서 설명한다.



빌드가 성공하거나 실패하면 이에 대한 리포트가 생성된다. Bamboo JUnit Parser 이용해 리포트를 분석하고, 필요한 정보를 가져온다. 만약 빌드가 실패했을 경우에는 무엇이 실패했는지에 대한 정보를 수집하며, 이를 개발자에게 알려준다. 현재 우리는 Git 새로운 소스 코드가 Commit 마다 이와 같은 과정을 반복한다. 그러나 이러한 정책은 프로젝트의 규모에 따라 적당하지 않을 있다. 그러므로 특정 시간에 빌드가 수행 되도록 하거나, 언제든지 수동으로 빌드를 수행할 수도 있다. 이러한 설정을 이용하면 모든 직원이 퇴근한 새벽 시간에 자동으로 빌드가 수행되고, 결과가 전달될 있어 편리하다.

목표3 테스트 프트웨어의 자동 배포 운영

모든 소프트웨어의 테스트를 자동화하는 것은 불가능하다.  Bamboo 의해 자동으로 수행된 테스트는 Unit 테스트라 불리는 기본적인 기능 테스트이며, 테스트에 통과하였다고 해도 소프트웨어에 오류가 없음을 보장할 없다. 단순한 테스트를 넘어 소프트웨어의 사용 시나리오를 기반으로 통합 테스트를 진행해야 한다. 이를 위해서는 버전의 소프트웨어가 실제로 구동되어야 하며, 테스터에 의해 바로 접속 가능해야 한다.

소프트웨어를 Docker 이용해 배포하려면 먼저 Dockerfile이란 것을 작성해야 한다. Dockerfile 소프트웨어가 어떻게 설정되고 배포되어야 하는지를 기술하는 스크립트이며, Docker 이를 이용해 소프트웨어를 실행하기 위한 모든 요소를 포함하고 있는 Self-Contained 이미지를 만든다. 그림 5 Docker 이미지를 만들기 위한 설정을 보여주고 있다.




소프트웨어를 실행하고 운영해야 하는 사람은 소프트웨어를 설치하거나 복잡한 설정 과정 없이 단순히 이미지를 실행함으로써 격리 환경에서 소프트웨어를 구동할 있다. Docker 이러한 특성은 격리된 환경에서 언제나 깨끗한 테스트가 가능하도록 해준다. 나아가 Dockerfile 소프트웨어를 실행하기 위한 복잡한 설정을 이미지 안에 숨겨줌으로써 소프트웨어의 내부에 대한 이해가 없더라도 소프트웨어를 운영하는 사람이 손쉽게 소프트웨어를 구동하고 관리할 있도록 해준다. 여러 사람이 만든 소프트웨어가 서로 연동되는 경우 다른 사람이 개발한 소프트웨어를 실행하기 위해 소프트웨어의 설정을 모두 이해하고 스스로 적용할 있어야만 하는 어려움이 있지만, Docker 이러한 어려움을 제거하여 비교적 쉽게 소프트웨어를 운영, 테스트 있도록 돕는다. 그림 5 이미지 빌드 스크립트가 실행되고나면 이미지가 Registry 등록된다. Registry 도커 이미지를 저장하고 있는 Repository로써 Docker 특정 소프트웨어의  설치를 위해 Registry 검색하고 등록된 이미지를 가져온다. Docker Docker Hub[1]라는 Public Registry 무료로 운영하고 있으며, 조직이 Private Registry 구축할 있도록 도와주고 있다. 물론 Registry 등록하지 않고도 Docker 이미지를 빌드하고 실행할 있다. 그림 6 빌드 이미지를 실행하는 과정이다. Docker 입력 파라마터에 따라 이미지를 실행한다. 시점부터 사용자들은 버전의 소프트웨어를 즉각 사용할 있게 된다.





기대효과


위와 같은 프로세스를 적용함으로써 우리는 빠르게 새로운 요구사항을 적용하고 결과를 모니터링 있었다. 또한 소프트웨어의 빌드, 테스트, 배포, 운영 등을 최대한 자동화함으로써 소요되는 시간과 노력을 최대한 줄이고, 대신 소프트웨어의 통합 테스트 유저 시나리오 기반의 테스트에 많은 시간을 할애할 있게 함으로써 나은 품질의 소프트웨어를 만들 있도록 하였다.

또한 JIRA 통해 요구사항과 소프트웨어의 이슈들을 체계적으로 관리함으로써 프로젝트의 진행 상황을 쉽게 모니터링하고 문제를 식별하고 대응할 있었으며, 개발자가 이슈들을 처리하는데 얼마나 많은 시간을 투자하고 있는지를 파악하여 비효율을 제거할 있었다. 나아가 JIRA Bamboo 개발환경에 통합함으로써 중앙 집중화된 관리가 가능하게 하였다.

마지막으로 Docker 사용해 테스트 환경을 구축함으로써 깨끗한 환경에서 테스트를 진행할 있도록 하여, 테스트의 결과의 일관성과 테스트의 품질을 확보하였다. 또한 소프트웨어를 실행하기 위한 복잡한 설정을 Docker 이미지 내로 숨김으로써 테스트 가용성을 높일 있었다.




프로세스는 지속적으로 개선되고 보완되어야 한다. 특히 소프트웨어 개발 프로세스의 효과는 프로세스를 사용하는 사람들에 의해 결정된다는 때문에, 구성원의 특성에 맞도록 지속적으로 보완될 필요성이 있다. 우리는 우리의 프로세스가 나은 품질 향상과 넓은 테스트 가능성을 확보해줄 있도록 하기 위해 노력하고 있다.

소프트웨어 나은 품질의 확보

단순히 소프트웨어의 기능 테스트를 통해 소프트웨어의 품질을 향상시켜주는 방법 이외에도 정적 분석 기법을 통해 소스 코드에 숨어있는 결함을 찾아내거나 Git 제출 소스 코드를 여러 사람이 리뷰할 있도록 함으로써 품질을 향상 시킬 있다. 대표적인 정적 분석 툴로는 FindBug, PMD, Checkstyle, SonarQube 등이 있으며, 우리는 SonarQube 프로세스에 통합하기 위해 작업을 진행하고 있다. 또한 코드 리뷰 툴로는 Crucible, Upsource 등이 있다.

넓은 테스트 가능성 확보

우리는 여러가지 운영체제와 모바일 환경에서 작업을 진행하고 있으며, 사용하는 프로그래밍 언어 또한 다양하다. Bamboo 다양한 플랫폼에서 동작하는 Build Agent 관리해준다. 테스트를 워하는 환경에 Build Agent 설치해줌으로써 Linux 소프트웨어는 Linux에서, Windows 소프트웨어는 Windows에서 테스트를 있다. 여러 개의 서버 컴퓨터가 필요한데, 클라우드 환경에서 여러 개의 컴퓨터를 관리하기 위해 Vagrant 같은 Provisioning Tool 도입할 필요가 있다.


'기술' 카테고리의 다른 글

Self-Adaptive Software  (0) 2013.02.20