Coverage 모듈
Coverage 모듈
Coverage는 Ruby에 커버리지 측정 기능을 제공해요. 이 기능은 실험적이라 API가 앞으로 바뀔 수 있어요.
주의: 현재는 프로세스 전역 커버리지 측정만 지원돼요. 스레드별 커버리지는 측정할 수 없어요.
사용법
require "coverage"Coverage.start실행- Ruby 소스 파일을 require하거나 load
Coverage.result는 파일 이름을 키로, 커버리지 배열을 값으로 갖는 해시를 돌려줘요. 커버리지 배열은 각 줄에 대해 인터프리터가 그 줄을 몇 번 실행했는지를 보여줘요.nil값은 그 줄에 대해 커버리지가 비활성화되었음을 뜻해요(else나end같은 줄).
예시
[foo.rb]
s = 0
10.times do |x|
s += x
end
if s == 45
p :ok
else
p :ng
end
[EOF]
require "coverage"
Coverage.start
require "foo.rb"
p Coverage.result #=> {"foo.rb"=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}
출처: Ruby 3.3 API
본문
라인 커버리지 (Lines)
커버리지를 시작할 때 커버리지 모드를 명시하지 않으면 라인 커버리지가 실행돼요. 각 줄이 몇 번 실행됐는지를 보고해요.
require "coverage"
Coverage.start(lines: true)
require "foo.rb"
p Coverage.result #=> {"foo.rb"=>{:lines=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil]}}
라인 커버리지 결과 값은 각 줄이 실행된 횟수를 담은 배열이에요. 이 배열의 순서가 중요해요. 예를 들어 인덱스 0의 첫 항목은 파일 1번 줄이 커버리지 실행 동안 몇 번 실행됐는지를 알려줘요(이 예시에선 1번). nil 값은 커버리지가 비활성화된 줄(else, end 같은)을 뜻해요.
원샷 라인 커버리지 (Oneshot Lines)
원샷 라인 커버리지는 커버리지가 실행되는 동안 실행된 줄을 추적하고 보고해요. 줄이 몇 번 실행되었는지는 알려주지 않고, 실행되었는지 여부만 알려줘요.
require "coverage"
Coverage.start(oneshot_lines: true)
require "foo.rb"
p Coverage.result #=> {"foo.rb"=>{:oneshot_lines=>[1, 2, 3, 6, 7]}}
원샷 라인 커버리지 결과 값은 실행된 줄 번호를 담은 배열이에요.
브랜치 커버리지 (Branches)
브랜치 커버리지는 각 조건문 안의 각 분기가 몇 번 실행됐는지를 보고해요.
require "coverage"
Coverage.start(branches: true)
require "foo.rb"
p Coverage.result #=> {"foo.rb"=>{:branches=>{[:if, 0, 6, 0, 10, 3]=>{[:then, 1, 7, 2, 7, 7]=>1, [:else, 2, 9, 2, 9, 7]=>0}}}}
브랜치 해시의 각 항목은 하나의 조건문이고, 그 값은 그 조건문 안의 각 분기가 담긴 또 다른 해시예요. 값은 메서드가 실행된 횟수이고, 키는 분기를 식별하는 정보예요.
분기나 조건문을 식별하는 키를 이루는 정보는 왼쪽부터 다음과 같아요.
- 분기·조건문 타입의 라벨
- 고유 식별자
- 파일에서 그 부분이 나타나는 시작 줄 번호
- 파일에서 그 부분이 나타나는 시작 열 번호
- 파일에서 그 부분이 나타나는 끝 줄 번호
- 파일에서 그 부분이 나타나는 끝 열 번호
메서드 커버리지 (Methods)
메서드 커버리지는 각 메서드가 몇 번 실행됐는지를 보고해요.
[foo_method.rb]
class Greeter
def greet
"welcome!"
end
end
def hello
"Hi"
end
hello()
Greeter.new.greet()
[EOF]
require "coverage"
Coverage.start(methods: true)
require "foo_method.rb"
p Coverage.result #=> {"foo_method.rb"=>{:methods=>{[Object, :hello, 7, 0, 9, 3]=>1, [Greeter, :greet, 2, 2, 4, 5]=>1}}}
메서드 해시의 각 항목은 하나의 메서드를 나타내요. 값은 메서드가 실행된 횟수이고, 키는 메서드를 식별하는 정보예요.
메서드를 식별하는 키를 이루는 정보는 왼쪽부터 다음과 같아요.
- 클래스
- 메서드 이름
- 파일에서 메서드가 나타나는 시작 줄 번호
- 파일에서 메서드가 나타나는 시작 열 번호
- 파일에서 메서드가 나타나는 끝 줄 번호
- 파일에서 메서드가 나타나는 끝 열 번호
모든 커버리지 모드 (All)
이 단축키로 모든 커버리지 모드를 동시에 실행할 수도 있어요. 모든 모드를 실행해도 라인 커버리지와 원샷 라인 커버리지는 동시에 실행되지 않아요. 이 두 모드는 동시에 실행할 수 없거든요. 이 경우 라인 커버리지가 실행되는데, 줄이 실행되었는지 여부를 여전히 알 수 있기 때문이에요.
require "coverage"
Coverage.start(:all)
require "foo.rb"
p Coverage.result #=> {"foo.rb"=>{:lines=>[1, 1, 10, nil, nil, 1, 1, nil, 0, nil], :branches=>{[:if, 0, 6, 0, 10, 3]=>{[:then, 1, 7, 2, 7, 7]=>1, [:else, 2, 9, 2, 9, 7]=>0}}, :methods=>{}}}
클래스 메서드
line_stub(file)— 파일의 각 줄에 대해 커버리지 값 자리가 마련된 배열을 만들어요.peek_result → hash— 파일 이름을 키로, 커버리지 배열을 값으로 갖는 해시를 돌려줘요.Coverage.result(stop: false, clear: false)와 같아요.result(stop: true, clear: true) → hash— 파일 이름을 키로, 커버리지 배열을 값으로 갖는 해시를 돌려줘요.clear가 true면 카운터를 0으로 지우고,stop이 true면 커버리지 측정을 비활성화해요.resume → nil— 커버리지 측정을 시작/재개해요. 주의: 현재는 프로세스 전역 측정만 지원해서 멀티 스레드 프로세스에서 특정 코드 블록의 커버리지를 잡으려고Coverage.resume/suspend를 쓰면 결과가 오해를 부를 수 있어요.running? → bool— 커버리지 측정이 현재 진행 중인지(true) 아닌지(false)를 돌려줘요(Coverage.start호출 후Coverage.result호출 전).setup → nil,setup(:all) → nil,setup(lines:bool, branches:bool, methods:bool, eval:bool) → nil,setup(oneshot_lines: true) → nil— 커버리지 측정을 설정해요. 이 메서드는 측정 자체를 시작하지는 않아요. 측정을 시작하려면Coverage.resume을 쓰세요. 설정과 시작을 함께 하려면Coverage.start를 쓰면 돼요.start → nil,start(:all) → nil, ... — 커버리지 측정을 활성화해요.Coverage.setup과Coverage.resume을 합친 것과 같아요.state → :idle, :suspended, :running— 커버리지 측정의 상태를 돌려줘요.supported?(mode) → true or false— 주어진 모드에 대해 커버리지 측정이 지원되면 true를 돌려줘요. 모드는:lines,:oneshot_lines,:branches,:methods,:eval중 하나여야 해요. 예:Coverage.supported?(:lines) #=> true,Coverage.supported?(:all) #=> falsesuspend → nil— 커버리지 측정을 일시 중지해요.Coverage.resume으로 다시 시작할 수 있어요.