Ruby on Rails 2.1 - Birim Testi

Giriş

Devam etmeden önce birkaç tanıma hızlıca göz atalım -

  • Tests- Tutarlı sonuç üreten ve bir Rails uygulamasının yapması beklenen şeyi yaptığını kanıtlayan test uygulamalarıdır. Testler, gerçek uygulama ile eşzamanlı olarak geliştirilir.

  • Assertion- Bu, beklenen sonuçlar için bir nesneyi (veya ifadeyi) değerlendiren tek satırlık bir koddur. Örneğin - Bu değer = bu değer mi? Bu nesne sıfır mı?

  • Test Case- Bu, bağlamsal olarak ilgili testlerden oluşan bir test stratejisi içeren Test :: Unit :: TestCase'den miras alınan bir sınıftır .

  • Test Suite- Bu, test durumlarının bir koleksiyonudur. Bir test paketi çalıştırdığınızda, sırayla kendisine ait olan her testi yürütecektir.

Rayların Test Edilmesi

Denetleyiciler ve modeller oluşturmak için yardımcı komut dosyası komut dosyasını çalıştırdığınızda / Rails, birim ve işlevsel testler için bir çerçeve oluşturur. Çerçeveyi yazdığınız işlevsellik için testlerle doldurarak oldukça iyi bir test kapsamı elde edebilirsiniz. Bir Rails uygulamasında test edilecek iki önemli nokta vardır -

  • Modelleri Test Etme

  • Denetleyicileri Test Etme

Bu eğitim, kısaca her iki testi de kapsayacaktır. Öyleyse kavramı anlamak için bir test uygulaması oluşturalım .

C:\ruby> rails -d mysql testapp

Veritabanı Kurulumu

Şimdiye kadar sadece Rails uygulamasının geliştirme veritabanını kullandık, ancak şimdi test veritabanının da oluşturulduğundan ve config / database.yml dosyanızın uygun bölümlerinin doğru şekilde kurulduğundan emin olmanız gerekiyor.

Geliştirme ve test veritabanlarını aşağıdaki gibi oluşturalım -

mysql> create database testapp_test;
Query OK, 1 row affected (0.01 sec)

mysql> create database testapp_development;
Query OK, 1 row affected (0.01 sec)

mysql> use testapp_test;
Database changed

mysql> grant all privileges on testapp_test.* 
   to 'root'@'localhost' identified by 'password';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Database.yml yapılandırılıyor

Config / database.yml dosyanızı aşağıdaki gibi yapılandırın -

development:
   adapter: mysql
   encoding: utf8
   database: testapp_development
   username: root
   password: password
   host: localhost
test:
   adapter: mysql
   encoding: utf8
   database: testapp_test
   username: root
   password: password
   host: localhost
production:
   adapter: mysql
   encoding: utf8
   database: testapp_production
   username: root
   password: password
   host: localhost

Göç Oluştur

Kitapların başlıkları, fiyatları ve küçük bir açıklamasını içeren bir tablonuz olduğunu varsayalım. Aşağıdaki taşıma bu tabloyu oluşturur -

testapp > ruby script/generate migration books

Şimdi testapp / db / migrate / 20080616170315_books.rb dosyasını aşağıdaki gibi değiştirin -

class Books < ActiveRecord::Migration
   def self.up
      create_table :books do |t|
         t.string     :title, :limit => 32, :null => false
         t.float      :price
         t.text       :description
         t.timestamp  :created_at
      end
   end
  
   def self.down
      drop_table :books
   end
end

Şimdi geçişi şu şekilde çalıştırın -

testapp > rake db:migrate

Bu yaratacak bookstestapp_development veritabanındaki tablo. Bundan sonra, aşağıdaki gibi rake komutunu kullanarak test veritabanınızı kurmamız gerekiyor -

C:\ruby\testapp > rake db:test:clone_structure

Bu, testapp_development veritabanını testapp_test veritabanına klonlayacaktır . Bu, geliştirme veritabanında ne varsa, şimdi test veritabanında da aynı verilere sahip olacaksınız demektir.

Test Modelleri

Oluşturma komut dosyasıyla bir model oluşturduğunuzda, Rails ayrıca test dizinindeki model için bir birim testi komut dosyası oluşturur. Ayrıca testapp_test veritabanına yüklenecek test verilerini içeren bir YAML dosyası olan bir fikstür oluşturur . Bu, birim testlerinizin çalıştırılacağı verilerdir -

testapp > ruby script/generate model Book
   exists  app/models/
   exists  test/unit/
   exists  test/fixtures/
   create  app/models/book.rb
   create  test/unit/book_test.rb
   create  test/fixtures/books.yml
   create  db/migrate
   create  db/migrate/20080616164236_create_books.rb

