LoginSignup
0
1

More than 3 years have passed since last update.

Ruby on RailsのテストフレームワークRspecでコードカバレッジを理解する

Last updated at Posted at 2020-05-17

テストケースを書いていると、どこまでカバレッジをカバーするって話がでてきます。

コードカバレッジってそういえばどんなのだっけ?って思ったので、自分の備忘録としてまとめようと思います。

コードカバレッジとは?

ソフトウェアテストにおいて、テスト対象となるプログラムコード(内部ロジック)全
体の中で、テストが行われた部分が占める割合(網羅率)です。
参照

代表的なカバレッジ

C0:命令網羅

それぞれの命令文が少なくとも1回は実行

C1:分岐網羅

それぞれの判定条件に置ける真偽が少なとも1回は実行

C2:条件網羅

それぞれの条件文に置ける真偽が少なくとも1回は実行

MCC:複合条件網羅

それぞれの条件に置ける真偽の組み合わせが全て実行

実際Rspecでカバレッジを意識してテストを書く

テストをするRubyコード

sample.rb
module CodeCoverage
  class << self
  # main
  # @params [interger] x
  # @params [interger] y
  # @return [String] xとyの値によってことなる文字列
  #
  # 引数は、intergerのみを想定
  def main(x, y)
    result = ''
    if x >= y || x % 2 == 0
      result << '処理1'
    else
      result << '処理2'
    end
    if x*y > 10
      result << '処理3'
    else
      result << '処理4'
    end
    return result
  end
  end
end

Rspecで書いたテストコード

Rspecとは

Ruby on Railsの開発手法の1つであるTDD(テスト駆動開発)を実現するためのフレームワークの1つ
参考

テストコード本体

RSpec.describe CodeCoverage do
  shared_examples '処理1と処理3通る' do
    it '処理1と処理3の文言が返却される' do
      expect(subject).to eq '処理1処理3'
    end
  end
  shared_examples '処理1と処理4通る' do
    it '処理1と処理4の文言が返却される' do
      expect(subject).to eq '処理1処理4'
    end
  end
  shared_examples '処理2と処理3通る' do
    it '処理2と処理3の文言が返却される' do
      expect(subject).to eq '処理2処理3'
    end
  end
  shared_examples '処理2と処理4通る' do
    it '処理2と処理4の文言が返却される' do
      expect(subject).to eq '処理2処理4'
    end
  end

  describe 'main' do
    subject { described_class.send(:main, x, y) }
      # C0:命令網羅
    # 命令が少なくても1回だけ実行するように書く
      context 'C0の場合' do
        context '処理1と処理3を通る' do
          let(:x) { 11 }
          let(:y) { 1 }
          it_behaves_like '処理1と処理3通る'
        end
        context '処理2と処理4を通る' do
          let(:x) { 1 }
          let(:y) { 9 }
          it_behaves_like '処理2と処理4通る'
        end
      end
      # C1:分岐網羅
      # それぞれの判定条件に置ける真偽が少なとも1回は実行
      context 'C1の場合' do
        context '処理1と処理3を通る' do
          let(:x) { 11 }
          let(:y) { 1 }
          it_behaves_like '処理1と処理3通る'
        end
        context '処理1と処理4を通る' do
          let(:x) { 3 }
          let(:y) { 2 }
          it_behaves_like '処理1と処理4通る'
        end
        context '処理2と処理3を通る' do
          let(:x) { 3 }
          let(:y) { 5 }
          it_behaves_like '処理2と処理3通る'
        end
        context '処理2と処理4を通る' do
          let(:x) { 1 }
          let(:y) { 4 }
          it_behaves_like '処理2と処理4通る'
        end
      end

      # C2:条件網羅
      # それぞれの条件文に置ける真偽が少なくとも1回は実行
      context 'C2の場合' do
        context 'x>=yかつx*y>10' do
          context '処理1と処理3を通る' do
            let(:x) { 11 }
            let(:y) { 1 }
            it_behaves_like '処理1と処理3通る'
          end
        end
        context 'x>=yかつx*y<10' do
          context '処理1と処理4を通る' do
            let(:x) { 3 }
            let(:y) { 2 }
            it_behaves_like '処理1と処理4通る'
          end
        end
        context 'x<yかつxが偶数かつx*y>10' do
          context '処理1と処理3を通る' do
            let(:x) { 4 }
       let(:y) { 5 }
            it_behaves_like '処理1と処理3通る'
          end
        end
        context 'x<yかつxが偶数かつx*y<10' do
          context '処理1と処理4を通る' do
            let(:x) { 2 }
            let(:y) { 3 }
            it_behaves_like '処理1と処理4通る'
          end
        end
        context 'x<yかつxが奇数かつx*y>10' do
          context '処理2と処理3を通る' do
            let(:x) { 3 }
            let(:y) { 5 }
            it_behaves_like '処理2と処理3通る'
          end
        end
        context 'x<yかつxが奇数かつx*y<10' do
          context '処理2と処理4を通る' do
            let(:x) { 1 }
            let(:y) { 4 }
            it_behaves_like '処理2と処理4通る'
          end
        end
      end
    end
  end
end

こうやって書くとパッとわかりやすいですね。
どこまでのコードカバレッジを満たすかは、適宜ですが、仕事だとC1ぐらいまでです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1