Ruby on Rails 2.1 - Kiểm thử đơn vị
Giới thiệu
Trước khi tiếp tục, chúng ta hãy xem nhanh một vài định nghĩa -
Các Tests- Chúng là các ứng dụng thử nghiệm tạo ra kết quả nhất quán và chứng minh rằng ứng dụng Rails thực hiện những gì nó được mong đợi. Các thử nghiệm được phát triển đồng thời với ứng dụng thực tế.
Các Assertion- Đây là một dòng mã đánh giá một đối tượng (hoặc biểu thức) cho kết quả mong đợi. Ví dụ - Giá trị này = giá trị đó? Đối tượng này là nil?
Các Test Case- Đây là một lớp kế thừa từ Test :: Unit :: TestCase chứa một chiến lược kiểm thử bao gồm các bài kiểm tra liên quan đến ngữ cảnh.
Các Test Suite- Đây là một tập hợp các trường hợp thử nghiệm. Khi bạn chạy một bộ thử nghiệm, nó sẽ lần lượt thực hiện từng thử nghiệm thuộc về nó.
Kiểm tra đường ray
Khi bạn chạy tập lệnh script trợ giúp / tạo để tạo bộ điều khiển và mô hình , Rails sẽ tạo một khuôn khổ cho các bài kiểm tra đơn vị và chức năng. Bạn có thể nhận được phạm vi kiểm tra khá tốt bằng cách điền vào khung các bài kiểm tra cho chức năng bạn viết. Có hai điểm quan trọng cần kiểm tra trong một ứng dụng Rails:
Kiểm tra các mô hình
Kiểm tra bộ điều khiển
Hướng dẫn này sẽ trình bày ngắn gọn cả hai thử nghiệm. Vì vậy, hãy tạo một testapp để hiểu khái niệm.
C:\ruby> rails -d mysql testapp
Thiết lập cơ sở dữ liệu
Cho đến nay, chúng tôi chỉ sử dụng cơ sở dữ liệu phát triển của ứng dụng Rails, nhưng bây giờ bạn cần đảm bảo rằng cơ sở dữ liệu thử nghiệm cũng được tạo và các phần thích hợp của tệp config / database.yml của bạn được thiết lập chính xác.
Hãy tạo cơ sở dữ liệu phát triển và thử nghiệm như sau:
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)
Định cấu hình database.yml
Định cấu hình config / database.yml của bạn như sau:
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
Tạo di chuyển
Giả sử bạn có một bảng chứa sách, bao gồm tên sách, giá và một mô tả nhỏ. Quá trình di chuyển sau đây thiết lập bảng này:
testapp > ruby script/generate migration books
Bây giờ sửa đổi tệp testapp / db / migrate / 20080616170315_books.rb như sau:
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
Bây giờ hãy chạy quá trình di chuyển như sau:
testapp > rake db:migrate
Điều này sẽ tạo ra booksbảng trong cơ sở dữ liệu testapp_development. Sau đó, chúng tôi cần thiết lập cơ sở dữ liệu thử nghiệm của bạn bằng lệnh rake như sau:
C:\ruby\testapp > rake db:test:clone_structure
Điều này sẽ sao chép các testapp_development cơ sở dữ liệu vào testapp_test cơ sở dữ liệu. Nó có nghĩa là bất cứ thứ gì bạn có trong cơ sở dữ liệu phát triển, bây giờ bạn cũng sẽ có cùng một dữ liệu trong cơ sở dữ liệu thử nghiệm.
Thử nghiệm Mô hình
Khi bạn tạo một mô hình bằng tập lệnh tạo, Rails cũng tạo một tập lệnh thử nghiệm đơn vị cho mô hình trong thư mục thử nghiệm. Nó cũng tạo ra một vật cố định , một tệp YAML chứa dữ liệu thử nghiệm để được tải vào cơ sở dữ liệu testapp_test. Đây là dữ liệu mà các bài kiểm tra đơn vị của bạn sẽ chạy -
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
Khi bạn viết mã trong các lớp mô hình, bạn sẽ viết các bài kiểm tra tương ứng trong các tệp này. Vì vậy, hãy tạo hai bản ghi sổ kiểm tra bằng YAML trong test / fixtures / books.yml như sau:
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'
Bây giờ hãy thay thế mã hiện có trong tệp kiểm tra đơn vị sách / unit / book_test.rb bằng mã sau:
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
Cuối cùng, chạy phương pháp kiểm tra như sau:
testapp > ruby test/unit/book_test.rb
Đây là kết quả của việc chạy trường hợp thử nghiệm thành công -
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
Hãy phân tích những gì đã xảy ra ở đây -
Phương thức BookTest bắt đầu bằng cách tạo một đối tượng Sách mới bằng cách sử dụng tiêu đề và các trường khác từ bản ghi đầu tiên trong text fixture / books.yml. Đối tượng kết quả được lưu trữ trong biến cá thể perl_book.
Kiểm tra xác nhận đầu tiên rằng việc lưu đối tượng Sách đã thành công.
Tiếp theo, đối tượng book được truy xuất bằng phương thức find và được lưu trữ trong một biến thể hiện khác có tên là perl_book_copy. Sự thành công của việc truy xuất này được kiểm tra trong khẳng định tiếp theo, so sánh tên sách của cả hai đối tượng sách. Tại thời điểm này, chúng tôi đã kiểm tra khả năng tạo và đọc bản ghi cơ sở dữ liệu.
Giải pháp kiểm tra việc cập nhật bằng cách gán một tiêu đề mới cho đối tượng được lưu trữ trong perl_book và sau đó xác nhận rằng việc lưu thay đổi thành công.
Cuối cùng, khả năng phá hủy một đối tượng Sách được thử nghiệm.
Đây là cách chúng tôi có thể kiểm tra các Mô hình Rails của mình.
Kiểm tra bộ điều khiển
Kiểm tra bộ điều khiển còn được gọi là functional testing. Kiểm tra chức năng kiểm tra các loại chức năng sau của bộ điều khiển:
- Phản hồi có được chuyển hướng như mong đợi không?
- Mẫu mong đợi có được hiển thị không?
- Định tuyến có như mong đợi không?
- Phản hồi có chứa các thẻ mong đợi không?
Khung công tác Rails hỗ trợ năm loại yêu cầu -
- get
- post
- put
- head
- delete
Để viết một bài kiểm tra chức năng, bạn cần phải mô phỏng bất kỳ loại yêu cầu HTTP nào trong năm loại yêu cầu HTTP mà bộ điều khiển của bạn sẽ xử lý.
Loại yêu cầu "get" và "post" được sử dụng phổ biến nhất trong thử nghiệm bộ điều khiển. Tất cả các phương thức này có bốn đối số -
- Hành động của bộ điều khiển
- Một băm tùy chọn của các tham số yêu cầu
- Hàm băm phiên tùy chọn
- Một băm flash tùy chọn
Trong hướng dẫn này, chúng ta sẽ xem cách sử dụng getphương pháp để kiểm tra bộ điều khiển của chúng tôi. Bạn có thể kiểm tra phần còn lại của các phương pháp theo cách tương tự.
Khi bạn tạo một bộ điều khiển bằng tạo, Rails sẽ tạo một tập lệnh kiểm tra chức năng cho bộ điều khiển như sau:
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
Khi bạn viết mã trong các lớp bộ điều khiển, bạn sẽ viết các bài kiểm tra tương ứng trong các tệp này. Trước đó, hãy xác định danh sách chức năng bộ điều khiển , hiển thị và tìm kiếm bên trongapp/controllers/book_controller.rb như sau -
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 - Bạn sẽ cần hai mẫu chế độ xem cho showvà phương pháp danh sách . Bạn có thể xác định các chế độ xem đó và kiểm tra chúng, nhưng ngay bây giờ, chúng tôi sẽ tiến hành mà không xác định các chế độ xem đó.
Bây giờ chúng ta hãy sử dụng lại vật cố định thử nghiệm của chúng tôi trong test/fixtures/books.yml tập tin như sau -
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'
Thêm dòng sau test_search_book và test_search_not_found phương pháp để test / functional / book_controller_test.rb để kiểm tra các chức năng của hành động tìm kiếm Kiểm Soát Tài Chính Sách.
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
Bây giờ chạy các trường hợp thử nghiệm của bạn như sau:
testapp > ruby test/functional/book_controller_test.rb
Nó cho kết quả sau:
Loaded suite test/functional/book_controller_test
Started
..
Finished in 0.422 seconds.
2 tests, 7 assertions, 0 failures, 0 errors
Hãy phân tích điều gì đã xảy ra ở đây -
Các thiết lập phương pháp là một phương pháp mặc định để tạo các đối tượng điều khiển, yêu cầu, và phản ứng. Chúng sẽ được sử dụng bởi Rails trong nội bộ.
Phương pháp thử nghiệm đầu tiên test_search_book tạo ragetyêu cầu hành động tìm kiếm, chuyển vào một tham số tiêu đề .
Hai xác nhận tiếp theo xác minh rằng đối tượng Sách đã được lưu trong một biến thể hiện có tên là @book và đối tượng đó vượt qua bất kỳ xác thực Bản ghi Hoạt động nào có thể tồn tại.
Xác nhận cuối cùng bên trong phương pháp đầu tiên kiểm tra rằng yêu cầu đã được chuyển hướng đến hành động hiển thị của bộ điều khiển.
Phương pháp kiểm tra thứ hai, test_search_not_found , thực hiện một yêu cầu nhận khác nhưng chuyển sang tiêu đề không hợp lệ
Kiểm tra xác nhận đầu tiên rằng chuyển hướng đến hành động danh sách đã được đưa ra.
Nếu các xác nhận tiếp tục được thông qua, sẽ có một thông báo trong mã băm flash mà bạn có thể kiểm tra bằng khẳng định_equal ..
Để có thêm thông tin về Assertions, vui lòng tham khảo Tài liệu Tiêu chuẩn của Rails .
Sử dụng Rake để kiểm tra
Bạn có thể dùng raketiện ích để kiểm tra các ứng dụng của bạn. Dưới đây là danh sách một số lệnh quan trọng.
$rake test - Kiểm tra tất cả các kiểm thử đơn vị và kiểm thử chức năng (và kiểm thử tích hợp, nếu chúng tồn tại).
$rake test:functionals- Chạy tất cả các bài kiểm tra chức năng.
$rake test:units - Chạy tất cả các bài kiểm tra đơn vị.
$rake test:integration - Chạy tất cả các bài kiểm tra tích hợp.
$rake test:plugins - Chạy tất cả kiểm tra trong ./vendor/plugins/**/test.
$rake test:recent - Chạy kiểm tra các mô hình và bộ điều khiển đã được sửa đổi trong 10 phút qua -
$rake test:uncommitted - Đối với các dự án trong Subversion, hãy chạy kiểm tra những thay đổi đã diễn ra trong các mô hình và bộ điều khiển kể từ lần cam kết cuối cùng -