Model sınıflarına kod yazarken, bu dosyalara karşılık gelen testleri yazacaksınız. Öyleyse test / fikstür / kitaplar.yml'de YAML kullanarak aşağıdaki gibi iki test kitabı kaydı oluşturalım -

perl_cb:
   id: 1
   title: 'Ruby Tutorial'
   price: 102.00
   description : 'This is a nice Ruby tutorial'
java_cb:
   id: 2
   title: 'Java Programming'
   price: 62.00
   description : 'Java Programming for the beginners'

Şimdi kitap birimi test dosyası test / unit / book_test.rb'deki mevcut kodu aşağıdaki kodla değiştirelim -

require File.dirname(__FILE__) + '/../test_helper'

class BookTest < ActiveSupport::TestCase
   fixtures :books

   def test_book

      perl_book = Book.new :title => books(:perl_cb).title, 
         :price => books(:perl_cb).price,
         :description => books(:perl_cb).description,
         :created_at => books(:perl_cb).created_at

      assert perl_book.save

      perl_book_copy = Book.find(perl_book.id)

      assert_equal perl_book.title, perl_book_copy.title

      perl_book.title = "Ruby Tutorial"

      assert perl_book.save
      assert perl_book.destroy
   end
end

Son olarak, test yöntemini aşağıdaki gibi çalıştırın -

testapp > ruby test/unit/book_test.rb

İşte başarılı test senaryosunu çalıştırmanın çıktıları -

testapp > ruby test/unit/book_test_crud.rb 
Loaded suite ./test/unit/book_test
Started
.
Finished in 0.0625 seconds.

1 tests, 4 assertions, 0 failures, 0 errors

Burada ne olduğunu analiz edelim -

  • BookTest yöntemi, fikstür / books.yml metinindeki ilk kayıttan başlık ve diğer alanları kullanarak yeni bir Kitap nesnesi oluşturarak başlar. Ortaya çıkan nesne, perl_book örnek değişkeninde saklanır.

  • İlk iddia, Book nesnesini kaydetmenin başarılı olduğunu test eder.

  • Daha sonra kitap nesnesi, bulma yöntemi kullanılarak alınır ve perl_book_copy adlı başka bir örnek değişkeninde saklanır. Bu geri çağırmanın başarısı, her iki kitap nesnesinin başlıklarını karşılaştıran bir sonraki iddiada test edilir. Bu noktada, bir veritabanı kaydı oluşturma ve okuma yeteneğini test ettik.

  • Çözüm, perl_book'ta depolanan nesneye yeni bir başlık atayarak güncellemeyi test eder ve ardından değişikliğin kaydedilmesinin başarılı olduğunu belirtir.

  • Son olarak, bir Kitap nesnesini imha etme yeteneği test edilir.

Ray Modellerimizi bu şekilde test edebiliriz.

Denetleyicileri Test Etme

Kontrolör testi olarak da bilinir functional testing. Fonksiyonel test, kontrolörlerin aşağıdaki fonksiyonellik türlerini test eder -

  • Yanıt beklendiği gibi yönlendirildi mi?
  • Beklenen şablon oluşturuldu mu?
  • Yönlendirme beklendiği gibi mi?
  • Yanıt beklenen etiketleri içeriyor mu?

Rails çerçevesi beş tür isteği destekler -

  • get
  • post
  • put
  • head
  • delete

İşlevsel bir test yazmak için, denetleyicinizin işleyeceği beş HTTP istek türünden herhangi birini simüle etmeniz gerekir.

"Get" ve "post" istek türü, denetleyici testinde en yaygın olarak kullanılanlardır. Tüm bu yöntemler dört argüman alır -

  • Bir denetleyicinin eylemi
  • İsteğe bağlı bir istek parametreleri karması
  • İsteğe bağlı bir oturum karması
  • İsteğe bağlı bir flash hash

Bu eğitimde nasıl kullanılacağını göreceğiz getdenetleyicimizi test etme yöntemi. Yöntemlerin geri kalanını benzer şekilde test edebilirsiniz.

Generation ile bir denetleyici oluşturduğunuzda, Rails aşağıdaki gibi denetleyici için işlevsel bir test komut dosyası oluşturur -

testapp > ruby script/generate controller Book
   exists  app/controllers/
   exists  app/helpers/
   create  app/views/book
   exists  test/functional/
   create  app/controllers/book_controller.rb
   create  test/functional/book_controller_test.rb
   create  app/helpers/book_helper.rb

Denetleyici sınıflarına kod yazarken, bu dosyalara karşılık gelen testleri yazacaksınız. Bundan önce, en bizim denetleyici işlevleri tanımlayalım , listesini göstermek, ve arama içiniapp/controllers/book_controller.rb aşağıdaki gibi -

