レジメに追記

当初のレジメに記載したディレクトリ構成に「config/database.yml」が無かったので追記しておく。
テストフレームワーク -RSpec

　アプリケーションの開発とともにテストを書いておき、リファクタリングや改修時の手間、恐怖を軽減する。

　Rubyでよく利用されるらしい「RSpec」というフレームワークを利用してみる。あわせて、デンドツーエンド用の「Capybara」も使用もインストールする。
　テスト時のみに利用するgemなのでGemfile内に「group :test」というブロック内に記述して bundle install
を行う。

※参考にしている書籍の執筆時には、 Capybara
が利用している「Nokogiri」というライブラリのインストールでエラーになるようだったが、今は大丈夫くさいので、とりあえずそのまま続けてみる。
テストフレームワーク -RSpec②

　「RSpec」を実行するための初期設定を行う「rspec --init」というオプションが用意されている。このコマンドを使って初期設定を行う。
　rspec --initで下記、ファイルが作成。

.repec
　「RSpec」を実行したときの出力オプションを記述しておくファイル。お気にいりの出力形式などある場合は、このファイルを編集する。

spec/spec_helper.rb
　このファイルを RSpec の設定など記述する起点のファイルとして扱っていく。
　　
テストフレームワーク -RSpec③

　事前準備として、テスト用のデータベースを作成しておく。
テスト実行時には RACK_ENVに test として設定されるため、 config/database.ymlの「test」の項目が使用される。
database に定義しているパスにデータベースファイルを用意することで、テストの実行時に参照できるようになる。
　データベースの作成方法は開発用データベースと同じ。

※ターミナルで
　$cd db
　$ sqlite3 sqlite.test.db < schema.sqlite3.sql
エンドツーエンドとユニットテスト

　一般的に「テストを書こう」という話しをするときにはユニットテストの文脈で語られることが多いらしい。でも、今回はテストの入口として、簡単なエンドツーエンドのテストを通じて、「RSpec」を使った方法を勉強する。

　「RSpec」を使いつつ、「Capybara」というエンドツーエンドテストフレームワークを追加することで、RSpecの構文を使って、エンドツーエンドテストを書くことができる。

※とりあえず元々、記入されてたコメントアウトは、削除。

*1).　テスト全般の初期設定として先頭行に「ENV['RACK_ENV'] = 'test」を記述。

*2).　「Capybara」を RSpecから利用できるように「require 'capybara/rspec'」を読み込む。

*3).　エンドツーエンドでテストを実行する Sinatra アプリケーション自体を読み込む。

*4).　RSpec.configure ブロック内で
　　　　　「Capybara.app」
　　　　　「config.include」
　　　の行を追加。

*1).～*4). で「Capybara」が扱うテスト対象を設定できた。
エンドツーエンドとユニットテスト②

ここでは、URLを1件登録した状態で http://localhost:9292
へアクセスし、登録したURLがHTML上に描画されていることをテストしている。
　※ RSpec
でテストを定義するファイルは末尾に「_spec」を付加する必要あり。今回は「app/shiori.rb」に対するテストなので「shiori_spec.rb」となる。

【解説】
　テストの構造は、 「describe」メソッドや「context」メソッドを使ってテスト対象や状況について明示し、「it '登録した...’
do ...
end」の「it」ブロック内に実際に検証する値を書いていく。「describe」メソッドは最低1つは必要だが、「context」は必ずしも必要ではない。テストの状況を説明するためにより具体的な説明を行いたい場合に使用することで、
RSpec を実行した際の出力結果をわかりやすくするために適宜使用する。

*1
「before」ブロックはテストを実行するたびに実行される前処理を実行する部分。ここで決まった前処理を行ってテストを実施するための状態をつくっている。

*2 本題は「it」ブロックの中。「visit」は Capybara が提供しているメソッドで、 '/'
へブラウザでアクセスするのと同じ状況を発生させる。そうすると、そのレスポンスデータが「page」オブジェクトに格納される。 page
オブジェクトの内容を「RSpec」の構文を使って検証する。

*3　の部分は RSpecでの検証方法を端的に表す構文。 expect() 内の値を eq
メソッドを使って右辺と等しいか検証している。つまり、この行では '/' へアクセスした結果、HTTP のステータスコードとして 200
が返ってくるということを期待したコードになる。

*4　ではレンダリングされたHTMLの検証を行っている。
ここでは、 page.find(...) を使ってXPathでHTML構造を解析し、出力させるリンクとして Bookmark.create!
で登録したURLが表示されているかどうかを検証している。

このままだと、このテストを数回繰り返すと Bookmarak.create! が何度も実行されてしまい、 page.find
の結果が複数件取得され、エラーとなってしまう。次のコミットで対策。
エンドツーエンドとユニットテスト③

テストごとにクリーンな状況を保つため、 spec_helper.rb 内でデータの削除処理を実行する。

*5　Bookmarkクラスを読み込む。

*6　config.before ブロック内で Bookmark.destroy_all
を実行し、これによりテーブル内のレコードを全件削除している。 config.before もまた、テスト実行時に毎回実行されるフック処理。

※今回はテーブル数も限られているので、自分でレコードの全件削除を実装しているが、レコードの削除を行う 「Database Cleaner」という
gem パッケージがよく利用される。

※テストは手元で実行するのもいいが、コードをコミット（あるいはプッシュ）したタイミングでテストを実行し、常に書いたテストが実行されるような CI
環境を併せて用意しておくと効果的。