[社会][web&リアル]文化の地域格差は人の格差か?— はてブついでに覚書。
文化の発信はどこからでもできるが,文化は中央に集約してしまう。そりゃそうだ。観客の数が違う。数が多いとフィードバックが多い。文化は発信だけでなく,反応もなければ成立しない。
例えば,地元鹿角市には正月2日に大日霊貴神社(大日堂,だいにちどうといった方が地元では通じるだろう。)で舞を奉納している。うちの集落谷内では,「五大尊舞」という演目が伝承されている。この日は県内の報道機関やアマチュアカメラマンが一同に集り,カメラのフラッシュがたかれる。
参考 大日堂舞楽(鹿角市)がユネスコ無形文化遺産の「代表一覧表」に記載されました
伝聞のように書いてあるのは,実は私は全く知らない。実は集落の人,特に同年代の方々を全く知らないのだ。自分が参加していないのが悪いんだろうと言われるが,引きこもり的な資質もあり中々進んでいけない。集落の方々が共有して持っている少年青年期に体験したことを私は全くしていない。理由は簡単。父が転勤族のため,小・中・高校と全て違うところで生活してきたからだ。
最初に戻ろう。文化の発信は1人でもできる。しかし,必ずしもフィードバックが得られるとは限らない。まだ東京の方が可能性がある。
文化の格差というよりも,文化を共有できる関係を求めるのが人間の性だと思う。San Jose近郊のBay areaに集まる人や,東京に集まる人。などなど。
Monday, October 26, 2009
フィードバックが得られない文化を維持していくことは難しい
Tuesday, October 13, 2009
Add new user (2) - Reading Tracks (5)
今日の課題
unless User.no_users_yet? || (@user && @user.is_admin?)
@page_title = "No signups"
@admin_email = User.find_admin.preference.admin_email
render :action => "nosignup", :layout => "login"
return
end
Userが登録されているにもかかわらず,admin以外のユーザが登録しようとしても失敗させるためのケース。
user = User.new(params['user'])
で,モデルUserのインスタンスを生成し,その次の評価で,作成するインスタンスのvalid性を評価している。
unless user.valid?
session['new_user'] = user
redirect_to :action => 'new'
return
end
validでないUserインスタンスならば,"/user/new" にリダイレクトさせて,その際にerror内容を表示させるのだろう。
first_user_signing_up = User.no_users_yet?
user.is_admin = true if first_user_signing_up
ここで,最初のuser登録かチェックしている。つまり,最初に登録されるユーザは必ずadmin権限を持つようになっている。
if user.save @user = User.authenticate(user.login, params['user']['password']) @user.create_preference @user.save session['user_id'] = @user.id if first_user_signing_up notify :notice, "Signup successful for user #{@user.login}." redirect_back_or_home end return最後に,新しく生成したインスタンスが保存できるのならば,redirect_back_or_home され,処理を終える。
おもしろい。このまま,tracks Applicationの実装を読み進めていこう。それと並行してRails applicationの試作を行ってみたい。
Monday, October 12, 2009
Add new user - Reading Tracks (4)
今日の課題
ユーザ登録はどのようにやっているのか?具体的には,
192.168.1.102 - - [08/Oct/2009:22:52:51 JST] "POST /users HTTP/1.1" 302 92
http://192.168.1.101:3000/users/new -> /users
ここで,どんな処理をしているのか?早速,user_controller.rb の該当するコードを参照してみる。
# Example usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml'
# -u admin:up2n0g00d
# -d '<request><login>username</login><password>abc123</password></request>'
# http://our.tracks.host/users
#
# POST /users
# POST /users.xml
def create
if params['exception']
render_failure "Expected post format is valid xml like so: <request><login>username</login><password>abc123</password></request>."
return
end
respond_to do |format|
format.html do
unless User.no_users_yet? || (@user && @user.is_admin?)
@page_title = "No signups"
@admin_email = User.find_admin.preference.admin_email
render :action => "nosignup", :layout => "login"
return
end
user = User.new(params['user'])
unless user.valid?
session['new_user'] = user
redirect_to :action => 'new'
return
end
first_user_signing_up = User.no_users_yet?
user.is_admin = true if first_user_signing_up
if user.save
@user = User.authenticate(user.login, params['user']['password'])
@user.create_preference
@user.save
session['user_id'] = @user.id if first_user_signing_up
notify :notice, "Signup successful for user #{@user.login}."
redirect_back_or_home
end
return
end
format.xml do
unless User.find_by_id_and_is_admin(session['user_id'], true)
render :text => "401 Unauthorized: Only admin users are allowed access to this function.", :status => 401
return
end
unless check_create_user_params
render_failure "Expected post format is valid xml like so: <request><login>username</login><password>abc123</password></request>."
return
end
user = User.new(params[:request])
user.password_confirmation = params[:request][:password]
if user.save
render :text => "User created.", :status => 200
else
render_failure user.errors.to_xml
end
return
end
end
end
まず最初の例外処理を見てみる。
if params['exception']
render_failure "Expected post format is valid xml like so: <request><login>username</login><password>abc123</password></request>."
return
end
想定外のXML文書が来たかどうかだと思う。想定外かどうか判断するには,モデルuserを参照するのだろう。validates_presence_of には,:login と :password があり,:login は 3文字以上80文字以下などなどと制限を設けている。そして失敗したら,render_failure で失敗理由を明示し,元に戻っている。実際のテストコードでも,このような内容のテストが行なわれている。test/functional/users_controller_test.rb の以下のテストだ。
def test_create_with_invalid_password_does_not_add_a_new_user
login_as :admin_user
assert_no_difference(User, :count) do
post :create, :user => {:login => 'newbie', :password => '', :password_confirmation => ''}
end
end
def test_create_with_invalid_password_redirects_to_new_user_page
login_as :admin_user
post :create, :user => {:login => 'newbie', :password => '', :password_confirmation => ''}
assert_redirected_to :controller => 'users', :action => 'new'
end
def test_create_with_invalid_login_does_not_add_a_new_user
login_as :admin_user
post :create, :user => {:login => 'n', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
assert_redirected_to :controller => 'users', :action => 'new'
end
def test_create_with_invalid_login_redirects_to_new_user_page
login_as :admin_user
post :create, :user => {:login => 'n', :password => 'newbiepass', :password_confirmation => 'newbiepass'}
assert_redirected_to :controller => 'users', :action => 'new'
end
なるほど,最初のテストではinvalidなpasswordを持つuserをUserに追加させていない。他の3つは,invalidな:login,:password を持つuserの作成に対するrequestに対して, /users/new に redirect されているかどうかをテストしている。(警告メッセージが出ているのかどうかテストするにはどうすればいいのだろうか。)次の行からは,
respond_to do |format|
と始まっているように,responseを作成している箇所であることを確認して,ここまでとする。早速以下の処理内容を理解できないので,じっくりと把握していきたい。
unless User.no_users_yet? || (@user && @user.is_admin?)
@page_title = "No signups"
@admin_email = User.find_admin.preference.admin_email
render :action => "nosignup", :layout => "login"
return
end
HTTP POST Method - Reading Track (3)
今日の課題
POSTの内容はどうなっているのか?誰がPOSTの内容をXML文書に成形しているのか?
<request><login>username</login><password>abc123<password></request>
POSTリクエストを送信したときのパケットをキャプチャしてみた。TCP payloadの内容を以下に記す(passwordの箇所は"password"でマスクした)。
POST /login HTTP/1.1
Host: 192.168.1.101:3000
User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.3) Gecko/20091007 Ubuntu/9.10 (karmic) Firefox/3.5.3 GTB5
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-2022-JP,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://192.168.1.101:3000/login
Cookie: preferred_auth=database; tracks_login=admin; _tracks_session_id=e22a17f51266e7fa3b30fb6cd3def1fb
Content-Type: application/x-www-form-urlencoded
Content-Length: 139
authenticity_token=2fc78f9b3f11d9447cdc5719f19742bdfe9b531f&user_login=admin&user_password=password&user_noexpiry=on&login=Sign+In+%C2%BB
Studying HTTPは,HTTP/1.1 Post Methodについて解説していただいている。そこを参照すると,Content-Type: application/x-www-form-urlencoded はエンテティボディのメディアタイプとして一般的に利用されているタイプの一つで,今回のUser-Agent (Firefox 3.5.3) は,この方式でエンティティを送信しているものと考えられる。このように,規格があるのならば,このようなRequestパケットを受信したRailsアプリケーションがurlencodedなデータから,validなXML-documentを生成するのは簡単だろう。他のブラウザではどのような形式で送信するかわからないが,そこのところはRailsでwrapperしているものと考えればいいのだろう。
Rails Application - Reading Tracks (2)
user_controller.rb
Track applicationでユーザー(admin)を登録した時のコンソール出力から何が起きているか確認してみる。まず,user_controller.rb のアクション new の内容を確認する。
# GET /users/new
def new
if User.no_users_yet?
@page_title = "TRACKS::Sign up as the admin user"
@heading = "Welcome to TRACKS. To get started, please create an admin account:"
@user = get_new_user
elsif @user && @user.is_admin?
@page_title = "TRACKS::Sign up a new user"
@heading = "Sign up a new user:"
@user = get_new_user
else # all other situations (i.e. a non-admin is logged in, or no one is logged in, but we have some users)
@page_title = "TRACKS::No signups"
@admin_email = User.find_admin.preference.admin_email
render :action => "nosignup", :layout => "login"
return
end
render :layout => "login"
end
@page_title というのが出てきた。先ほど指定した @page_title が埋めこまれている。おそらく <%= render :partial => "shared/footer" %> は共通のfooterを埋めこんでいるのだろう。
さて,<%= yield %> は何ものか?これはActionController::Layoutのクラスメソッドの説明を読んで考えてみると,どうやらtitleとかfooterは共通にしたいけど,login 画面は個別のviewを埋めこみたいと考えているのだろうか。ここで,"/users/new" リクエストでアクセスしてきたことを思いだす。app/views/users/new.html.erb が定義されてあった。 ここでユーザーAccount Signupのviewを生成しているのだなと確認できる。
さて,submitボタンを押したときに,コンソール画面には以下の内容が表示されている。
192.168.1.102 - - [08/Oct/2009:22:52:51 JST] "POST /users HTTP/1.1" 302 92
http://192.168.1.101:3000/users/new -> /users
# Example usage: curl -H 'Accept: application/xml' -H 'Content-Type: application/xml'
# -u admin:up2n0g00d
# -d 'username abc123 '
# http://our.tracks.host/users
#
# POST /users
# POST /users.xml
def create
if params['exception']
render_failure "Expected post format is valid xml like so: username abc123 ."
return
end
respond_to do |format|
format.html do
unless User.no_users_yet? || (@user && @user.is_admin?)
@page_title = "No signups"
@admin_email = User.find_admin.preference.admin_email
render :action => "nosignup", :layout => "login"
return
end
user = User.new(params['user'])
unless user.valid?
session['new_user'] = user
redirect_to :action => 'new'
return
end
first_user_signing_up = User.no_users_yet?
user.is_admin = true if first_user_signing_up
if user.save
@user = User.authenticate(user.login, params['user']['password'])
@user.create_preference
@user.save
session['user_id'] = @user.id if first_user_signing_up
notify :notice, "Signup successful for user #{@user.login}."
redirect_back_or_home
end
return
end
format.xml do
unless User.find_by_id_and_is_admin(session['user_id'], true)
render :text => "401 Unauthorized: Only admin users are allowed access to this function.", :status => 401
return
end
unless check_create_user_params
render_failure "Expected post format is valid xml like so: username abc123 ."
return
end
user = User.new(params[:request])
user.password_confirmation = params[:request][:password]
if user.save
render :text => "User created.", :status => 200
else
render_failure user.errors.to_xml
end
return
end
end
end
<request><login>username</login><password>abc123</password></request>
Thursday, October 08, 2009
Rails Application - Reading Tracks (1)
ここでは,Rails Application, Tracksの振舞いを見てみる。
Tracks を動かすのは簡単だ。自分は Rails 2.3.3 の環境を構築して,SQLite3,libsqlite3-ruby をインストールすれば準備完了。Download ページから 1.7 release を展開して,rake db:migdate を実行した後,server を実行する(databaseのconfigは用意されてある)。
起動してみて,webブラウザでアクセスすると,コンソールに以下の内容が表示される。
192.168.1.102 - - [08/Oct/2009:21:57:59 JST] "GET / HTTP/1.1" 302 97
- -> /
192.168.1.102 - - [08/Oct/2009:21:57:59 JST] "GET /login HTTP/1.1" 302 101
- -> /login
192.168.1.102 - - [08/Oct/2009:21:58:00 JST] "GET /users/new HTTP/1.1" 200 2523
- -> /users/new
どうやら login controller を経由して,users_controller の new アクションを実行している模様。
config/routes.rb の内容を確認してみると,
ActionController::Routing::Routes.draw do |map|
map.with_options :controller => 'login' do |login|
login.login 'login', :action => 'login'
login.formatted_login 'login.:format', :action => 'login'
login.logout 'logout', :action => 'logout'
login.formatted_logout 'logout.:format', :action => 'logout'
end
# snip
とあるので,login controller の login action を呼びだしている模様。login.login とか login.formatted_login とかが何を表現しているのかがよくわからない。これは "/login" や "login.m" というリクエストに対して名前をつけたと考えていいのだろうか?このことを確認するため,ユーザ登録後に "/login","/login.m","/login.xml" というリクエストを発行した。login_controller の login method の最後の方に,こんな表示がある。
respond_to do |format|
format.html
format.m { render :action => 'login_mobile.html.erb', :layout => 'mobile' }
従って最後の "/login.xml" は xml 形式のrespondが定義されていないので,何も表示されない。実際に "/login.xml" では何も表示されない。また "/login.m" ではいかにも携帯電話用のログイン画面が表示された。さて,login_controller.rb の内容に戻ってみる。
def login
if openid_enabled? && using_open_id?
login_openid
else
@page_title = "TRACKS::Login"
case request.method
# snip
when :get
if User.no_users_yet?
redirect_to :controller => 'users', :action => 'new'
return
end
end
# snip
end
end
とあるので,ユーザを未登録の場合,users controller の action new へ redirect されているのがわかる。
次にユーザ(admin)を登録してみる。コンソール出力は以下の通り。
192.168.1.102 - - [08/Oct/2009:22:52:51 JST] "POST /users HTTP/1.1" 302 92
http://192.168.1.101:3000/users/new -> /users
192.168.1.102 - - [08/Oct/2009:22:52:52 JST] "GET / HTTP/1.1" 200 10825
http://192.168.1.101:3000/users/new -> /
192.168.1.102 - - [08/Oct/2009:22:53:01 JST] "GET /stylesheets/cache/bundle.css?1255009973 HTTP/1.1" 200 29449
http://192.168.1.101:3000/ -> /stylesheets/cache/bundle.css?1255009973
192.168.1.102 - - [08/Oct/2009:22:53:01 JST] "GET /behaviours/index.js HTTP/1.1" 304 0
http://192.168.1.101:3000/ -> /behaviours/index.js
192.168.1.102 - - [08/Oct/2009:22:53:01 JST] "GET /javascripts/cache/bundle.js?1255009981 HTTP/1.1" 200 247440
http://192.168.1.101:3000/ -> /javascripts/cache/bundle.js?1255009981
次から users_controller.rb の内容を追ってみようと思う。
Rails Integration Test (1)
A Guide to Testing Rails Applications
5. Integration Testing
Integration テスト: (複数の)コントローラ間の通信をテストすること。important work flowsをテストするのに使われる。
RailsにはIntegrationテスト用のスケルトンコード作成機能が備わっている。
% script/generate integration_test user_flows
exists test/integration/
create test/integration/user_flows_test.rb
内容は,こんな感じ。
require 'test_helper'
class UserFlowsTest < ActionController::IntegrationTest
fixtures :all
# Replace this with your real tests.
test "the truth" do
assert true
end
end
ここで,fixturesというのが出てきた。
5.1 Helpers Available for Integration Tests
どんな helper が使えるのかという内容。リンク先のテーブル参照。
ここまで読んで,その後もざっと流し読みしたが,自分の中のRailsやTDDについてのイメージがまだ浮かんでこないので,ここで実際のアプリケーションに立ち入って理解していきたいと思う。
Monday, October 05, 2009
Rails Functional Test (2)
A Guide to Testing Rails Applications
昨日の復習
test "should create post" do
assert_difference('Post.count') do
post :create, :post => { :title => 'Hi', :body => 'This is my first post.' }
end
assert_redirected_to post_path(assigns(:post))
assert_equal 'Post was successfully created.', flash[:notice]
end
というテストコードを書いた。最初の"post :create, :post => { :title => 'Hi', :body => 'This is my first post.' }" はpostコントローラにcreate アクションを実行。":post" symbol にpost controllerのcreate actionに対する引数を与えた。(パラメータは{ :title => 'Hi', :body => 'This is my first post.' }) 次のassert文 "assert_redirected_to post_path(assigns(:post))" 。よくわからないが,"format.html { redirect_to(@post) }" に関連したテストなのだろうか?
最後のassert文,"assert_equal 'Post was successfully created.', flash[:notice]" で,flash[:notice]に "Post was successfully created" が渡されているかどうかをテスト。post_controller.rb を見ると,flash[:notice] に "Post was successfully created" が引き渡されていた。
続き。def create @post = Post.new(params[:post]) respond_to do |format| if @post.save flash[:notice] = 'Post was successfully created.' format.html { redirect_to(@post) } format.xml { render :xml => @post, :status => :created, :location => @post } else format.html { render :action => "new" } format.xml { render :xml => @post.errors, :status => :unprocessable_entity }
4.6 Testing Views
viewのテストとして,key HTML elementsの存在やコンテンツに対するassertingをすることによって,viewのテストを行う。
"assert_select" を使うことで,simpleだけどpowerfulなsyntaxを使うことができる。
assert_selectの形式:
assert_select (selecter, [equality], [message]) | ensures that the equality condition is met on the selected elements through the sector. The selector may be a CSS selector expresion (String), an expression with substitution valutes, or an HTML::Selector object. |
assert_select (element, selecter, [equality], [message]) | ensures that the equality condition is met on all the selected elements through the selector starting from the element (instance of HTML::Node) and its descendants. |
assert_select 'title', "Welcome to Rails Testing Guide"
あまり用途がわからない。他の用法等を参照してみる。
Sunday, October 04, 2009
Rails Functional Test (1)
A Guide to Testing Rails ApplicationsのFunctional Tests for Your Controllersから再開。
4. Functional Tests for Your Controllers
Rails における,functional test: controller単体の様々なアクションをテストすること。Controllersはimcoming web-requestをアプリケーションに受け渡し,その結果rendered viewを返答する。4.1 What to Include in your Functional Tests
テストすべき項目- was the web request successful? (日本語では何といえばいい?成功したweb request?ちゃんとしたweb requestであるか?)
- was the user redirected to the right page? 正しいページにリダイレクトされたか?
- was the user successfully authenticated? (ユーザーはちゃんと認証されたか?)
- was the correct object stored in the response template? (正しいオケクトがレスポンステンプレートの中に記録されたか?)
- was the appropriate message displayed to the user in the view? (適切なメッセージがユーザにview表示されたか?)
tutorialでは test_should_get_index というメソッドが定義されているが,ここでは
test "should get index" do
get :index
assert_response :success
assert_not_nil assigns(:posts)
end
となっているので今回も,これを見てみる。"should get index"テストでは,Railsは "index" アクションを要求して, request が成功したかどうかを,そして更に妥当な posts インスタンス変数を割りあてているかどうかテストを確認している。
"get" メソッドはweb requestを発行して,結果をレスポンスに反映させている。It (="get" method) accepts 4 arguments:
- リクエストするコントローラのアクション。文字列,もしくはsymbol形式で与える。
- (Optional)アクションに引き渡すリクエストパラメータのオプショナルハッシュ (eg. クエリー文字列やポスト変数)。
- (Optional)リクエストに沿った内容のセッション変数のハッシュ
- (Optional)フラッシュ値(メッセージ)
get(:show, {'id' => "12"}, {'user_id' => 5})
例題。:view アクションを呼びだす。その際,"12"というidをパラメータとして与える。セッションは確立されないとするが,フラッシュメッセージが添えられている。
get(:view, {'id' => "12"}, nil, {'message' => 'booya!'))
ここで先に進む前に,Post モデルに "validates_presence_of :title" を追加したことを思い出す。
If you try running test_should_create_post test from posts_controller_test.rb it will fail on account of the newly added model level validation and rightly so.と書いてあるように,Testがパスできるように test_should_create_post に手を加える。
test "should create post" do
assert_difference('Post.count') do
post :create, :post => { :title => 'Some title' }
end
assert_redirected_to post_path(assigns(:post))
end
実際にfunctional testを実行してみた。変更前
/home/abekatsu/webroot/TestingRails% rake test:functionals
(in /home/abekatsu/webroot/TestingRails)
/usr/bin/ruby1.8 -I"lib:test" "/home/abekatsu/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/posts_controller_test.rb"
Loaded suite /home/abekatsu/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
F......
Finished in 0.236084 seconds.
1) Failure:
test_should_create_post(PostsControllerTest) [/test/functional/posts_controller_test.rb:16]:
"Post.count" didn't change by 1.
<3> expected but was
<2>.
7 tests, 9 assertions, 1 failures, 0 errors
rake aborted!
Command failed with status (1): [/usr/bin/ruby1.8 -I"lib:test" "/home/abeka..."]
(See full trace by running task with --trace)
変更後
/home/abekatsu/webroot/TestingRails% rake test:functionals
(in /home/abekatsu/webroot/TestingRails)
/usr/bin/ruby1.8 -I"lib:test" "/home/abekatsu/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader.rb" "test/functional/posts_controller_test.rb"
Loaded suite /home/abekatsu/.gem/ruby/1.8/gems/rake-0.8.7/lib/rake/rake_test_loader
Started
.......
Finished in 0.23919 seconds.
7 tests, 10 assertions, 0 failures, 0 errors
4.2 Available Request Types for Functional Tests
Railsのfunctional テストでサポートされているリクエストタイプ:- get
- post
- put
- head
- delete
4.3 The Four Hashes of the Apocalypse
先程の5つのメソッドでリクエストが作成されると,次の4つのタイプのハッシュオブジェクトを使用できる。- assigns - Any objects that are stored as instance variables in actions for use in views.
- cookies - Any cookies that are set.
- flash - Any objects living in the flash
- session - Any objected in session variables.
flash["gordon"] flash[:gordon] session["shmession"] session[:shmession] cookies["are_good_for_u"] cookies[:are_good_for_u] # Because you can't use assigns[:something] for historical reasons: assigns["something"] assigns(:something)
4.4 Instance Variables Available
functional testに次の3つのインスタンス変数にアクセスできる。- @controller – The controller processing the request
- @request – The request
- @response – The response
4.5 A Fuller Functional Test Example
test "should create post" do
assert_difference('Post.count') do
post :create, :post => { :title => 'Hi', :body => 'This is my first post.' }
end
assert_redirected_to post_path(assigns(:post))
assert_equal 'Post was successfully created.', flash[:notice]
end
Saturday, October 03, 2009
Rails Unit Test
これまでの流れ。 A Guide to Testing Rails Applicationsを読んでいる。
確認
test "post should not save without title" do
post = Post.new
assert !post.save, "Saved the post without a title"
end
というテストを書いたので,今度は
test "post can save with title" do
post = Post.new
post.title = "Test Title"
assert post.save, "Saved the post with a title"
end
というのを書いてみたが, post.title = "Test Title" で怒られる。どう記述すればいいのか。
3.3 What to Include in Your Unit Tests
続き
Unit Testに何を含めればいいのか?
Ideally you would like to include a test for everything which could possibly break. It’s a good practice to have at least one test for each of your validations and at least one test for every method in your model. 理想的にいえば,起こりえる全ての事に大してテストしたい。全てのvalidationに対して少なくとも一つのテストと,全てのメソッドに対しても少くても一つ以上のテストを作成するのが good practice である。メソッドに対するテストと書いてあるが,具体的にどんなメソッドテストを書くのだろうか?
3.4 Assertions Available
3.5 Rails Specific Assertions
どんなassert式を書けるか。Rails特有のassertionは? リンク先の表を見るのがいい。