ねこものがたり

プログラミング学習の記録

自動テストの考え方

苦戦しているけれど、テストの書き方の基本が少しずつわかってきたので、まとめ。

そういえば、ブログを書いたり日報を書いたりするのがとても下手だと自分で思います。

読み返した時に自分が何に詰まっていたのか、それがどんな原因で、どう対応したら解決したかっていうのを意識してまとめて行きたいと思います。

戦いの記録

初回

  • 詰まっていたこと: バリデーションしかかける自信がない
  • 書いたテスト:modelのテスト(バリデーションだけ)
  • もらった助言:「”自分で書いたメソッド"のテストを書こう」

2回目

  • 詰まっていたこと:「自分で書いたメソッド」がどれかわからない。gemやrails自体の機能との区別がつかない。
  • 書いたテスト:gemとか全く絡めてないメソッドのテスト
  • もらった助言:「gemの機能を使って書き加えたテストも”自分で書いたメソッド”だよ」

3回目

3回目でこのテストならオッケー( ・∇・)いただきました。

初歩の初歩のテストコードでめちゃくちゃ苦戦して1週間使いました。辛かったです。

でも、オッケー頂いた時は、ただただ嬉しくで涙が・・・(● ˃̶͈̀ロ˂̶͈́)੭ꠥ⁾⁾

modelのメソッドのテストを書く(ユニットテスト

基本的なことなので、このブログをいつか読み返している私は、ここに書くことなんてもう分かってて当然でしょって思ってて欲しい。

メソッドが何をしているのか

”自分で書いたメソッドに該当するのが悲しいことにomniauthを使ったメソッドで、正直usageとかomniauthを使いこなしている人たちのコードをみて写して書いたみたいなところがあったので、「果たしてこれはどうテストしたらいいんだろう」というのを考えるもの大変でした。

こんなメソッド。

def self.from_omniauth(auth, singend_in_recource = nil)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email || User.create_unique_email
      user.password = Devise.friendly_token[0, 20]
      user.name = auth.info.name
      user.avatar_file_name = auth.info.image
      user
    end
  end

このメソッドでやりたいこと。

where(provider: auth.provider, uid: auth.uid).firstの部分。 providerauth.provider(このアプリではTwitterのみ)でuidauth.uidの情報を持っている最初のユーザーを探す。

or_create do |user|は、該当するユーザーがいなかったらユーザーを新規登録する。

user.email = auth.info.email || User.create_unique_email  
    user.password = Devise.friendly_token[0, 20]
    user.name = auth.info.name
    user.avatar_file_name = auth.info.image
    user

ユーザーの登録情報はemailpasswordnameavatarで、provider(=Twitter)のアカウント情報を使うよ。

登録したユーザーを返して終わり。

というのがこのメソッドである。(テスト書かなかったらわからなかった)

やりたいことをテストする

where(provider: auth.provider, uid: auth.uid).firstの部分。 providerauth.provider(このアプリの場合はTwitterのみ)でuidauth.uidの情報を持っている最初のユーザーを探す。

テストに書くこと。 *「過去にTwitter認証を使って登録している」という状態なので、テストではすでに登録したユーザーのデータを作成。

before do
    user = User.create(
    name: "TestUser",
    email: "testuser@example.com",
    provider: "twitter",
    password: "testpassword"
  )
 end
  • providerauth.provider(このアプリの場合はTwitterのみ)でuidauth.uidの情報を持っている最初のユーザーを探す」をコードにする。
it "authenticate an user" do
    user = User.where(provider: "twitter").first
    expect(user.name).to eq ("TestUser")
end

or_create do |user|は、該当するユーザーがいなかったらユーザーを新規登録する。

  • 「ユーザーの登録情報はemailpasswordnameavatarで、provider(=Twitter)のアカウント情報を使う」をコードにする。
 it "create an user through Twitter's API" do
              user = User.create(
                name: "OtherUser",
                provider: "twitter",
                password: "otherpassword"
                )
              expect(user.email).to be_empty
            end
Twitter認証の場合、アカウント情報にeメールアドレスがないっていう問題があるので、そこは別のメソッドとテストで書いています。

初めてテストっぽいテストを書いてみて

今回はfjord Boot Campの課題だったので、メソッドが先にあって、それを追う形でテストを書きました。 ですがテスト駆動型だとテストを先に書いて、やりたいことを明確にしてからメソッドにしていくんだなという感覚が少しは分かってきた気がします。

しかしまだこれはちょっとしたユニットテストに過ぎないし、もっと美しい書き方があるそうなので、もっともっと努力をしていきたいです。

テストを書くのは大変そうですが、テストを通してアプリ全体の設計やコードを美しくするというマインドも高めて行けたらなって思います。