開発未経験のテストエンジニアがRailsで自動テストをやってみた


私は、テストエンジニアとして働いています。
業務経験としては、業務系システムのテスターが1年3か月、
進捗管理が2か月程です。

私の技術的な強みが、
少しSQLが得意なこと以外に思い浮かばないのに危機感を感じ、
10月からRailsを使った個人開発を自己研鑽として行っています。
(SQLの知識としては、オラクルマスターブロンズ合格程度です。)

そんな私が、Railsでテストを書いてみて、
手動テストとの比較を記事にしてみました。

自動テストの魅力

大きく分けて以下の2つのメリットを感じました。

・テスト実行が楽
・テストを先に書くことで、仕様の整理ができる

テスト実行が楽

何と言っても、テスト実行が楽です。
ひとたびコードを書いてしまえば、
"rails t"というコマンド一行でテストを実行できます。

きちんとテストが書けていればという前提ですが、
本番環境へのデプロイ前に、先述のコマンドを打ち込めば、
正常にアプリケーションが動くかどうかが確認できます。

また、手動テストでExcel方眼紙にスクリーンショットを貼り付けて
エビデンスを整形するのが常識である現場にいる人間にとって、
この効率の良さは驚異的です。

テストを先に書くことで、仕様の整理ができる

これも大きなメリットだと感じます。

テスト設計をするときは、正常系のみならず、
異常系も考慮しなくてはなりません。

個人的にはモデルのテストを書くときが最もわかりやすく効果を感じました。

例えば、パスワードを格納するカラム一つとっても、
文字数に上限や下限を設けるのかや、
半角記号や半角数字を含むことを必須にするのかなど、
検討事項は複数あります。

そして、それらに確固たる正解はありません。

そのような事項を1つ1つテストとして書いて思考を整理するのです。

ウォーターフォール型開発の現場にしかいたことがないせいか、
細かい仕様の検討とテスト設計を同時に進めることは、
新鮮かつ楽しく感じます。
(上流・下流という謎の上下関係のような概念はそこにはないと思う。)

自動テストの課題

私が自動テストを書きながら課題と感じたのは以下のことです。
(私自身の今後の技術的課題でもあります。)

・細かい表示のテストは難しい。
・うまく自動化できない場合がある。

細かい表示のテストは難しい

画面がスクロールしても固定させたい部分や、
画面のスクロールに合わせて一定の範囲で動かしたいといった、
ユーザビリティに関わることをテストするのは難しく感じます。

うまく自動化できない場合がある。

エンジニアの技術不足で、うまくテストを自動化できない場合もあります。

私の技術不足で、今開発しているアプリでうまく自動化できなかったのは、
コントローラーに書いた以下のコードに対応するテストです。

※ブラウザ上では期待結果通り、
destroyアクションが動く前に参照していたページにリダイレクトされました。

app/controllers/mission_controller.rb
 def destroy
    Mission.find(params[:id]).destroy
    flash[:success] = "タスクを削除しました。"
    #以下の1行に関するテストが書けませんでした。
    redirect_back(fallback_location: root_path)
  end

コードの意味としては、
可能ならリファラーにリダイレクトし、
不可能ならroot_pathにリダイレクトするという意味です。

integration testでテストを書くと、
どうしてもroot_pathにリダイレクトしてしまいます。
※以下のように書かないとテストが失敗します。

test/integration/missions_destroy_test.rb
require 'test_helper'

class MissionsDestroyTest < ActionDispatch::IntegrationTest

  def  setup
    @user = users(:michael)
    @mission = Mission.find_by(user_id: @user.id)
  end

  test "destroy mission from users show when cannot get refferer" do
    log_in_as(@user)
    get user_path(@user)
    assert_template 'users/show'
    delete mission_path(@mission)
    assert_redirected_to root_path
  end

  test "destroy mission from missions index when cannot get refferer" do
    log_in_as(@user)
    get missions_path
    assert_template 'missions/index'
    delete mission_path(@mission)
    assert_redirected_to root_path
  end
end

考えられる原因としては、
システムテストのように、
実際のブラウザに対してテストを実行しておらず、
fallback_locationを取得できなかったからだと考えています。
(間違っていたら、ご指摘いただけますと幸いです。)

まとめ

自動テストはとても魅力的だと思います。
これから、システムテストも書けるようになっていきたいです。