Rubyでテストを自動化する方法とメリット

## はじめに
今回、Rubyのテストの自動化について学んだことの備忘録を残したいと思い、記事を書くことにしました。

なお、本記事の作成にあたって
[プロを目指す人のためのRuby入門[改訂2版]](https://amzn.asia/d/7pM8zu7)
[minitest-5.18.0 Documentation](https://docs.seattlerb.org/minitest/)
を参考にしています。


## この記事の読者対象
- Rubyを学習し始めた方
- テストの自動化について知りたい
- エンジニアを目指して学習されている方で、ある程度Rubyの基礎構文を理解されている方

## テストを自動化するメリット
テストを自動化しない場合、思ったとおりの結果になってほしいが、毎回コードを書いて確かめるのが面倒くさいため、数が多ければ多いほど正しくテストを行えなくなる可能性が高いです。

一方で、テストの自動化を行なった場合、コマンド一つでコンピュータが即実行結果をチェックしてくれるため、間違っている場所を詳しく指摘してくれます。

## 環境構築
#### 環境や前提条件
```
Minitest version: 5.16.3
ruby version 3.2.2
```

#### Minitestというテストのフレームワークを利用
テストを自動化するためにテスト用のフレームワークを使用するのですが、今回はセットアップ不要で使用できるMinitestというフレームワークを使用。 
コードエディターはVisual Studio Code、実行についてはVisual Studio Codeのターミナルで行います。

```
# Minitestのversionをチェック
ruby -r minitest -e "puts Minitest::VERSION"
5.16.3
```

## 実際のテストの流れ

**1: テスト用のファイルと、実行用のファイルを作成します。**
```
root
  |----lib/
  |     |--fizz_buzz.rb
  |----test/
        |--fizz_buzz_test.rb 

```  

**2: 続いて、それぞれのファイルにテストを書いていきます。**

テストを行いたいファイル
```
# lib/fizz_buzz.rb

def fizz_buzz n
  if n % 15 == 0
    # 15で割り切れるなら
    "Fizz Buzz!!"
  elsif n % 5 == 0
    # 5で割り切れるなら
    "Buzz"
  elsif n % 3 == 0
    # 3で割り切れるなら
    "Fizz"
  else
    # それ以外は文字列に変換
    n.to_s
  end
end

```
テストコードの書かれているファイル
```
# test/fizz_buzz_test.rb

require 'minitest/autorun' # Minitest ライブラリを読み込む
require_relative '../lib/fizz_buzz' # このテストファイルと同じ階層にある lib ディレクトリの fizz_buzz.rb を読み込む

class FizzBuzzTest < Minitest::Test # FizzBuzzTest クラスを定義し、Minitest::Test クラスを継承する
  def test_fizz_buzz
    assert_equal '1', fizz_buzz(1)        # fizz_buzz(1) の結果が '1' と等しいことを確認
    assert_equal '2', fizz_buzz(2)        # fizz_buzz(2) の結果が '2' と等しいことを確認
    assert_equal 'Fizz', fizz_buzz(3)     # fizz_buzz(3) の結果が 'Fizz' と等しいことを確認
    assert_equal '4', fizz_buzz(4)        # fizz_buzz(4) の結果が '4' と等しいことを確認
    assert_equal 'Buzz', fizz_buzz(5)     # fizz_buzz(5) の結果が 'Buzz' と等しいことを確認
    assert_equal 'Fizz', fizz_buzz(6)     # fizz_buzz(6) の結果が 'Fizz' と等しいことを確認
    assert_equal '7', fizz_buzz(7)        # fizz_buzz(7) の結果が '7' と等しいことを確認
    assert_equal 'Fizz Buzz!!', fizz_buzz(15) # fizz_buzz(15) の結果が 'Fizz Buzz!!' と等しいことを確認
  end
end

```

**3, テストの実行方法**

1: VS Codeのターミナルを開く(macの方は、Command + Jで開けます)
2: ターミナルに`ruby + 半角スペース + testファイル`をドラッグ&ドロップ
```
ruby {testファイルまでの絶対パス}
例: ruby '/Users/ariyan/practice_ruby/ruby-book/test/fizz_buzz_test.rb'
```

※絶対パスとは


**4, テストコードの結果を確認**
```
Run options: --seed 24971

# Running:

.

Finished in 0.000846s, 1182.0331 runs/s, 9456.2648 assertions/s.

1 runs, 8 assertions, 0 failures, 0 errors, 0 skips
```
テストコードの結果の内容を順に説明していきます。

```
Run options: --seed 24971
```

テスト実行時のオプションを示しています。
`--seed 24971`は、テストケースのランダムな順序で実行するためのシード値を示しています。シード値を指定することで、テストの順序に依存した問題を見つけることができます。

```
# Running:
```
テストの実行が開始されたことを示しています。

```
.
```
この行は、テストケースの結果を示しています。「.」は、テストケースが成功したことを意味します。他にも、以下の記号が表示されることがあります。

F：テストケースが失敗したことを示します。
E：テストケースでエラーが発生したことを示します。
S：テストケースがスキップされたことを示します。

```
Finished in 0.000846s, 1182.0331 runs/s, 9456.2648 assertions/s.
```
テストの実行が終了したことと、実行にかかった時間を示しています。この例では、テストが 0.000846 秒で終了しました。また、実行速度も表示されており、1 秒あたり 1182.0331 回のテストケースが実行され、9456.2648 回のアサーションが評価されたことを示しています。

```
1 runs, 8 assertions, 0 failures, 0 errors, 0 skips
```
テストの結果の概要を示しています。以下の情報が含まれています。

- 1 runs：1 つのテストケースが実行されました。
- 8 assertions：8 つのアサーション（テストの期待値と実際の値を比較する評価）が行われました。
- 0 failures：失敗したテストケースは 0 件です。
- 0 errors：エラーが発生したテストケースは 0 件です。
- 0 skips：スキップされたテストケースは 0 件です。

この結果から、テストが正常に実行され、すべてのテストケースが成功したことが分かります。


## アサーションについて
アサーションとは、プログラムの特定のポイントで期待される状態や条件を確認するためのチェックです。テストコードにおいて、アサーションは機能やメソッドの出力が期待どおりであることを検証する際に使用されます。アサーションが成功すると、テストはその部分で期待される動作を満たしていると判断され、失敗すると、バグや問題が存在する可能性があることが示唆されます。

アサーションは、様々なテストフレームワークでサポートされており、それぞれ独自のアサーションメソッドを提供しています。たとえば、Minitestでは以下のようなアサーションメソッドがあります。

**aがbと等しければPathする**
`assert_equal b, a`

**aが真であればPathする**
`assert a`

**aが偽であればPathする**
`refute a`

アサーションは、テストコードにおいて重要な役割を果たします。アサーションによって、コードの正確性や信頼性を向上させ、保守性を高めることができます。コードの変更やリファクタリングが行われた際に、アサーションを含むテストが正常に動作することを確認することで、コードの品質を維持することが可能になります。