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