Hu Gb

Ruby on Rails és a tesztek

Tesztek írása nélkül olyan a fejlesztés, mint gumi nélkül szexelni egy ismeretlennel. Sok későbbi fejfájást spórolhatunk meg, ha a fejlesztés alatt végig írogatjuk a tesztjeinket. A Ruby on Rails egy - véleményem szerint - nagyon jó teszt keretrendszert tartalmaz, ezt fogom most bemutatni. Generáljuk egy rails app-ot, utána pedig egy scaffold-ot:
rails new rails_testing
cd rails_testing
rails g scaffold post title:string content:text
rake db:migrate
A fenti kód legenerálja az app-unk vázát, illetve egy scaffold-ot a "post" model-hez. Ennek részeként az app/test mappában, a rails létrehoz nekünk egy fixture-t, és minta teszteket. A fixture-ök abban lesznek segtségünkre, hogy előre meghatározott adatokat tárolnak nekünk a teszteléshez. A rails ezeket előre kitölti nekünk, de inkább alakitsuk át őket egy kicsit:
#test-fixtures/posts.yml

one:
  title: Elso post
  content: elso post szoveges tartalma

two:
  title: Masodik post
  content: második post szoveges tartalma
Az adataink készen állnak, a rails config fájlban a teszt adatbázis alapértelmezetten meg van adva, úgyhogy kezdhetjük is a tesztelést. Nezzük meg először a Unit teszteket. Tegyük fel, hogy a példánkban, nem akarjuk hogy a 'title' attribútum nélkül el lehessen menteni egy post-ot. Erre írhatunk egy ilyen tesztet: Az adataink készen állnak, a rails config fájlban a teszt adatbázis alapértelmezetten meg van adva, úgyhogz kezdhetjük is a tesztelést. Nezzük meg először a Unit teszteket. Tegyük fel, hogy a példánkban, nem akarjuk hogy a 'title' attribútum nélkül el lehessen menteni egy post-ot. Erre írhatunk egy ilyen tesztet:
test "shouldn't save without title" do 
	post = Post.new
	assert !post.save
end
Konzolból futtasuk le a tesztünket. Ezt a 'rake test' parancs megadasával tudjuk elérni. Az eredmény kb ez lesz:
Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.9.2/lib/rake/rake_test_loader
Started
F
Finished in 0.066695 seconds.

  1) Failure:
test_shouldn't_save_without_title(PostTest) [test/unit/post_test.rb:7]:
 is not true.

1 tests, 1 assertions, 1 failures, 0 errors
Loaded suite /Library/Ruby/Gems/1.8/gems/rake-0.9.2/lib/rake/rake_test_loader
Started
.......
Finished in 0.14225 seconds.

7 tests, 10 assertions, 0 failures, 0 errors
Errors running test:units!
A tesztünk elbukott, mivel nincsen semmilyen validálás a modelünkön. Állítsuk be a hiányzó validálást:
class Post < ActiveRecord::Base
  validates :title, :presence => true 
end
És futtasuk le újra a tesztet:
rake test
Most hiba nélkül lefutott a tesztünk. A unit tesztelés nagyon hasznos, de szerintem a functional tesztek még hasznosabbak. A példa alkalmazásunkban, ha megnézzük a Rails már automatikusan legenerált nekünk egy minta tesztet. A test/functional/posts_contoller_test.rb fájl tartalmaz néhány hasznos tesztet. Például az alábbit:
test "should get new" do
  get :new
  assert_response :success
end
Ez a teszt annyit csinál, hogy ellenőrzi a post/index action válaszkódját. Ígz ha valamilyen véletlen folytán egy hibát ejtünk ezen a részén az alkalmazásunknak, akkor jó esélyel, ez a teszt jelezni fogja. A generált teszt fájlunk tartalmaz egy-egy tesztet a CRUD-unk minden action-jéhez. Készítsünk egy új actiont a post contoller-ünkben, ami a főoldalát kezelné a blogunknak és tegyük fel, hogy a legfrissebb 3 posztot szeretnénk megjeleníteni rajta. Mielőtt a kódot megírnánk, írjuk meg a tesztünket hozzá:
test "should get home with max 3 post" do
	get :homepage
	assert_response :success
	assert_not_nil assigns(:posts)
end
Futtassuk le ezt a tesztet:
1) Error:
test_should_get_home_with_posts(PostsControllerTest):
ActionController::RoutingError: No route matches {:action=>"homepage", :controller=>"posts"}
    test/functional/posts_controller_test.rb:9:in `test_should_get_home_with_max_3_post'
Az eredmény egy hiba, mivel a root route-unk nincs meg beállítva. Javítsuk a hibát és végezzük el az alábbi változtatásokat:
#config/routes.rb
root :to => 'post#homepage'

#app/controllers/posts_contoller.rb
def homepage
  @posts = Post.limit(3)
  render :template => 'posts/index'
end
#app/views/posts/homepage.html.erb
<% @posts.each do |e| %>
	<h2><%= e.title %></h2>
<% end %>
#test/fixtures/posts.yml
one:
  title: Elso post
  content: elso post szoveges tartalma

two:
  title: Masodik post
  content: masodik post szoveges tartalma
three:
  title: Harmadik post
  content: harmadik post szoveges tartalma
four:
  title: Negyedik post
  content: negyedik post szoveges tartalma

#test/functional/posts_controller_test.rb
test "should get home with max 3 post" do
	get :homepage
	assert_response :success
	assert_not_nil assigns(:posts)
	assert (css_select('h2').count <= 3)
end
Így már hiba nélkül le fut a tesztünk. Remélem ezzel a rövid bevezetővel meghoztam a kedvet a tesztek írásához.

Szólj Hozzá