[Rails] [TDD] Hướng dẫn viết feature testing
Bài đăng này đã không được cập nhật trong 3 năm
Bài viết này hướng dẫn cách viết feature testing cho 1 rails app
- Vậy feature testing là gì?
Định nghĩa chi tiết thì các bạn đọc ở đây nhưng hiểu nôm na thì feature testing nghĩa là thực hiện 1 công việc test cho 1 chức năng (feature) như 1 người test.
Để minh họa cho các bạn dễ hiểu, thì khi chạy feature testing các bạn sẽ có kết quả như video sau
https://www.youtube.com/watch?v=GdIgVqJHbak&feature=youtu.be
Như vậy nghĩa 1 test case feature test đã bao gồm khá nhiều test case unit test (mặc dù k phải là tất cả).
Ví dụ bạn test việc fill vào form sau
thì các việc cần làm là
- Visit page http://localhost/books
- Fill fields
- Click button submit
- Expect result
Phân tích 1 chút.
-
Ở bước 1, visit page thì k có gì, bỏ qua nhe
-
Ở bước 2. Fill fields. Đơn giản là điền các giá trị cho các fields
-
Ở bước 3. Ở đây có thể xảy ra các trường hợp (tùy theo fill ở bước 2):
- blank title, author hay price
- title, author invalid (quá dài, ngắn, hoặc k đúng format... tùy theo validations của các bạn) hay price không đúng (ví dụ bạn nhập vào text hay ký tự đặc biệt...)
- và cuối cùng là all fields is valid.
-
Bước 4. Kết quả kỳ vọng, sẽ phụ thuộc vào từng trường hợp ở bước 2
- Ví dụ blank title thì màn hình thông báo phải có đoạn text "title can't blank" và current_path thay đổi
- Còn trong trường hợp valid thì mà hình có thông báo "Create book successfully" và current_path sẽ chuyển về book_path(:id)
Setup
- Tao project demo (mình dùng scaffold)
rails new sample_app
- Tạo 1 scaffold book gồm có title:string, author: string, price: float
rails g scaffold book title:string author:string price:float
-
OK, lúc này view http://localhost:3000/books/new thì các bạn có form như hình trên
-
Trong Gemfile
group :development, :test do
gem 'byebug'
gem 'rspec-rails'
gem 'capybara'
gem "selenium-webdriver"
end
Việc setup cho từng gem, các bạn xem trên github dùm mình.
- Trong model book.rb, giả sử mình có validation cho title
class Book < ActiveRecord::Base
validates :title, presence: true, length: { maximum: 50 }
end
- Việc setup tới đây coi như hoàn tất.
Test cases
Sau đó các bạn cần list ra các test cases có thể xảy ra. Ở ví dụ trên thì có thể
scenario "valid input" do
end
scenario "missing title" do
end
scenario "title too long" do
end
...
Trên đây mình chỉ đưa ra 1 số test case. Tùy theo validation và theo chương trình của các bạn mà lượng test case sẽ khác đi.
Implement
Các bạn tạo 1 folder features trong sample_app/spec
Trong folder features tạo 1 file create_book_spec.rb (sample_app/spec/features/create_book_spec.rb) với nội dung
require "rails_helper"
RSpec.feature "Create new book", type: :feature do
before do
visit new_book_path
end
end
Tiếp theo, ta cùng implement với từng test case cụ thể.
Trường hợp 1.
scenario "valid input" do
fill_in "book[title]", with: "god father"
click_button "Create Book"
expect(page).to have_text("Book was successfully created.")
end
Ở đây book[title] là name của 2 trường title trong form. Các bạn có thể set name theo ý mình trong code. Tuy nhiên, mình khuyên nên để name mặc định rails sinh ra cho mình.
Với các trường hợp còn lại, các bạn làm tương tự, và file create_book_spec.rb cuối cùng sẽ như sau
require "rails_helper"
RSpec.feature "Create new book", type: :feature do
before do
visit new_book_path
end
scenario "valid input" do
fill_in "book[title]", with: "god father"
click_button "Create Book"
expect(page).to have_text("Book was successfully created.")
end
scenario "mising title" do
click_button "Create Book"
expect(page).to have_text("Title can't be blank")
end
scenario "title too long", js: true do
fill_in "book[title]", with: "a" * 51
click_button "Create Book"
expect(page).to have_text("Title is too long (maximum is 50 characters)")
end
end
Problems
Tuy nhiên khi test thế này, ví dụ khi các bạn có 1 field, có value được update bằng jQuery, phụ thuộc theo giá trị các fields khác thì giá trị của field đó sẽ không được cập nhật, do chương trình test hiện tại không chạy js.
Các bạn fix bằng cách thêm js: true vào trước test case nào có dùng tới jQuery
scenario "valid input", js: true do
end
và lúc này, khi chạy test, các bạn sẽ thấy 1 điều khá thú vị là rspec sẽ tự động mở trình duyệt, fill vào các field, click button Submit và cho các bạn view page result.
Lời kết
Qua ví dụ trên, các bạn có thể viết feature test cho chương trình của mình. Việc viết feature test giúp các bạn có thể test chương trình như 1 tester, tuy nhiên nó chỉ giúp bạn hiểu rõ logic dự án và phần nào tránh được bugs chứ không thể thay thế hoàn toàn tester được.
Trên đây mình chỉ demo 1 ví dụ đơn giản, còn các controls như checkboxs, dropdowns... việc select hay fill những fields đó, các bạn tự tìm hiểu thêm.
Việc viết feature test không khó, khó là bạn phải cover được nhiều nhất case có thể xảy ra. Điều này thì phải nhờ đến tester rồi
All rights reserved