見出し画像

カバレッジが高ければいいわけじゃないってどゆこと?

ソフトウェアテストの文脈でユニットテストのカバレッジだけを指標にすればいいわけじゃない、むやみに上げればいいわけじゃないというのをチラホラ聞きます。
が、「無理にカバレッジをあげる必要は無いのかぁ」と思うもののなんだか釈然としません。
果たしてこれがどういうことなのかを僕なりに考えて言語化してみました。

カバレッジとは

コード網羅率(コードもうらりつ、英: Code coverage、コードカバレッジ)は、ソフトウェアテストで用いられる尺度の1つである。プログラムのソースコードがテストされた割合を意味する。この場合のテストはコードを見ながら行うもので、ホワイトボックステストに分類される。
https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%BC%E3%83%89%E7%B6%B2%E7%BE%85%E7%8E%87

簡単にいうとテストコードを実行したときに本番のコードを通過した場所としてない場所の割合のことを言います。
割合が高ければカバレッジも高くなります。

カバレッジが高いとは

テストで実行される箇所が多いのであればカバレッジは高い方がいいのでは?と思われるかもしれませんが、ここで注目すべきはあくまでも実行はされるということですね。
ユニットテストの役割は色々ありますが、大事な役割として確認(assertion)があります。
ユニットテストの実行だけして確認をしなくてもカバレッジは高くなってしまいます。
どういうことか下記のサンプルコードで説明します。(言語はSwiftです)

import Foundation

func sum(_ lhs: Int, _ rhs: Int) -> Int {
    return lhs + rhs
}

そして下記のようなテストコードがあったとします。

import Foundation
import XCTest
@testable import Sum

final class SumTestXCTestCase {
    func testSum() {
        _ = sum(12)
    }
}

これでもテストは成功しますし、カバレッジは100%です。

カバレッジ100%達成!

これって本当に正しいでしょうか?どこか違和感があるはずです。
違和感の正体は先ほど説明した確認を全くしていないことですね。
最低限下記のようなXCTAssertで実行結果の確認をしていれば多少違和感は拭えると思います。(あくまでもサンプルなのでこれが正しいユニットテストとは言いません)

import Foundation
import XCTest
@testable import Sum

final class SumTestXCTestCase {
    func testSum() {
        XCTAssertEqual(sum(01), 1)
        XCTAssertEqual(sum(12), 3)
    }
}

ただ、コードを実行すること自体を否定するつもりもありません。
例えばクラッシュしないことやコードが最後まで実行されることが分かったりはするので価値がゼロというわけではないと思います。(稀に確認コードが書けないということもあったりするかもしれませんし)

まとめ

カバレッジは高ければいいわけではない(ちゃんと確認もしようね)というニュアンスが含まれているということがわかりました。
逆に言えばちゃんと実行結果の確認さえしておけばカバレッジは高ければ高いほどいいとも言えるなと思いました。(ここの認識においても間違っていたら指摘してください)
とはいえなんでもかんでも書けばいいのかというとそこは優先度とか考えることは色々あると思いますが、個人的には腹落ちしたので今夜もぐっすり眠れそうです。

同僚により詳しい記事を教えていただきました。
カバレッジについてより詳しい説明はこちらに譲ります。

この記事が気に入ったらサポートをしてみませんか?