| 両方とも前のリビジョン
前のリビジョン
次のリビジョン
|
前のリビジョン
|
blog:2020:1015_effective_testing_with_rspec_3 [2020/11/28 17:47] kijima [Effective Testing with RSpec 3] |
blog:2020:1015_effective_testing_with_rspec_3 [2020/11/30 00:23] (現在) kijima |
| {{tag>book 進行中}} | {{tag>book}} |
| |
| ====== Effective Testing with RSpec 3 ====== | ====== Effective Testing with RSpec 3 ====== |
| |
| 15 23 33 47 254 | |
| ===== 1 ===== | ===== 1 ===== |
| |
| |
| * 操作の結果を保存する、メモ化を利用する。典型的なのは | * 操作の結果を保存する、メモ化を利用する。典型的なのは |
| <code> | <code ruby> |
| def sandwich | def sandwich |
| @sandwich ||= Sandwich.new('delicious', []) | @sandwich ||= Sandwich.new('delicious', []) |
| |
| ===== 3 ===== | ===== 3 ===== |
| | * メモを忘れる。 |
| | ===== 4 ===== |
| | * いきなりsinatraをやらされる。 |
| | * requestのテストでは、レスポンスの返すステータスコードで動作を確認したりする。内部については考えないということ。ブラックボックステスト。 |
| | |
| | ===== 5 ===== |
| | * Umm... |
| | * before, letはDRYを実行するリファクタリングに便利。 |
| | * 急に出てきたコイツ↓ |
| | <code ruby> |
| | allow(ledger).to receive(:record) |
| | .with(expense) |
| | .and_return(RecordResult.new(false, 417, 'Expense incomplete')) |
| | </code> |
| | は何なんだよ!ledgerのrecordメソッド。RecordResultがrecordに反応するかどうか? |
| | * とりあえずLedgerは元帳。記録する役割。gemの名前とかではない。Structで一時的に作った中身のない引数だけとるヤツだった。。 |
| | * なんとなくわかり始める。テストというよりHTTPメソッドのやりとりがよくわかってなかったんだな。 |
| | ===== 6 ===== |
| | * integration spec |
| | * GETメソッドを追加する。 |
| | * <code ruby>bundle exec rackup config.ru #sinatra起動</code> |
| | * 最初にテストを作っておけばいちいちブラウザでできたか確認する必要がない。 |
| | * ''bundle exec rspec --bisect --seed 32043'' |
| | * 毎回DBをrollbackするために、設定を追加する。requireをヘルパーに追加して、:dbが使われるときに読み込むようにする。 |
| | |
| | ===== 7 ===== |
| | |
| | 重複をなくす方法いろいろ。フックとかincludeとか。すごい綺麗になった。 |
| | |
| | ===== 8 ===== |
| | |
| | メタデータをつけた効率的なテスト実行。 |
| | |
| | ===== 9 ===== |
| | |
| | カスタマイズ。 |
| | 出力を必要なものに絞るとか。あまりいらないような。 |
| | |
| | ===== 10 ===== |
| | |
| | expectation |
| | |
| | matcherは正規表現のようなものだ。文字列のかわりに特定のオブジェクトでマッチする。 |
| | 175ページは興味深い。マッチャがどう反応するか試している。適当に作ったオブジェクトをexpectにわたすと、no method errorが出る。matches? がないらしい。matches?を追加する。 |
| | |
| | matcher = Object.new |
| | |
| | def matcher.matches?(actual) |
| | actual == 1 |
| | end |
| | |
| | 1だと正を返すような。それで、 |
| | |
| | expect(1).to matcher # => true |
| | expect(2).to matcher # => no method error, 'failure_message' |
| | |
| | def matcher.failure_message |
| | 'failure' |
| | end |
| | |
| | irbでマッチャをチェック |
| | <code ruby> |
| | require 'rspec/expectations' |
| | include RSpec::Matchers |
| | </code> |
| | |
| | マッチャを組み合わせるときに''.and''もしくは''&''などを使う。or,not.. |
| | |
| | ''description''がメソッドを文字に変更するようす |
| | <code ruby> |
| | [57] pry(main)> (start_with(1) & end_with(9)).description |
| | => "start with 1 and end with 9" |
| | </code> |
| | |
| | ↑を利用してit内を省略できるときがある。一行のマッチャのとき? |
| | |
| | <code ruby> |
| | # fish_oilが重複している |
| | it 'should not include:fish_oil' do |
| | expect(CookieRecipe.new.ingredients).not_to include(:fish_oil) |
| | end |
| | |
| | => should not include:fish_oil |
| | </code> |
| | |
| | <code ruby> |
| | specify do |
| | expect(CookieRecipe.new.ingredients).not_to include(:fish_oil) |
| | end |
| | |
| | => should not include:fish_oil |
| | </code> |
| | |
| | 最初にsubjectを指定しておくことでexpectにいつも書く手間が省けることがある。is_expected_to |
| | |
| | ===== 11 ===== |
| | |
| | さらなるmatcher。 |
| | 特定の型に反応する''primitive matcher'' |
| | |
| | 「同じ」にもいろいろある。 |
| | * 同じオブジェクト |
| | * 同じ値 |
| | * 同じハッシュ(?) |
| | |
| | なんの脈絡もなくハリーポッターが出てきて笑う |
| | |
| | U2も。作者がイギリスの人なんだなきっと。 |
| | ===== 12 ===== |
| | |
| | 新しいマッチャを定義する |
| | |
| | ===== 13 ===== |
| | |
| | スタブ、モック、スパイ、ヌルオブジェクト。 |
| | |
| | システムの一部を独立させてテストしやすいようにする |
| | |
| | テスト用のはりぼてのクラスやメソッドを作ったり、テストのときだけ定義される定数なんかもできる。stub_const |
| | |
| | 前者3つの違いがよくわからん…。スタブ: 受信メッセージ用。依存するオブジェクトを決まりきった反応しかしないオブジェクトに変える。 |
| | |
| | モック: 送信メッセージ用。 |
| | |
| | ===== 14 ===== |
| | |
| | 設定 |
| | |
| | ===== 15 ===== |
| | |
| | ダブルを効率的に |
| |