Làm Quen Với Unit Test

Unit Test là gì?

Là một loại kiểm thử phần mềm sẽ kiểm tra những thành phần nhỏ nhất trong dự án như Function, Procedure, Class hoặc các Method...Việc viết Unit test trước khi bàn giao cho QA nhằm hạn chế bug xảy ra, do thực hiện test trên từng đơn vị của các module riêng rẽ nên khi phát hiện lỗi cũng dễ dàng khoanh vùng và sửa chữa hơn.

Rails có rất nhiều gem support việc viết Unit Test, ở bài viết này mình cũng sẽ giới thiệu 1 số gem cần thiết để viết và quản lý test một cách dễ dàng, hiệu quả.

Gems

1. rspec-rails

Là 1 mở rộng của RSpec, là một gem cần thiết để viết Unit Test, nó mang RSpec testing framework vào ứng dụng của bạn, cho phép bạn viết unit tests cho Model, Controller, Views và Helpers.

group :test do
  gem "rspec-rails"
end

Nó sẽ cài đặt những gems sau: rspec, rspec-core, rspec-expectations, rspec-mocksrspec-rails. Các bạn có thể đọc thêm Doc của chúng ở đây https://rspec.info/documentation/

Khởi tạo thư mục spec/:

rails generate rspec:install

2. shoulda-matchers

Giúp cho bạn có thể viết Unit Test 1 cách ngắn gon, rõ ràng và nhanh hơn ít gặp lỗi hơn so với viết tay.

group :test do
  gem "rspec-rails"
  gem "shoulda-matchers"
end

spec/rails_helper.rb

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

Shoulda Matchers cung cấp nhiều phương thức dùng để test với ActiveModel, ActiveRecord, ActionController, Independent Matchers EX:

  describe "associations" do
    it { should have_many :posts }
  end
  
  describe "validations" do
    it { should validate_presence_of(:name) }
  end

3. database_cleaner

Dùng để dọn dẹp database test, bảo đảm trạng thái clean trong quá trình test. Có thể chạy trước hoặc sau mỗi case test.

group :test do
  gem "rspec-rails"
  gem "shoulda-matchers"
  gem "database_cleaner"
end

Chạy bundle install. Sau đó ở spec/rails_helper.rb

RSpec.configure do |config|

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, :js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end

4. Faker

Dùng để tạo dữ liệu giả ngẫu nhiên, vd: tên, avartar, địa chỉ, email, barcode,...

group :development, :test do
  gem "faker"
end

**VD: **

Faker::Name.name      #=> "Christophe Bartell"

Faker::Internet.email #=> "kirsten.greenh[email protected]"

5. factory_bot_rails

Dùng để tại data khi test

group :development, :test do
  gem "faker"
  gem "factory_bot_rails"
end

Giả sử ta có Model User gồm columns name, role, address trong đó có enum role: {admin: 0, pic: 1}
Ở spec/factories/user.rb.

FactoryBot.define do
  factory :user do
    name     { Faker::Name.name }
    role         { "admin" }
    address       { Faker::Address.street_address }
    
    factory :user_pic do
      role { "pic" }
    end
  end
end

Như vậy khi viết Unit Test ta có thể gọi ntn để tạo admin tương ứng với role mà mình muốn:

let(:admin) { create :admin }
let(:admin_pic) { create :admin_pic}

6.simplecov

Dùng để thống kê phần trăm coverage code Unit Test, mức độ hòan thiện test của từng file, phân biệt đoạn code nào đã test và đoạn code nào chưa viết test.

group :test do
  ...
  gem "simplecov"
  gem "simplecov-rcov" // style formatter for the ruby 1.9+ coverage gem: SimpleCov.
  gem "simplecov-json" // JSON formatter for the ruby 1.9+ code coverage gem SimpleCov
end

Tiếp theo thêm vào spec/spec_helper.rb

require "simplecov"
require "simplecov-json"
require "simplecov-rcov"

SimpleCov.formatters = [
  SimpleCov::Formatter::HTMLFormatter,
  SimpleCov::Formatter::JSONFormatter,
  SimpleCov::Formatter::RcovFormatter
]
SimpleCov.start do
  coverage_dir "tmp/coverage"
end

Sau khi chạy Unit Test, chọn mở coverage/index.html bẳng trình duyệt bạn sẽ thấy một file mẫu như thế này, nó hiển thị đầy đủ thông tin covarage Unit Test của bạn. https://cloud.githubusercontent.com/assets/137793/17071162/db6f253e-502d-11e6-9d84-e40c3d75f333.png https://cloud.githubusercontent.com/assets/137793/17071163/db6f9f0a-502d-11e6-816c-edb2c66fad8d.png

Kết Luận

Trên đây là những gem mình hay sử dụng để viết Unit Test sẽ còn thiếu sót rất nhiều nhưng cơ bản sẽ giúp bạn có thể viết làm quen được với Unit Test dễ dàng hơn. Và tùy vào mục đích và như cầu của bạn cũng còn rất nhiều gem khác có thể hỗ trợ thêm và tốt hơn nữa như:

//
gem "capybara"
gem "selenium-webdriver"
gem "webdrivers"

gem "rails-controller-testing"
gem "action-cable-testing"
gem "rspec-collection_matchers"
...

All Rights Reserved