class BookController < ApplicationController
   def list
      @book_pages, @books = paginate :books, :per_page => 10
   end

   def show
      @book = Book.find(params[:id])
   end

   def search
      @book = Book.find_by_title(params[:title])
      if @book
         redirect_to :action => 'show', :id => @book.id
      else    
         flash[:error] = 'No such book available'
         redirect_to :action => 'list'
      end
   end
end

NOTE - için iki görünüm şablonuna ihtiyacınız olacak showve liste yöntemi. Bu görünümleri tanımlayabilir ve test edebilirsiniz, ancak şu anda bu görünümleri tanımlamadan ilerleyeceğiz.

Şimdi test fikstürümüzü tekrar kullanalım. test/fixtures/books.yml aşağıdaki gibi dosya -

perl_cb:
   id: 1
   title: 'Ruby Tutorial'
   price: 102.00
   description : 'This is a nice Ruby tutorial'
java_cb:
  id: 2
  title: 'Java Programming'
  price: 62.00
  description : 'Java Programming for the beginners'

Kitap Denetleyicisinin arama eyleminin işlevselliğini test etmek için aşağıdaki test_search_book ve test_search_not_found yöntemlerini test / function / book_controller_test.rb'ye ekleyin .

require File.dirname(__FILE__) + '/../test_helper'
require 'book_controller'

# Re-raise errors caught by the controller.
class BookController
   def rescue_action(e) 
      raise e 
   end
end

class BookControllerTest < Test::Unit::TestCase
   fixtures :books
   def setup
      @controller = BookController.new
      @request    = ActionController::TestRequest.new
      @response   = ActionController::TestResponse.new
   end

   def test_search_book
      get :search, :title => 'Ruby Tutorial'
      assert_not_nil assigns(:book)
      assert_equal books(:perl_cb).title, assigns(:book).title
      assert_valid assigns(:book)
      assert_redirected_to :action => 'show'
   end

   def test_search_not_found
      get :search, :title => 'HTML Tutorial'
      assert_redirected_to :action => 'list'
      assert_equal 'No such book available', flash[:error]
   end
end

Şimdi test senaryolarınızı aşağıdaki gibi çalıştırın -

testapp > ruby test/functional/book_controller_test.rb

Aşağıdaki çıktıyı verir -

Loaded suite test/functional/book_controller_test
Started
..
Finished in 0.422 seconds.

2 tests, 7 assertions, 0 failures, 0 errors

Burada ne olduğunu analiz edelim -

  • Kurulum yöntemi kontrol, istek ve yanıt nesneler oluşturmak için varsayılan bir yöntemdir. Dahili olarak Rails tarafından kullanılacaktır.

  • İlk test yöntemi test_search_book , birgetbir başlık parametresini ileterek arama eylemine istek .

  • Sonraki iki iddia, bir Book nesnesinin @book adlı bir örnek değişkenine kaydedildiğini ve nesnenin var olabilecek tüm Active Record doğrulamalarını geçtiğini doğrular.

  • İlk yöntemin içindeki son iddia, isteğin denetleyicinin göster eylemine yönlendirildiğini test eder.

  • İkinci bir test yöntemi, test_search_not_found , başka bir yerine olsun talebi fakat geçersiz başlıkta geçer

  • İlk iddialar, listeye bir yönlendirme eyleminin yayınlandığını test eder .

  • Devam eden iddialar geçildiyse , flash karmasında assert_equal ile test edebileceğiniz bir mesaj olmalıdır .

Onaylar hakkında daha fazla bilgi edinmek için lütfen Rails Standart Belgelerine bakın .

Test İçin Tırmık Kullanma

Kullanabilirsiniz rakeuygulamalarınızı test etmek için yardımcı program. Aşağıda birkaç önemli komutun bir listesi verilmiştir.

  • $rake test - Tüm birim testlerini ve fonksiyonel testleri (ve varsa entegrasyon testlerini) test edin.

  • $rake test:functionals- Tüm fonksiyonel testleri çalıştırın.

  • $rake test:units - Tüm birim testlerini çalıştırın.

  • $rake test:integration - Tüm entegrasyon testlerini çalıştırın.

  • $rake test:plugins - Tüm testleri ./vendor/plugins/**/test içinde çalıştırın.

  • $rake test:recent - Son 10 dakika içinde değiştirilen modeller ve denetleyiciler için testleri çalıştırın -

  • $rake test:uncommitted - Subversion'daki projeler için, son işlemden bu yana modellerde ve denetleyicilerde meydana gelen değişiklikler için testler çalıştırın -