Ruby on Rails 2.1-단위 테스트

소개

계속하기 전에 몇 가지 정의를 간단히 살펴 보겠습니다.

  • 그만큼 Tests− 일관된 결과를 생성하고 Rails 애플리케이션이 예상되는 작업을 수행함을 증명하는 테스트 애플리케이션입니다. 테스트는 실제 응용 프로그램과 동시에 개발됩니다.

  • 그만큼 Assertion− 예상 결과에 대해 객체 (또는 표현식)를 평가하는 한 줄의 코드입니다. 예를 들어 –이 값 = 그 값입니까? 이 객체가 nil입니까?

  • 그만큼 Test Case− 이것은 문맥 적으로 관련된 테스트로 구성된 테스트 전략을 포함 하는 Test :: Unit :: TestCase에서 상속 된 클래스 입니다.

  • 그만큼 Test Suite− 이것은 테스트 케이스 모음입니다. 테스트 스위트를 실행하면 해당 스위트에 속한 각 테스트를 차례로 실행합니다.

Rails 테스트

도우미 스크립트 스크립트 / 생성 을 실행하여 컨트롤러모델을 생성하면 Rails는 단위 및 기능 테스트를위한 프레임 워크를 생성합니다. 작성한 기능에 대한 테스트로 프레임 워크를 채우면 꽤 좋은 테스트 범위를 얻을 수 있습니다. Rails 애플리케이션에서 테스트해야 할 두 가지 중요한 사항이 있습니다.

  • 모델 테스트

  • 컨트롤러 테스트

이 튜토리얼에서는 두 가지 테스트를 간략하게 다룹니다. 개념을 이해하기 위해 하나의 테스트 앱 을 만들어 보겠습니다 .

C:\ruby> rails -d mysql testapp

데이터베이스 설정

지금까지는 Rails 애플리케이션의 개발 데이터베이스 만 사용했지만 이제 테스트 데이터베이스도 생성되고 config / database.yml 파일의 적절한 섹션이 올바르게 설정되었는지 확인해야합니다.

다음과 같이 개발 및 테스트 데이터베이스를 생성 해 보겠습니다.

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 구성

다음과 같이 config / database.yml을 구성하십시오.

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

마이그레이션 생성

제목, 가격 및 간단한 설명이 포함 된 책이 포함 된 테이블이 있다고 가정합니다. 다음 마이그레이션은이 테이블을 설정합니다-

testapp > ruby script/generate migration books

이제 testapp / db / migrate / 20080616170315_books.rb 파일을 다음과 같이 수정하십시오.

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

이제 다음과 같이 마이그레이션을 실행하십시오.

testapp > rake db:migrate

이것은 만들 것입니다 bookstestapp_development 데이터베이스의 테이블. 그 후 다음과 같이 rake 명령을 사용하여 테스트 데이터베이스를 설정해야합니다.

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

이것은 testapp_development 데이터베이스를 testapp_test 데이터베이스 로 복제 합니다. 즉, 개발 데이터베이스에있는 것이 무엇이든 이제 테스트 데이터베이스에서도 동일한 데이터를 갖게됩니다.

모델 테스트

생성 스크립트 를 사용하여 모델 을 생성하면 Rails는 테스트 디렉토리에 모델에 대한 단위 테스트 스크립트도 생성합니다. 또한 testapp_test 데이터베이스에로드 할 테스트 데이터를 포함 하는 YAML 파일 인 fixture를 생성 합니다. 이것은 단위 테스트가 실행될 데이터입니다.

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

모델 클래스에 코드를 작성할 때 이러한 파일에 해당 테스트를 작성합니다. 따라서 다음과 같이 test / fixtures / books.yml에서 YAML을 사용하여 두 개의 테스트 북 레코드를 생성 해 보겠습니다.

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'

이제 책 단위 테스트 파일 test / unit / book_test.rb의 기존 코드를 다음 코드로 교체해 보겠습니다.

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

마지막으로 다음과 같이 테스트 방법을 실행하십시오.

testapp > ruby test/unit/book_test.rb

다음은 성공적인 테스트 케이스를 실행 한 결과입니다.

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

여기서 무슨 일이 일어 났는지 분석해 봅시다.

  • BookTest 메서드는 텍스트 fixture / books.yml의 첫 번째 레코드에서 제목 및 기타 필드를 사용하여 새 Book 개체를 만드는 것으로 시작합니다. 결과 개체는 perl_book 인스턴스 변수에 저장됩니다.

  • 첫 번째 어설 션은 Book 개체를 성공적으로 저장했는지 테스트합니다.

  • 다음으로, 책 객체는 find 메소드를 사용하여 검색 되고 perl_book_copy라는 다른 인스턴스 변수에 저장됩니다. 이 검색의 성공 여부는 두 책 개체의 제목을 비교하는 다음 주장에서 테스트됩니다. 이 시점에서 데이터베이스 레코드를 만들고 읽는 기능을 테스트했습니다.

  • 이 솔루션은 perl_book에 저장된 객체에 새 제목을 할당하여 업데이트를 테스트 한 다음 변경 사항이 성공적으로 저장되었는지 확인합니다.

  • 마지막으로 Book 객체를 파괴하는 기능이 테스트됩니다.

