Hướng dẫn cơ bản sử dụng Rspec để viết unit test cho ứng dụng rails

Việc lập trình viên tạo ra một sản phẩm thì có rất nhiều khâu quan trọng. Một trong những bước quan trọng đó là quá trình unit test. Bạn có thể tham khảo thêm bài viết về unit test ở đây. Khái niệm TDD chắc cũng không còn xa lạ gì với các lập trình viên hiện nay. Nó được hiểu là quá trình 3 màu. 3 màu đó là 3 màu gì. Mình xin giải thích một chút, 3 màu đó là Red, Green, Blue. Tương tương 3 màu là 3 quá trình :

  1. Viết 1 test fail (Red)
  2. Sửa code cho test pass (Green)
  3. Loại bỏ code dư thừa - clean code (Blue) Cụ thể hơn thì :
  • Viết Tests trước - sau đó chạy bộ tests vừa viết --> Đỏ lòm vì viết Test trước, chưa có code.
  • Code chạy được --> chạy lại bộ Tests --> Pass hết và màu xanh, không có lỗi đỏ nào hết hết.
  • Refactor code cho ngon --> Chạy lại bộ Tests --> Vẫn phải xanh hết.

Điều đó chứng tỏ, nếu chúng ta viết test càng ngon thì sau này càng đỡ khổ. Fixbug đối với các dev thì là điều không hề mong muốn nhưng đó là cơm bữa. Nên giảm thiểu số bug đi càng nhiều càng tốt. Mà viết test tốt thì cũng làm giảm gánh nặng cho QA và cũng tránh dẫn tới những xung đột không đáng có. (đùa chút thôi 😄).

Viết Test trong Rails Trong rails thì đã hỗ trợ việc viết test ngay từ đầu. Bạn để ý khi chúng ta tạo ra một model bằng câu lệnh

rails g scaffold Player name:string:index shirt_number:integer

Kém với việc tạo ra file model.rb thì nó còn tạo ra cả các file spec đi của model, controller, view. Xem chi tiết tại đây. Trong bài này, mình sẽ giới thiệu về viết Rspec trong rails. Chắc hẳn sẽ có nhiều bạn nghĩ tại sao rails đã hỗ trợ viết test rồi mà còn dùng Rspec để viết. Cái gì cũng có lý do của nó cả. Và chắc cũng sẽ có nhiều câu giải thích khác nhau. Nhưng theo cá nhân mình thì mình thấy nó dễ sử dụng, code ngắn gọn và kểt quả cũng dễ đọc hơn nên mình chọn Rspec.

Thêm Rspec vào trong app Khai báo trong Gemfile:

group :development, :test do
  gem 'rspec-rails', '~> 3.0'
end

Sau đó chạy

$ bundle install

Install rspec và generate test cases.

$ rails g rspec:install
$ rails g rspec:model Player

mở file spec/models/playerspec.rb

require 'spec_helper'
 
describe Player do
  pending "add some examples to (or delete) #{__FILE__}"
end

Ta sẽ viết lại file này:

require 'spec_helper'
 
RSpec.describe Player, type: :model do
  describe "validations" do
    it { should validate_presence_of :name }
    it { should validate_numericality_of(:shirt_number).only_integer }
    it { should validate_numericality_of(:shirt_number).is_greater_than_or_equal_to(1) }
  end
end

Ngoài type::model ra thì Rspec cũng cung cấp nhưng type khác như: :controller, :request, :view, :routing, :helper. ở đây mình đang viết test cho model player nên mình dùng type::model. describe được dùng ở đây là để nhóm một số các test case liên quan tới chức năng nào đó, và mỗi it là một test case. Ở file trên mình ví dụ test validation nên mình không có tạo ra đối tượng. Nếu muốn tạo ra đối tượng thì các bạn có thể dùng gem fabricator, faker, factory girl để tạo dữ liệu giả. Rspec cung cấp từ khóa let để giúp ta khởi tạo đối tượng.

Giở ta chạy thử ví dụ trên teminal:

rspec spec/models/playerspec.rb

Sau khi chạy xong hết các test case nếu không có lỗi gì thì sẽ cho kết quả :

...
Finished in 0.0228 seconds
3 examples, 0 failures

Chúng ta có thể thấy việc thao tác với rspec rất dễ dàng. Nhưng để viết test được tốt thì không hề dễ. Cái này cần phải có một quá trình thực hành. Khi làm việc với rspec để viết test, mình xin giới thiệu thêm gem SimpleCov. Nó sẽ hiện thị độ coverage mà các test case của bạn. Để bạn biết còn những phần nào viết rồi, chưa viết và cần phải viết. Lời kêt Hồi mới đầu tiếp cận với rails minh rất sợ viết test nhưng về sau minh bắt đầu thấy được sự quan trọng của nó. Mình khuyên các bạn mới học rails nên bắt đầu chú trọng ngay từ đầu. Bài viết này mình rút ra từ kinh nghiệm của minh nên có điều gì sai sót mong các bạn góp ý. Cảm ơn các bạn đã đọc bài viết của mình.