목차
Rails와 GitHub Actions에 커버리지 레포트를 달아보자
이 블로그의 CMS이기도 한 Shiori를 대폭 리팩토링하면서 테스트가 얼마나 잘 작성되어있는지 궁금해졌습니다.
💡 이 글은 작성된지 1년 이상 지났습니다. 정보글의 경우 최신 내용이 아닐 수 있음에 유의해주세요.
앞으로도 종종 궁금할 일이 있을테니, 이참에 아예 CI 수준에서 커버리지 레포트를 달아보기로 했습니다.
Codecov와 같은 무료로 사용 가능한 상용 서비스도 존재합니다. 그러나 Codecov는 프라이빗 레포지토리를 포함한 소스 코드 및 시크릿 정보 등의 사용자 정보가 유출된 사고가 터진 바 있습니다.
개인 프로젝트야 큰 영향이 없겠지만, 만약 회사 프로젝트였다면 어떤 영향이 생겼을지 상상하기 어렵습니다. 때문에 조금 번거롭더라도 모든 행위가 통제 가능한 영역에 있는 오픈 소스 프로젝트를 사용하기로 했습니다.
우선 아래와 같이 의존성을 추가, 설치합니다.
# Gemfile
gem "simplecov"
gem "simplecov-lcov"
LCOV는 리눅스에서 사용하는 커버리지 정보를 담는 포맷입니다. Ruby 혹은 Rails에 의존적이지 않기 때문에 다른 언어에서도 동일하게 플러그인을 사용할 수 있다는 장점이 있죠.
이후 spec_helper.rb
혹은 그에 준하는 파일에 다음을 추가합니다.
# spec/spec_helper.rb
require "simplecov"
require "simplecov-lcov"
SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::LcovFormatter,
])
SimpleCov.start "rails" do
add_filter "/spec/"
end
LCOV 파일은 프로그램을 위한 포맷이기 때문에 사람이 읽기 어렵습니다. 때문에 HTMLFormatter를 함께 설정하여 브라우저를 통해 확인할 수 있도록 하였습니다.
또한 SimpleCov가 소스 코드를 파악할 수 있도록 Rails 코드가 로드되기 전에 설정되어야 한다는 점에 주의해야합니다. 때문에 웬만하면 spec_helper.rb
의 최상단에 추가하는 것이 좋습니다.
위와 같이 설정한 후 테스트를 한 바퀴 돌려봅시다.
$ bundle exec rspec
................................................................
Finished in 1.34 seconds (files took 1.53 seconds to load)
64 examples, 0 failures
Coverage report generated for RSpec to ./coverage. 520 / 706 LOC (73.65%) covered.
Lcov style coverage report generated for RSpec to ./coverage/lcov/shiori.lcov
간단하게 73.65% 라는 커버리지가 표시되고, 커버리지 레포트 파일이 생성되었음을 볼 수 있습니다. 생성된 coverage/index.html
파일을 열어서 구체적인 커버리지를 시각적으로 확인할 수도 있습니다.
브라우저에서 커버리지 레포트를 확인하는 화면
각 분기에 대한 커버리지가 표현된 화면
생성된 LCOV 파일을 통해 GitHub의 pull request에 커버리지가 보고되도록 설정해봅시다. 다행히도 LCOV 파일을 읽어 보고해주는 오픈 소스 액션은 여럿 존재합니다.
name: Run tests
on: [ push, pull_request ]
jobs:
test:
# ... 설정 과정은 프로젝트마다 다양하므로 생략
steps:
- uses: actions/checkout@v2
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: 3.2
bundler-cache: true
- name: Run tests
run: |
bundle exec rails db:migrate
bundle exec rspec
- name: Report coverage
if: ${{ github.event_name == 'pull_request' }}
uses: romeovs/[email protected]
with:
# 아래 파일 이름은 프로젝트의 설정에 따라 달라집니다.
lcov-file: ./coverage/lcov/project_name.lcov
여기서는 if 조건을 통해 pull request에서만 댓글이 달리도록 하였습니다. 만약 해당 조건이 없다면 각 커밋 단위로 커버리지 레포트를 측정할 수도 있습니다.
커버리지가 NaN으로 표시되는 모습
오류는 발생하지 않았지만 커버리지가 NaN%로 보고되는 문제가 있었습니다. 이는 simplecov-lcov gem이, lcov-reporter-action이 사용하는 "LH", "LF" 정보를 출력하지 않기 때문입니다.
이를 해결하기 위한 PR을 누군가 생성해놓은 상태이며, 해당 PR이 머지되기 전까지는 simplecov-lcov를 포크 레포지토리를 지정하여 사용할 수 있습니다.
# Gemfile
gem "simplecov-lcov", require: false, github: "t-mario-y/simplecov-lcov", branch: "feature/write-LF-LH"
최종적으로 아래와 같이 커버리지 레포트가 잘 생성된 것을 확인할 수 있습니다.
커버리지가 정상적으로 표시되는 모습
관련된 글
Rails Global ID로 전역 객체 식별하기
Global ID는 Rails의 모든 객체를 식별할 수 있는 URI(Uniform Resource Identifier)입니다.
Ruby on WebAssembly: 살짝 맛보기
Ruby 3.2에 추가된 WebAssembly 지원을 간단하게 테스트해봅시다.
Ruby의 and와 &&는 다르다
Ruby로 프로그램을 짜다보면 반드시 밟게되는 지뢰가 있습니다. 바로 or 과 ||, 혹은 and 와 && 연산자의 우선순위가 달라서 발생하는 일입니다.
본 사이트의 저작물은 별도의 언급이 없는 한 크리에이티브 커먼즈 저작자표시-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
LYnLab, 2011 - 2024.
작성한 댓글은 giscus를 통해 GitHub Discussion에 저장됩니다.