이것이 Rails 모델을 테스트하는 방법입니다.

컨트롤러 테스트

컨트롤러 테스트는 functional testing. 기능 테스트는 컨트롤러의 다음 유형의 기능을 테스트합니다.

  • 응답이 예상대로 리디렉션됩니까?
  • 예상 템플릿이 렌더링됩니까?
  • 라우팅이 예상대로입니까?
  • 응답에 예상 태그가 포함되어 있습니까?

Rails 프레임 워크는 5 가지 유형의 요청을 지원합니다.

  • get
  • post
  • put
  • head
  • delete

기능 테스트를 작성하려면 컨트롤러가 처리 할 5 가지 HTTP 요청 유형 중 하나를 시뮬레이션해야합니다.

요청 유형 "get"및 "post"는 컨트롤러 테스트에서 가장 일반적으로 사용됩니다. 이 모든 방법은 네 가지 인수를 취합니다.

  • 컨트롤러의 행동
  • 요청 매개 변수의 선택적 해시
  • 선택적 세션 해시
  • 선택적 플래시 해시

이 튜토리얼에서 우리는 get컨트롤러를 테스트하는 방법입니다. 유사한 방식으로 나머지 메서드를 테스트 할 수 있습니다.

generate로 컨트롤러 를 생성 할 때 Rails는 다음과 같이 컨트롤러에 대한 기능 테스트 스크립트를 생성합니다.

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

컨트롤러 클래스에 코드를 작성할 때 이러한 파일에 해당 테스트를 작성합니다. 그 전에, 우리의 컨트롤러 기능을 정의 할 수 , 목록을 표시,검색 내부app/controllers/book_controller.rb 다음과 같이-

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 − 두 개의 뷰 템플릿이 필요합니다. show목록 방법. 이러한 뷰를 정의하고 테스트 할 수 있지만 지금은 해당 뷰를 정의하지 않고 계속 진행합니다.

이제 테스트 픽스쳐를 재사용하겠습니다. test/fixtures/books.yml 다음과 같이 파일-

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'

다음 test_search_booktest_search_not_found 메소드를 test / functional / book_controller_test.rb 에 추가하여 Book Controller의 검색 조치 기능을 테스트하십시오.

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

이제 다음과 같이 테스트 케이스를 실행하십시오.

testapp > ruby test/functional/book_controller_test.rb

다음과 같은 출력을 제공합니다.

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

2 tests, 7 assertions, 0 failures, 0 errors

여기서 무슨 일이 일어 났는지 분석해 봅시다.

  • 설치 방법은 컨트롤러, 요청 및 응답 객체를 생성하는 기본 방법이다. Rails에서 내부적으로 사용됩니다.

  • 첫 번째 테스트 방법 인 test_search_bookget검색 작업에 대한 요청으로 제목 매개 변수를 전달 합니다.

  • 다음 두 개의 어설 션은 Book 개체가 @book 이라는 인스턴스 변수에 저장되었고 개체가 존재할 수있는 모든 Active Record 유효성 검사를 통과하는지 확인합니다.

  • 첫 번째 메서드 내부의 마지막 어설 션은 요청이 컨트롤러의 show 작업으로 리디렉션되었는지 테스트합니다.

  • 두 번째 테스트 메서드 인 test_search_not_found 는 다른 가져 오기 요청을 수행 하지만 잘못된 제목을 전달합니다.

  • 첫 번째 어설 션은 목록 작업에 대한 리디렉션 이 실행 되었는지 테스트합니다 .

  • 진행중인 어설 션이 통과되면 assert_equal로 테스트 할 수 있는 메시지가 플래시 해시 에 있어야합니다 .

Assertions에 대한 자세한 정보는 Rails Standard Documentation을 참조하십시오 .

테스트를 위해 레이크 사용

당신이 사용할 수있는 rake응용 프로그램을 테스트하는 유틸리티. 다음은 몇 가지 중요한 명령 목록입니다.

  • $rake test − 모든 단위 테스트 및 기능 테스트 (및 존재하는 경우 통합 테스트)를 테스트합니다.

  • $rake test:functionals− 모든 기능 테스트를 실행합니다.

  • $rake test:units − 모든 단위 테스트를 실행합니다.

  • $rake test:integration − 모든 통합 테스트를 실행합니다.

  • $rake test:plugins − ./vendor/plugins/**/test에서 모든 테스트를 실행합니다.

  • $rake test:recent − 지난 10 분 동안 수정 된 모델 및 컨트롤러에 대한 테스트 실행 −

  • $rake test:uncommitted − Subversion의 프로젝트의 경우 마지막 커밋 이후 모델 및 컨트롤러에서 발생한 변경 사항에 대한 테스트를 실행합니다.