テストとは
テストについてまとめていきます。
そもそもテストとは、コードを書いてブラウザで表示させてエラーがあったらそれを修正してまたブラウザで表示して、、という手動テストを自動化する機能です。
◆テストには3種類あります。
- 単体テスト(unitテスト):モデルやヘルパーのテスト
- 機能テスト(functionalテスト):コントローラのテスト
- 統合テスト(integrationテスト):実際のリクエストをシュミレーションするテスト
◆では、これらは実際何をテストするのか?
- 単体テスト * モデルの検索系メソッド(findなど)が正しいデータを取得できるか * モデルの更新系メソッド(saveなど)が正しくデータベースの状態を変化させるか * モデルの更新系メソッドが不正な入力に対して適切なエラーを発生させるか(値の検証の確認)
- 機能テスト * 適切なテンプレートが選択されているか * インスタンス変数に適切な値が格納されているか * 適切にレンダリングされているか、あるいは適切なURLにリダイレクトされているか * 更新系のアクションが正しくデータベースの状態を変化させるか
- 統合テスト * 例えば、ログインして名簿に新しいメンバーを追加してログアウトする、といった一連の動きをテストする 統合テストはユーザーが使う流れをシミュレートするテストで、あんまり書きません。機能テストに書けちゃうので。
◆テスト駆動開発
テストはバグを調べるためだけのものではなく、機能を実装する前にテストを行うこともできます。 仕様を明確にするためにテストをつくり、テストを通すためにコーディングを行う、というスタイルのことをテスト駆動開発と言います。 テスト駆動開発は以下の流れで行っていきます。①テストを書く ある機能が正しく実装されていれば成功し、そうでなければ失敗するようなテストスクリプトを作る ⇒機能が動く条件を定める =仕様決め
②テストが失敗することを確認 テストスクリプトを実行 ∟成功⇒テストスクリプトが上手く書けてない ∟失敗⇒エラーの表示を詳しく調べ、 テストスクリプト自体のバグやデータベースの 設定ミス等による失敗ではないか確認
③テストが成功するよう実装 実際のコーディング。目標はテストを通すこと。 この段階では多少コードが汚くてもOK。
④リファクタリング コードを綺麗にする。 「テストが成功する」という状態を維持したままプログラムを書き換える。 変数名を変える、長すぎるメソッドを分割する、コードの重複部分を除く、など。
①テストを書く
②...以下繰り返し
このテスト駆動開発によって単純な短いサイクルを繰り返せば、コーディングの目標が明確になり、プログラマの負担を減らすことが出来ます。
次のテーマではテストスクリプトについて説明します。
最後までお読みいただきありがとうございます!
フォームとモデル
モデルとフォームの連携
データベースからデータを取り出し、フォームに表示し、ユーザーの操作によって情報を更新する、といった一連の流れは、Railsでは以下のようになります。
レコード(モデル)
コントローラ
モデルのオブジェクトをテンプレート(ビュー)に渡し、
テンプレートではそのオブジェクトを使ってHTMLのフォームを作成
↓
フォーム(ビュー)
コントローラ
↓ 保存
レコード(モデル)
※Memberモデルと関連したフォームからデータが送信された場合は、paramsの中身は以下のようになります。
params = { :id => 2,
:member => {
:family_name => '鈴木',
:given_name => '弘',
:member_number => 11,
}
}
このとき、paramsが入れ子になったハッシュになっています。
paramsの要素の1つをparams[:member]として取り出すと、それ自体もハッシュになっています。このparams[:member]をモデルクラスのメソッドに渡せば、簡単にレコードの作成や更新ができます。
フォームの記述
テンプレートでフォームを記述するには、form_forメソッドを使います。form_forメソッドの引数には、
・モデル名(次の例の:member)
・コントローラで作成したモデルオブジェクト(次の例の@member)
・オプション
を指定します。
モデル名とモデルオブジェクトの変数名が同じ場合は、モデルオブジェクトを省略できます。
オプションのうち、:urlには「:url => { :action => アクション名, :id => idパラメータ }」のように、フォーム名の送信先のアクションを指定します。これは、フォームの送信先(form要素のaction属性)に変換されます。
:htmlオプションを使うと、CSSでのデザインのためにclass属性やid属性を指定できます。
また、「:html => { :method => :put }」のようにしてHTTPのメソッド(form要素のmethod属性)も指定できます。HTTPのメソッドを指定しない場合は、自動的にPOSTメソッドになります。
<% form_for :member, @member,
:url => { :action => 'update', :id => @member },
:html => { :class => 'member_form' } do |form| %><% end %>
form_forメソッドは、ブロックを受け取ります。ブロックの中には、テキスト入力欄や送信ボタンのようなフォームの部品を記述します。ブロックの引数として渡されるのは、フォームビルダーオブジェクトと呼ばれる特別なオブジェクトです。
form_forメソッドを記述するときは「<%=」で始めずに、「<% form_for...」と書きます。フォームの各部品を記述するときは「<%= form.text_field...」と書きます。
<% form_for :member, @member,
:url => { :action => 'update', :id => @member },
:html => { ;class => 'member_form' } do |form| %>
姓:<%= form.text_field :family_name %>
名:<%= form.text_field :given_name %>
<%= submit_tag '更新' %>
<% end %>このテンプレートは、以下のようなHTMLコードに変換されます。フォームの各部品には、自動的にid属性とname属性が振られます。
テンプレート側ではfamily_nameの値について何の処理もしてないのに、value属性に現在の値(佐藤)がセットされる形になっています。値のセットはRailsが自動的にやってくれます。
テーブルの作成
モデルの作成
テーブルを作成する前に、モデルを作成しましょう。モデルを作成するには、コントローラを作成したときのように、コマンドプロンプトからscript\generateスクリプトを実行します。
cd\rails\アプリケーション名
ruby script\generate model member
Railsの命名規約では、モデルに対応するデータベースのテーブル名はmembersのように複数形になります。モデルのクラス名はMemberのように頭が大文字の単数形になります。
マイグレーション
次に、Memberモデルに対応するmembersテーブルを作りましょう。Railsでは、データベースのテーブルの作成や変更にマイグレーションという機能を使います。マイグレーションを使うと、自動的にテーブルのフィールドを定義できるだけでなく、開発の途中でフィールドを追加したり変更したりする作業も楽に行えます。
script\generateスクリプトでモデルを作成すると、db\migrateフォルダの下に001_create_members.rbというファイルができます。このファイルをマイグレーションスクリプトと呼びます。
マイグレーションスクリプトを開いてみると、CreateMembersクラス(マイグレーションクラス)にupとdownという2つのクラスメソッドがあります。upメソッドの中のcreate_tableメソッドはテーブルの作成を行うもので、このメソッドに渡すブロックの中にフィールドを記述します。
フィールドは
t.column:フィールド名,:フィールドの型
という形で記述します。
ex.
create_table :members do |t|
t.column :family_name, :string # 名前(姓)
t.column :given_name, :string # 名前(名)
end
マイグレーションスクリプトを使ってテーブルを実際に作成するには、Rakeタスクdb:migrateを使います。
★membersテーブルの作成
主キーのフィールドは、idという名前で自動的に作られます。製品番号や会員番号のようなフィールドを作りたい場合は、idとは別にフィールドを用意します。マイグレーションスクリプトを記述したら、コマンドプロンプトでrakeタスクのdb:migrateを実行します。マイグレーションスクリプトによってデータベースにテーブルが作成され、フィールドが加えられます。データベースへの接続は、YAMLファイルの設定に従います。
cd\rails\club
rake db:migrate
テーブルが加えられるデータベースは、開発用のもの(hoge_development)になります。本番用のデータベースでマイグレーションを行いたい場合は以下のように記述します。
cd\rails\club
rake db:migrate RAILS_ENV=production
マイグレーションの詳細
★マイグレーションとバージョン
フィールドを変更するときは、db\migrateフォルダに「002_hoge.rb」、「003_fuga.rb」のように頭を連番にしたマイグレーションスクリプトを加えていきます。ex.
positionフィールドを追加したいときは、002_add_position.rbのような名前のファイルを作成し、001_create_members.rbと同じようにクラスとメソッドを記述します。マイグレーションクラスの名前はファイル名から連番とアンダーバーを取り除き、頭文字を大文字にします。
upメソッドにはフィールドを追加するメソッド「add_column:テーブル名,:フィールド名,:型」を記述します。
コマンドプロンプトで「rake db:migrate」を実行すると、自動的に新しいバージョンである002_add_position.rbが読みこまれ、フィールドが追加されます。
ファイル名の頭の「001」や「002」はマイグレーションのバージョンを表しています。
「002」のマイグレーションを行ったあとでもう一度db:migrateタスクを実行しても、既にバージョンが2になっているため何も起こりません。
古いバージョンに戻したいときは、以下のようにdb:migrateタスクにバージョン番号を指定します。現在のバージョンが2のときは、002_add_position.rbのdownメソッドが実行されてフィールドが削除される、という仕組みになっています。
cd\rails\アプリケーション名
rake db:migrate VERSION=1
★インデックス
多くのDBMSでは、フィールドにインデックスを加えることができます。これによって特定のフィールド値を持つレコードを検索しやすくでき、データベース検索の高速化が可能です。ただし、テーブルと別に索引情報を持つことになるので、メモリが大きく消費されることになります。通常は「名前」のようによく検索対象になるフィールドに設定します。
Railsのマイグレーションスクリプトでインデックスを設定するには、add_indexメソッドを使います。
ex.
add_index :member, :first_name,
:unique => true, :name = 'fname_index'
インデックスを削除するには、remove_indexメソッドを使います。:columnでフィールド名を指定するか、:nameでインデックス名を指定します。
ex.
remove_index :member, :column => 'first_name'
remove_index :member, :name => 'fname_index'
データベースとモデルの基本
データベースとは
ここで言うデータベースとは、リレーショナルデータベースのことを指します。データベースはテーブルの集合で出来ており、各行(レコード)が1つのデータを表し、列(フィールド)がそのデータの属性を表します。
商品番号 (整数) |
商品名 (文字列) |
価格 (整数) |
発売日 (日付) |
1 | 掛け時計 | 1890 | 2007/03/09 |
2 | ティッシュケース | 1050 | 2006/12/15 |
3 | マグカップ | 609 | 2007/02/28 |
Railsのモデル
Railsでは、データベースとのやり取りを行うクラスをモデルと呼びます。モデルはデータベースのテーブルに対応するクラスです。 モデルクラスのインスタンスは、1つの行(レコード)を丸々表すオブジェクトになり、そのオブジェクトはさっきのテーブルの列(フィールド)に相当する属性を持ちます。 つまり、 DBMSのテーブル=Railsのモデルクラスであり、 モデルクラスのインスタンスは以下3点のような各行となる。 このインスタンスは「:」以下の3つの属性を持つ。 ・商品番号1:掛け時計、1890円、2007/03/09に発売 ・商品番号2:ティッシュケース、1050円、2006/12/15に発売 ・商品番号3:マグカップ、609円、2007/02/28に発売 ということです。★コードについて
Railsのモデルでは、以下のようなコードを記述してデータベースを扱います。 ①product = Product.find(123) #123番の商品 ②name = product.name #nameフィールドから値を取り出す ③product.price = 1980 #priceフィールドに値を設定 ①では123番の商品を表すレコードを取り出します。モデルクラスのfindメソッドに番号を渡します。 ②はレコードから値を取り出したり入れたりするときに使います。 ③はそのまんま、値を設定します。 Railsのモデルはメソッド呼び出しを自動的にSQL文に変換してDBMSに送信します。★主キーについて
主キーとは、レコードを識別するためのID番号です。 データベースのテーブルには、たいてい主キーとなるフィールドを作成します。 1つのテーブルで主キーの値が同じレコードを複数作ることはできません。 Railsのモデルでは、テーブルに決まった形式の主キーを必ず設定することになっています。 主キーとなるフィールドの名前はidです。値は整数の連番になります。接続の設定とデータベースの作成
一からデータベースを作成する際は、次の順で作業をします。- DBMSへの接続の設定
- データベースの作成
- テーブルの定義と作成
- テーブルに入れるデータの作成
★接続の設定
Railsでは、接続の設定はconfigフォルダにあるdatabase.ymlで行います。このファイルはRailsアプリケーションを作成したときに自動的に作られますが、文字コードの指定は自動的に記述されないので、自分で encoding: utf8 を追加します。 Railsではデータベースは3つ用意することになっています。 開発用、テスト用、本番用です。 データベース名はそれぞれ 「アプリケーション名_development」 「アプリケーション名_test」 「アプリケーション名_production」 となります。こうしたデータベース名は変更可能です。 database.ymlでは、3つのデータベースに対して接続のための設定を行えます。設定名 | 内容 |
adapter | DBMS名 |
database | データベース名 |
username | DBMSのユーザ名 |
password | DBMSのパスワード |
host | DBMSのホスト名またはIPアドレス(自分のPCならlocalhost) |
port | DBMSのポート名(省略するとデフォルト) |
encoding | データベースの文字コード。utf8 |
★データベースの作成
データベースの作成はRailsでは自動的に行えないので、MySQLにログインして直接コマンドを実行する必要があります。手作業でデータベースを作成する場合は、コマンドプロンプトを開き、以下のように入力します。作成するのは開発用とテスト用のデータベース2つです。 C:\>mysql -u root # ユーザ名rootでログイン mysql> drop database if exists hoge_development; # 開発用データベースが既にあれば削除 mysql> drop database if exists hoge_test; # テスト用データベースが既にあれば削除 mysql> create database hoge_development character set utf8; # 開発用データベースを作成 mysql> create database hoge_test character set utf8; # テスト用データベースを作成 mysql> exit # MySQLからログアウト初歩の初歩-WEBrickの起動方法
いっつも忘れちゃうのでメモ。
穴があったら入りたいぐらいの初歩の初歩ですが…
★WEBrickの起動方法
cd \ rails \ asagao
① ② ③
ruby script\server
④ ⑤
①今から以下のディレクトリに移動します(2010/8/13 訂正)
②railsフォルダの中の
③asagaoっていうアプリケーションに入ってる、
④rubyコマンドの
⑤script\server
を起動してください。
っていうコマンドをコマンドプロンプトに入力します。
③のアプリケーション名だけ任意ですが、その他は決まり文句です。
こんな内容を書くのは憚られますが、
私みたいな純文系且つPCにもそんな詳しくない人が
プログラミングを始める際に
少しでもお役に立てればと思います。。m(_ _;)m
初日記!
テストも兼ねての初日記です。
このデザイン、妙に気に入ってしまいましたw
今後はたくさんアウトプットしていきたいと思います!
どうぞ宜しくお願いいたします(´∀`*)