Amazon Web Services 한국 블로그

AWS CodeBuild Report를 통한 UnitTest 및 Code Coverage 시각화

유닛테스트는 모듈의 기능을 테스트 할 수 있는 작은 단위의 효과적인 테스트입니다. 하나의 소프트웨어는 여러개의 모듈로 이루어져있으며 유닛테스트는 이런 각각의 모듈이 정상적으로 기능을 수행하는지 시험할 수 있는 최소 수준의 시험단위를 뜻합니다. AWS CodeBuild에서는 유닛테스트와 코드 커버리지의 결과를 시각화하여 리포트로 받아볼 수 있습니다. 덕분에 CI/CD 파이프라인의 일부로서 CodeBuild 를 보다 효과적으로 활용할 수 있게 되었습니다.

CodeBuild 보고서가 지원하는 테스트 보고서 파일 형식은 다음과 같습니다.

  • Cucumber JSON
  • JUnit XML
  • NUnit XML
  • NUnit3 XML
  • TestNG XML
  • Visual Studio TRX

샘플 코드는 https://github.com/aws-samples/amazon-cicd-concurrency-sample-application.git 을 사용하였습니다. HashMap의 동시성 이슈를 가지고 있으며 테스트를 위해 Junit으로 유닛테스트를 수행하고 있습니다. 또한 얼마나 많은 범위를 테스트하고 있는지 Jacoco를 이용해 코드 커버리지를 측정하고 있습니다. 해당 유닛테스트와 코드 커버리지 도구에 대한 정보는 Junit, Jacoco를 검색해보세요.

먼저 유닛테스트 보고서를 만들기위해 보고서의 결과 경로를 buildspec에 추가한 후 CodeBuild Report에서 리포트 그룹을 생성합니다.

1. 오른쪽 Build 탭의 Report groups를 선택합니다. 그리고 오른쪽 상단의 Create report group을 선택합니다.

2. Report group configuration의 Report group name에 보고서 이름 Concurrency-Unittest-Report 를 입력합니다. 결과를 s3에 저장하려면 Amazon S3로 내보내기를 체크하고 S3 버킷 이름을 입력합니다. 테스트 결과 데이터를 zip 파일로 압축를 체크하면 S3에 Zip 형태로 저장합니다. Report type은 Test를 선택합니다.

3. Report groups에서 Concurrency-Unittest-Report를 선택합니다.

4. 이제 이곳에 수행한 유닛테스트의 결과가 보여질 것입니다. 보고서 그룹을 CodeBuild가 알 수 있도록 구성의 Report group ARN의 내용을 복사합니다.

5. 복사한 ARN을 BuildSpec의 reports에 붙여 넣습니다. 그리고 base-directory에 유닛테스트의 생성 경로를 입력합니다.

reports:
  <YOUR-REPORT-GROUP-ARN>:
    files:
      - '**/*'
    base-directory: 'build/test-results/test'

6. 유닛테스트 리포트가 적용된 buildspec.yaml의 내용은 아래와 같습니다.

version: 0.2

phases:
  install:
    runtime-versions:
      java: corretto11
    commands:
      - java -version
      - gradle -version
  build:
    commands:
      - ./gradlew clean build
reports:
  <YOUR-REPORT-GROUP-ARN>:
    files:
      - '**/*'
    base-directory: 'build/test-results/test'
artifacts:
  files:
    - '**/*'
  name: concurrencysample-$(date +%Y-%m-%d)

7. 코드 커버리지의 결과 시각화도 buildspec.yaml을 이용하여 쉽게 할 수 있습니다. 또한 테스트가 얼마나 충분한지 확인하여 테스트를 통과시킬 수도 있고 실패시킬 수도 있습니다. UnitTest의 보고서를 생성한 방법과 동일한 순서로 보고서 그룹을 작성합니다. 이름은 Concurrency-Coverage-Report 로 입력합니다. Report type은 Code Coverage를 선택합니다.

8. 동일하게 생성된 Concurrency-Coverage-Report Report groups의 ARN을 복사하여 <Coverage-REPORT-GROUP-ARN>을 교체합니다.

reports:
  <Coverage-REPORT-GROUP-ARN>:
    files:
      - 'build/jacoco_report/test/jacocoTestReport.xml'
    file-format: 'JACOCOXML'

9. buildspec.yml의 최종 내용은 아래와 같습니다.

version: 0.2

phases:
  install:
    runtime-versions:
      java: corretto11
    commands:
      - java -version
      - gradle -version
  build:
    commands:
      - ./gradlew clean build
reports:
  <YOUR-REPORT-GROUP-ARN>:
    files:
      - '**/*'
    base-directory: 'build/test-results/test'
  <Coverage-REPORT-GROUP-ARN>:
    files:
      - 'build/jacoco_report/test/jacocoTestReport.xml'
    file-format: 'JACOCOXML'
artifacts:
  files:
    - '**/*'
  name: concurrencysample-$(date +%Y-%m-%d)

10. 이제 CodeBuild에서 빌드를 수행하면 아래와 같이 tail log에서 유닛테스트가 수행된 결과를 볼 수 있습니다. 13개의 테스트 중 2개가 실패하였습니다. 더 자세한 내용을 보기위해선 build 폴더에 생성된 보고서 파일을 보실 수 있습니다. 하지만 이전에 연동한 CodeBuild 보고서를 이용하면 빌드별 결과를 손쉽게 확인하실 수 있습니다.

11. 보고서 그룹으로 가서 업로드된 보고서를 확인하겠습니다. 코드빌드 콘솔의 왼쪽메뉴에서 Report groups를 선택합니다. 그리고 앞에서 만든 Cuncurrency-Unittest-Report를 선택합니다.

12. 성공실패와 수행시간을 그래프로 볼 수 있고 하단의 reports history의 report를 누르시면 UnitTest의 세부사항을 보실 수 있습니다.


13. 이제 시각화한 코드 커버리지 리포트를 확인하겠습니다. 이전과 같이 왼쪽 Build 메뉴의 Report groups를 선택합니다. 그리고 앞에서 만든 Concurrency-Coverage-Report를 선택합니다.

14. 이곳에서는 현재 수행된 테스트가 얼마나 충분한지 보고서도 확인할 수 있습니다. Line별 Branch별 커버리지 트렌드를 확인할 수 있습니다.

15. build.gradle을 수정하여 일정 커버리지를 넘지 못하면 빌드를 실패 시킬 수도 있습니다.  (현재는 20%만 넘겨도 통과하게 설정되어 있습니다.)

유닛테스트의 결과와 코드 커버리지의 결과를 시각화하여 문제를 더 빠르게 파악할 수 있습니다. 또한 지금 업로드된 코드의 테스트 결과 뿐만아니라 지난 테스트와의 트렌드를 한눈에 알아볼 수 있습니다. 개발자들은 이런 기능을 이용하여 현재 코드의 테스트 결과는 물론, 지금까지의 테스트 기록을 통해 코드에 대한 다양한 통찰력을 확보할 수 있습니다. 이는 AWS CodeGuru나 CodePipeline등과 함께 사용되어 고품질의 코드를 유지하는데 많은 도움을 줄 수 있습니다.

코드품질 향상을 위한 코드품질 향상을 위한 AWS CI/CD pipeline with CodeGuru & UnitTest에 대한 자세한 워크샵은 이곳에서 추가로 확인하실 수 있습니다.

– 강세용, AWS 솔루션즈 아키텍트