【技術書メモ3】everyday Rails RSpecによるRailsテスト入門
- イントロダクション
- RSpecのセットアップ
- モデルスペック
- 意味のあるテストデータの作成
- フィーチャスペックでUIをテストする
- リクエストスペックでAPIをテストする
- スペックをDRYに保つ
- 速くテストを書き、早いテストを書く
- 最後のアドバイス
イントロダクション
・テストは信頼できるものであること
・テストは簡単に書けること
・テストは簡単に理解できること
RSpecのセットアップ
spec 作成したスペックファイルを格納するディレクトリ
spec/spec_helper.rb
・RSpecの出力をドキュメント形式に変更する
.rspecに
--equirespec_helper
--formatdocumentation
モデルスペック
・有効な属性で初期化された場合は、モデルの状態が有効(valid)になっていること
・バリデーションを失敗させるデータであれば、モデルの状態が有効になっていなこと
・クラスメソッドとインスタンスメソッドが期待通りに動作すること
一時的にバリデーションをコメントアウトしたり、テストを書き換えたりして、結果が変わることを確認する。
・期待する結果は能動的で明示的に記述すること
・起きてほしいことと、起きて欲しくないことをテストすること
・境界値テストをすること
・可読性を上げるためにスペックを整理すること
意味のあるテストデータの作成
FactoryBot
FactoryBot.buildを使うと新しいテストオブジェクトをメモリ内に保存FactoryBot.createを使うとアプリケーションのテスト用データベースにオブジェクトを永続化
ファクトリ内の重複をなくす
・ファクトリの継承
・トレイト(trait)
フィーチャスペックでUIをテストする
・モデルとコントローラが他のモデルとコントローラと上手く一緒に動作することを確認する。
・Capybaaを使うとリンクをクリックできたり、Webフォームを入力したり、画面の表示を検証したりできる。
・click_buttonを使うと、起動されたアクションが完了する前に次の処理へ移ってしまうことがあるので、cliclk_buttonを実行したexpect{}の内部で最低でも1個以上のエクス白テーションを実行する。
・save_and_open_pageをテストが失敗する場所の直前に挟み込むと、なぜテストが失敗したのかブラウザ上で詳しくわかる。
リクエストスペックでAPIをテストする
スペックをDRYに保つ
統合テストでaggregate_failuresを使えば、同じコードを何度も実行して遅くなったり、複雑なセットアップを複数のテストで共有したりせずに、テストが失敗した複数のポイントを把握することができる。
速くテストを書き、早いテストを書く
focusというタグをつけるだけで、focusタグを持つスペックだけを実行することができる。
また、bin/rspectag~slowとテストを実行すれば、タグがついたテスト以外を実行することができる。
※タグはコミットの前に必ず削除する
最後のアドバイス
小さなテストで練習!
自分がやっていることを意識!
短いスパイクを書くのはOK!
小さくコードを書き、小さくテストするのもOK!
統合スペックから書く!
テストをする時間を作る!
常にシンプルに!
古い習慣に戻らない!
テストを使ってコードを改善!
練習し続ける!
【技術書メモ2】パーフェクト Ruby on Rails
- 1章 Ruby on Railsの概要
- 2章 Ruby on RailsとMVC
- 3章 アセット
- 4章 Railsのロードパスとレイヤーの定義方法
- 5章 開発を効率化するgem
- 6章 Railsアプリケーション開発
- 7章 Railsアプリケーションのテスト
- 8章 Railsのインフラと運用
- 9章 より実践的なモデルの使い方
- 10章 Railsを拡張する
1章 Ruby on Railsの概要
Bundlerはgemパッケージの仕組みを進化させ、「開発しているプロジェクト内でどのgemパッケージを使っているのか」、そして「どのバージョンを使用しているのか」ということを明示する仕組みを提供する。
・CoC (Convention over Configuration) 設定より規約
設計を設けることにより非常にシンプルになり、本来注力すべきビジネスロジックの実装だけを考えることができるようになる。
・DRY (Don’t Repeat Yourself) 同じことを繰り返さない
DRY原則を守ることにより、変更が生じた際に何箇所もコードを修正することがなくなり、メンテナンス性が高まる。
・REST (Representation State Transfer) すべてのリソースに一意となる識別子がある
リソースを中心に考えると、機能追加のしやすい自然な設計になる。
自動テストとは
2章 Ruby on RailsとMVC
・M = Model
データベースとの接続とデータに対する操作、およびビジネスロジック
・V = View
Modelの内容を参照し視覚表現を行う部分
・C = Controller
Modelロジックを呼び出し、必要なviewの選択など、ModelとViewをつなぐ部分
モデルの役割
データベースと接続し、データベースのレコードとエンティティを結びつける。
※エンティティとは、対象物のまとまりのこと。データベースを設計する際に、人・物・事象・概念・サービスといった対象物を同一のカテゴリーでまとめたもののこと。
ビジネスロジックの実装的な振る舞いに関するところ、すなわちバリデーションや様々なコールバックを実行するところ。
※コールバックとは、レコードを作成して保存する一連の流れの間の様々な箇所で、任意の処理を埋め込む。こういった特定の処理を呼びだすこと。
コントローラーの役割
リクエストからコントローラーとアクションを決定し、アクションの中でモデルを通じてデータを取得・加工する。最後にそのデータをビューに渡してレンダリングを指示することで、Webアプリケーションの画面をユーザーに返す役割を担っている。
例外処理を行う。
例外処理を行う。
ビューの役割
情報についてユーザが最終的に認識可能な形にするところ。
Railsのテンプレートエンジンについて
・ERB
ERBの見た目はHTMLとほぼ同じ。そのため、既存のHTMLなどがある場合はそのまま利用できる。
Rubyの構文を使用する場合は<% %> <%= %>を使用する。
・Haml
HTMLの構造を非常にシンプルなインデントで表現したテンプレートエンジン。Railsの標準機能ではないが、gemパッケージとしてインストールできる。
・Slim
3章 アセット
Webアプリケーションの直接のレスポンスではない構成要素をアセットと呼ぶ。RailsにはPipelineという仕組みがあり、簡単にアセットを扱えるようになっている。
Sprockets(アセットパッケージングツール)の概要
・アセットファイルにアクセスするためのパスを管理させる
・アセットのコンパイル
・アセットファイルどうしの依存性を管理する
Sprocketsはアセットファイルを配置するパスを管理して1つのディレクトリにあるかのようにアクセスする機能を提供している。
よりモダンな構文と便利な機能を利用してJavaScriptを記述できる
Turbolinks
TurbolinksはJavaScriptやCSSに変化が無いなら、タイトルとbodyだけ差し替えることでJavaScriptやCSSの読み込みを省略し高速化できる、という発想の下に成り立っている。大まかには以下のフローに従っている。
・ページ内のクリックイベントを補足し、それがAタグに対するクリックだった時、Turbolinksによる遷移を実行する。
・取得したHTMLのタイトルとbodyタグの中身を抽出する
・現在のページのタイトルとbodyタグを抽出したものと入れ替えて更新する
・window.history.pushStateを実行し、参照しているURLをリンク先のURLに更新する
Turbolinksが実行されるのはGETメソッドによって遷移するリンクだけ
4章 Railsのロードパスとレイヤーの定義方法
MVCに当てはまらないようなモジュールの管理方法
・モデルとして扱う
・libディレクトリで管理する
・新しいレイヤーを定義する
libディレクトリ
独自に定義したRakeタスクを配置しておく場所
レイヤー
同種の機能を持ったクラスをいくつか定義したい場合、その機能を司るレイヤーを新しく追加しても良い。
5章 開発を効率化するgem
gem 'pry-byebug’
gem ‘hirb’
gem 'hirb-unicode’
コンソール上でのモデル情報の出力結果を、表形式の出力結果に整形することができる。
gem ‘spring'
springとは⇨railsコマンド実行時にspringコマンドを追加することで、初期起動時のデータなどを読み込むspringサーバが起動する。2回目以降はこのspringサーバを経由することでrailsコマンドが処理を開始する時間が高速化する。
springはgemパッケージとして提供されており、インストールすることでspringコマンドが実行可能となる。
gem 'rails-erd'
モデルの情報からER図のPDFなどを出力できる。
6章 Railsアプリケーション開発
OAuthとは?
gemについて
・gemのバージョンの取り扱いは、次の例のように様々なポリシーが採用されている
・常に新しいバージョンを使う
・リリース時までは定期的に新しいバージョンにアップデートするが、リリース時に固定する
・リリース時のバージョンで一旦固定するが、定期的にバージョンを見直す
7章 Railsアプリケーションのテスト
なぜテストコードを書くのか
テスト対象となる仕様とアプリケーションの設計を考える機会が増える
(仕様の抜け漏れを減らすことができる)
(きれいな設計にできる)
・手作業によるテストを減らすことができる
・「ここはちゃんと想定通りに動くだろうか…」という不安を減らせる
・リファクタリングや仕様の変更に自信を持って対応できる
モデルのテスト
・各メソッドが期待通りの値を返すか
・各メソッドが期待通りの副作用をもたらしているか
・バリデーションが正しく設定されているか
コントローラーのテスト
アクションがビューに渡すインスタンス変数に期待通りのオブジェクトを代入しているか
アクションが期待通りのステータスコードを返しているか
アクションが期待通りのテンプレートを選択しているか
8章 Railsのインフラと運用
DevOps
Dev:アプリケーション開発者
Ops:運用・インフラ担当エンジニア
DevOps⇨DevとOpsが歩み寄る
アプリケーションの構成
・ウェブサーバ
Railsのアプリケーション自体をホストするサーバ。
・データベース
Railsのバックエンドに利用するデータベースとしては、SQLitee3、MySQL、PostgreSQLなどがあります。このうち、MySQL、PostgreSQLは別途サーバプロセスを立ち上げる必要がある。
アプリケーションが大きくなった場合の安定性という点では、MySQLやPostgreSQLを利用してサーバ型のデータベースを用いたほうが有利。
9章 より実践的なモデルの使い方
Concern
日本語で関心ごとという意味で、開発者がひとまとまりの概念として捉えたい物事を指す。つまり、Concernモジュールとは開発者の関心ごとをまとめたモジュールということになる。
中でも、複数のモデルや機能に跨がって影響するようなものを、横断的関心ごとといい、以下のような例がある。
・アプリケーション全体で利用されるロギング機能
・変更に対する証跡の記録
・タグによる分類機能
・データの論理削除や、有効化・無効化処理
・他のサービスやバックエンドプロセスと連携するためのシリアライズ
サービスクラス
「コントローラ」と「モデル」の中間のイメージ。
コントローラがユーザーからのリクエストを呼び出すインターフェースであり、サービスがモデルが行う処理を取りまとめて実行するためのインターフェースになる。
10章 Railsを拡張する
Railsを拡張するgemの作り方は大きく分けて3つある
・RackMiddlewareを作る
・Railtieの仕組みを利用する
・その他、コマンドラインツールなどを作る
Rack
Webサーバ実装とアプリケーションフレームワークの実装との中間に存在し、お互いの差異を吸収するような規約のひとまとまり。
自己紹介
初めまして!よっぴと申します。
twitterはこちらです!!!!
経歴
2019/2/15からwebエンジニアとして働きはじめました。
Railsを使ってCtoCアプリの開発をしています!
それまでは美容外科クリニックで看護師として働いてました💉
DIVE INTO CODEで半年間プログラミングを学んで、今の会社に転職しました💻
好きなもの
食べ物は、とろろご飯とオムライス🍚
このブログでは、とりあえず読んだ技術書と参加した勉強会について書いていきたいと思います🐈
立派なエンジニア目指して頑張ります!よろしく願いします🙇♂️
【技術書メモ1】スクラムチームで始めるアジャイル開発 SCRUM BOOT CAMP THE BOOK
「スクラムチームで始めるアジャイル開発 SCRUM BOOT CAMP THE BOOK」を読みました!
職場でスクラム開発をしており、先輩が本を貸してくれたのがこの本を読むきっかけです!
この本は漫画を挟みながらスクラム開発について分かりやすく説明してくれているので、スクラム初心者の私でもとても理解しやすかったです♩
基礎編
アジャイル開発とは
・関係者は目的達成のためにお互いに協力しながら進める。
・利用者の反応や関係者からのフィードバックを継続的に得ながら。計画を調整する。
・計画は一度にまとめてではなく、少しずつくくる。そして実際に出来上がったものが求めているものに合っているかを頻繁に確認する。
・「事前に全てを正確に予測し、計画することはできない」という前提を意識する。
重要なもの、リスクの高いものを先に作り、重要度の低いものは後に回すことで、必要以上の時間をかけないようにする。
スクラムってなんだろう?
・要求を常に順番に並べ替えて、その順にプロダクトを作ることで成果を最大化すること。
・スクラムでは実現される価値やリスクや必要性を基準にする。固定の短い時間に区切って、作業を進める。この期間のことをタイムボックスと呼びます。?
・現在の状況や問題点を常に明らかにする。これを透明性と呼ぶ。
・検査⇨定期的に進捗状況や作っているプロダクトが正しいか、仕事の進め方に問題がないかを確認。
・適応⇨やり方に問題があったり、もっとうまくできる方法があったら、やり方そのものを変える。
・最低限のルールだけを決める。そのルールをどのように適用していくかは自分たちで決めなくてはいけない。
要求を並べ替える
プロダクトバックログ⇨製品やサービスの要件リスト。要求を抽出し、順番に並び替える
・順位の高いものから開発される。
・常にメンテナンスをして最新の並び順に保つ。
プロダクトの責任者は誰?
ロール1:プロダクトオーナー
・プロダクトのビジョンを明らかにし、周りと共有する。
・おおよそのリリース計画を定める。
・予算を管理する。
・顧客、プロダクトの利用者や経営者などのプロジェクト関係者と、プロダクトバックログの項目の内容を確認したり、作る順番や実現時期を相談したりする。
・既存のプロダクトバックログの項目の内容を関係者が理解できるように説明する。
・作られたプロダクトが要求にあっているかどうかを検査する。
⇨ つまり、要求や仕様、計画といったことに深く関係する作業を行う
ロール2:開発チーム
・リリース判断可能なプロダクトを作る
・3〜9人で構成
・上下関係はない
短く区切って繰り返す
スプリント⇨スプリント期間は固定する。(最長1ヶ月)
開発チームはこの期間の中で、計画、設計、開発、テストなどのプロダクトのリリース判断に必要なすべてのことを行う。
スプリント最終日に作業が残っていても、スプリントは終了し、期間は延長しない。
頻繁に計画する
計画は、スプリント計画ミーティングと呼ばれる。
開発する量は過去のスプリントの実績と、今後の予測を参考に決める。過去の実績のことをベロシティと呼ぶ。
第一部⇨スプリントの内容を簡潔にまとめる。これをスプリントゴールと呼ぶ。
※開発チームはスプリント計画で合意した内容を完了させることについて全力で尽くす必要はあるものの、計画したことをすべて完了させることについて約束をしているわけではない。
毎日状況を確認する
チームメンバ全員で進捗状況を確認したり、困りごとの相談を毎日実施する。
これをデイリースクラムと呼ぶ。
デイリースクラムで伝えること
・前回のデイリースクラムからやったこと
・次回のデイリースクラムまでにやること
・困っていること
出来上がったプロダクトを確認する
スプリントの最後にプロダクトオーナーがプロダクトを確認する機会を設定する。これをスプリントレビューと呼ぶ。
依頼したものと異なる場合は作業は完了していないものとし、プロダクトバックログに戻す。
・開発チームが完了できなかったプロダクトバックログの項目について説明する。
・プロダクトオーナーがプロダクトの状況やビジネスの環境について説明する。
・プロジェクトを進める上で問題となる事項について関係者で議論する。
・現在の進捗を踏まえてリリース日や完了日を予測する。
もっとうまくできるはず
スプリントの最後はスプリントレトロスペクティブを行う。(振り返り)
縁の下の力持ち
プロダクトをうまく作れるようにプロダクトオーナーや開発チームを支えるのがスクラムマスターである。
スクラムの外にいる人からの妨害や割り込みからプロダクトオーナーや開発チームを守る。
スクラムマスターの役割
・分かりやすいプロダクトバックログの書き方を、プロダクトオーナーや開発チームに教える。
・プロダクトバックログの良い管理方法を探す。
・スプリント計画ミーティングやスプリントレトロスペクティブなどの会議の進行を必要に応じて行う。
・プロダクトオーナーと開発チームの会話を促す。
・プロダクトオーナーや開発チームの生産性が高くなるように変化を促す。
・仕事を進める上での妨げになっていることをリスト化する⇨妨害リスト
実践編
大丈夫だと思う見通しを立てる
・これくらいなら大丈夫だという見通しを立てる。
・ユーザーストーリーは実際に使うユーザーに何を提供して、その目的はなんなのかを簡潔に書くやり方。最初に重要な項目が漏れないようにすることが大切。
プロダクトバックログの順序
・超重要
・重要
・普通
・なくても良い
まずは大雑把に分類する
見積もりは素早くやろう⇨見積もりはあくまで推測にすぎない
時間やお金で見積もるのではなく、プロダクトバックログの項目を終わらせるためにどれくらいの量の作業があるかに注目する。
スクラムでは実際に作業をする人が最終的な見積もりをする。
作業量を考えるには、過去に実施した作業と比較する。
比較の基準になる作業は、簡単すぎてはダメ。比較対象の作業量が10倍くらいに収まるような基準になっているのが良い。
基準の見つけ方
⇨大雑把に3つに分ける
・簡単に終わらせられる
・少し大変そう
・結構大変そう
分類したら「少し大変そう」の項目を、作業の量が少ないと思う順にさらに一列に並び替える。
並んだ項目の真ん中あたりから作業が具体的にイメージできる項目を選んで、それを基準にする。
これから先のことを知っておく
ポイント⇨実現したいことそれぞれがどのくらいの作業になりそうかの単位?
ベロシティ⇨スプリントごとに終わらせることのできるポイント数
プロジェクトの先のことは以下のようにベロシティを使うと見えてくる
・絶対に必要な項目の見積もりの合計÷ベロシティ=必要なスプリント数
・ベロシティ×期間内に実施できるスプリント数=実現できるポイント数(どこまで実現できそうか)
確実に終わる計画を作ろう!
スプリント計画ミーティング⇨これから始まるスプリント計画を作るための活動。確実に終わらせられる計画を作る。
プロダクトバックログの中からどれを実現するかを、二段階のステップを踏んで決める。
第一部では、プロダクトオーナーと開発チームで今回のスプリントでどこまで終わらせられそうか見当をつける。
第二部では、開発チームが中心となって実際の開発作業を洗い出し、今回のスプリントで達成するプロダクトバックログの項目はどれかを決定する。
スプリントレビュー
完了の定義を決めておく。
完了の決め方
1、プロダクトオーナーがスプリントごとにどこまで終わっていてほしいかを伝える。
2、開発チームがどんな基準を設けるかを話し合う。
3、プロダクトオーナーが本当にこれでいいのかを判断する。
スクラムチーム全員が終わったと確実に判断できるようにしておかなければいけない。
問題になる前に見つける!
スプリントの期間は思っている以上に短いので、どんなに些細なことでもスクラムチーム全員で対処する。
タスクボードなどを使うと、スプリントが順調に進んでいるのかを確認できる
タスクボード⇨未着手、着手、完了でタスクを分ける
タイムボックスは譲れない!
まずはタイムボックスを守ることから始める。
・スプリントの期間は最大1ヶ月
・デイリースクラムは15分以内
・スプリント計画ミーティングは8時間以内(スプリント期間が1ヶ月の場合)
・スプリントレビューは4時間まで(スプリント期間が1ヶ月場合)
・スプリントレストロスペクティブは4時間まで(スプリント期間が1ヶ月の場合)
タイムボックスの考え方⇨制限時間を設けてその中で必要なことをやり、時間内に終わらなかったものは次のタイムボックスに回す。
実施できるスプリントの回数が決まっていれば、実現できることが可能。
プロジェクトの先を見通すためにタイムボックスは不可欠。
少し早くおわったぞ!
もし、スプリントで予定していたものが早く終わったら、プロダクトバックログを見て、次の項目に着手する。
(この時、開発チームからプロダクトオーナーに連絡をする)
ベロシティに惑わされるな!
ベロシティは先のことを考えるのに必要不可欠。ベロシティに求められるのは安定をしていること。
ベロシティを無理にあげるのはよくないが、日々の作業を工夫したり協力することによって、作業をよりうまく進めていくことが大切。ベロシティはあくまで目安。
みんなで協力して進めていく
スクラムチームが全員参加すると決められているイベント
・スプリント計画ミーティング
・スプリントレビュー
・スプリントレトロスペクティブ
ユーザーストーリー
フォーマット
<どういったユーザーや顧客>として
<どんな機能や性能>が欲しい
それは<どんなことが達成したい>ためだ
このフォーマットで書けば、プロダクトオーナーや開発チームでの誤解が生じにくくなる。
プロダクトバックログはこまめに手入れをする
プロダクトバックログは誰でも自由に書き込めるようにしておいて、様々な意見を取り入れていく。
・重要なことを見逃さないように順序を見直す。
・見積もりを最新にする。
・プロジェクトの進む先を整理するために順序をもう一回見直す。
手戻りをなくしていく
手戻りは実現したいことが曖昧な時に起こる。
プロダクトオーナーは、プロダクトバックログの中から直近で実現したい項目を明確にしていくことに注力する。
手戻りをなくしていくために、スクラムチームは以下のことに取り組む。
・実現したいことは先に深く理解しておく。
・決めるべき仕様を決めておく。
・技術的にどういう風に実現するといいか理解しておく。
協力をして乗り越えていこう!
スクラムではスプリント期間中に様々な作業をしなくてはならない。状況に応じて誰かがリーダーシップを取ることが大切。
そのために、スキルマップを書いてみるのも良い。
そのために以下のことを話し合ってみる。
・これまでどんなプロジェクトにいたか。
・自分が仕事をする上で大切にしていること。
・自分に期待されていることはなんだと思うか。
今度の金曜日にある会議では、この本の内容を思い出しながら出席しよう!