Sử dụng test framework Capybara với RSpec
Chắc hẳn các lập trình viên Ruby on Rails đều biết đến RSpec - một công cụ viết test phổ biến cho Rails. RSpec giúp chúng ta dễ dàng viết test cho các controller, các model, ... Tuy nhiên, như vậy vẫn là chưa đủ. Khi viết test với các controller và model, chúng ta chỉ có thể kiểm tra sự đúng ...
Chắc hẳn các lập trình viên Ruby on Rails đều biết đến RSpec - một công cụ viết test phổ biến cho Rails. RSpec giúp chúng ta dễ dàng viết test cho các controller, các model, ... Tuy nhiên, như vậy vẫn là chưa đủ. Khi viết test với các controller và model, chúng ta chỉ có thể kiểm tra sự đúng sai của những method trong đó, nhưng sự hoạt động đúng đắn của ứng dụng chúng ta vẫn chưa thể dám chắc. Bạn có chắc chắn được khi click vào nút "Login" khi đã nhập tên tài khoản và mật khẩu đúng nó sẽ dẫn tới trang chúng ta mong muốn? Hay nói cách khác bạn có chắc chắn giao diện đăng nhập của bạn hoạt động đúng đắn không khi chỉ có mỗi controller login đúng? Capybara sẽ giúp chúng ta giải quyết vấn đề trên. Để hiểu rõ hơn về khả năng của Capybara, hãy cùng tôi đi tìm hiểu sâu hơn về nó nhé (yeah).
Capybara giúp cho bạn test các ứng dụng web của mình bằng cách mô phỏng một người dùng thực sẽ tương tác với ứng dụng của bạn như thế nào.
Những lợi ích chính
- Không nhất thiết phải cài đặt ứng dụng Rails và Rack.
- API trực quan: bắt chước giống ngôn ngữ mà một người dùng thực tế sử dụng.
- Tính năng đồng bộ mạnh mẽ có nghĩa là bạn sẽ không bao giờ phải tự chờ đợi quá trình không đồng bộ hoàn thành.
Cài đặt
Capybara yêu cầu Ruby phiên bản 1.9.3 hoặc cao hơn. Để cài đặt, thêm dòng sau vào Gemfile rồi chạy bundle install:
# Gemfile gem 'capybara'
Nếu ứng dụng bạn đang test là ứng dụng Rails, hãy thêm dòng sau vào test helper file:
require 'capybara/rails'
Sử dụng Capybara với RSpec
Nếu bạn đang sử dụng Rails, hãy để Capybara specs vào trong thư mục spec/features.
Nếu bạn không sử dụng Rails, hãy đánh dấu tất cả các example groups mà bạn muốn sử dụng Capybara với type: :feature
Bây giờ, bạn có thể viết một specs giống như sau:
describe "the signin process", :type => :feature do before :each do User.make(:email => 'hung@gmail.com', :password => 'password') end it "signs me in" do visit '/sessions/new' within("#session") do fill_in 'Email', :with => 'hung@gmail.com' fill_in 'Password', :with => 'password' end click_button 'Sign in' expect(page).to have_content 'Success' end end
Một số hàm sử dụng trong Capybara
Chú ý rằng, theo mặc định Capybara chỉ xác định được các thành phần có thể nhìn thấy được. Đó là bởi vì, một người dùng thực tế sẽ không thể tương tác được với các thành phần bị ẩn.
Navigation
Bạn có thể sử dụng hàm visit để chuyển sang các trang khác:
visit('/entries') visit(entry_comments_path(entry))
Do hàm visit chỉ nhận một tham số, nên request method của nó luôn luôn là GET.
Bạn có thể lấy current pathcủa một phiên truy cập cho một expect như sau:
expect(current_path).to eq(entry_comments_path(entry))
Clicking links và buttons
Bạn có thể tương tác với ứng dụng web bằng cách nhấn vào các button hay link trên giao diện web. Capybara giúp thực thi điều này như sau:
click_link('id-of-link') click_link('Link Text') click_button('Save') click_on('Link Text') # có thể click vào link hoặc button click_on('Button Value')
Tương tác với các Form
Có một số hàm hỗ trợ tương tác với các thành phần của form như sau:
fill_in('Full Name', :with => 'Vuong Hung') fill_in('Password', :with => '12345678') fill_in('Description', :with => 'A handsome boy...') choose('A Radio Button') check('A Checkbox') uncheck('A Checkbox') attach_file('Image', '/path/to/image.jpg') select('Option', :from => 'Select Box')
Để biết nhiều thêm về các actions khác, bạn có thể tham khảo tại đây Capybara::Node::Actions
Querying
Capybara có nhiều tùy chọn cho việc truy vấn trang về sự tồn tại của các thành phần nào đó, làm việc và thao tác với các thành phần đó.
page.has_selector?('table tr') page.has_selector?(:xpath, '//table/tr') page.has_xpath?('//table/tr') page.has_css?('table tr.foo') page.has_content?('foo')
Bạn có thể sử dụng chúng với các magic matchers của RSpec như sau:
expect(page).to have_selector('table tr') expect(page).to have_selector(:xpath, '//table/tr') expect(page).to have_xpath('//table/tr') expect(page).to have_css('table tr.foo') expect(page).to have_content('foo')
Để biết nhiều thêm về các matchers khác, bạn có thể tham khảo tại đây Capybara::Node::Matchers
Tìm kiếm
Bạn có thể tìm kiếm các thành phần trong trang web để có thể thao tác với chúng như sau:
find_field('First Name').value find_link('Hello', :visible => :all).visible? find_button('Send').click find(:xpath, "//table/tr").click find("#overlay").find("h1").click all('a').each { |a| a[:href] }
find sẽ chờ đợi một thành phần xuất hiện trên trang web. Nếu như thành phần đó không xuất hiện, nó sẽ raise một error.
Scoping
Capybara cho phép chúng ta giới hạn những hành động nhất định, ví dụ nhưu tương tác với các form hoặc click vào các link hay button ở trong một vùng cụ thể của trang web. Để làm được điều này, bạn sử dụng hàm within.Bạn có thể tùy chọn các selector khác nhau để sử dụng, ví dụ như sau:
within("li#employee") do fill_in 'Name', :with => 'Hung' end within(:xpath, "//li[@id='employee']") do fill_in 'Name', :with => 'Hung' end
Ngoài ra còn có một số hàm khác dành cho các fieldset hoặc table, định danh bởi id hoặc đoạn text của fieldset hay table đó:
within_fieldset('Employee') do fill_in 'Name', :with => 'Hung' end within_table('Employee') do fill_in 'Name', :with => 'Hung' end
Làm việc với các cửa sổ
Capybara cung cấp một số hàm giúp chúng ta dễ dàng tìm kiếm và chuyển đổi cửa sổ trang web:
facebook_window = window_opened_by do click_button 'Like' end within_window facebook_window do find('#login_email').set('a@example.com') find('#login_password').set('qwerty') click_button 'Submit' end
Scripting
Bạn có thể dễ dàng thực thi Javascript trong test như sau:
page.execute_script("$('body').empty()") page.execute_script("$('button#next').prop('disabled', false)")
Modals
Bạn có thể chấp nhận, từ chối hay đáp ứng đối với các alert, confirm và prompt. Bạn có thể chấp nhận hay từ chối một alert message bằng cách sử dụng block accept_alert và dismiss_alert:
accept_alert do click_link('Show Alert') end dismiss_alert do click_link('Show Alert') end
Tương tự như vậy, bạn có thể chấp nhận hay từ chối một confirm hay một prompt bằng cách sử dụng các block tương tự như:
dismiss_confirm do click_link('Show Confirm') end accept_prompt(with: 'Linus Torvalds') do click_link('Show Prompt About Linux') end
Debugging
Nó có thể hữu dụng để chụp được ảnh của trang hiện tại:
save_and_open_page
Bạn cũng có thể lấy được trạng thái hiện tại của DOM như một string sử dụng page.html:
print page.html
Trên đây mới chỉ là một số hàm hữu dụng được sử dụng nhiều khi bạn viết test sử dụng RSpec, để tìm hiểu thêm những tính năng khác, các bạn có thể tham khảo tại đây Capybara gem. Hi vọng bài viết này đã đem lại cho bạn đọc một cái nhìn tổng quát về việc sử dụng test framework Capybara để test ứng dụng web của mình (yeah).
Nguồn tham khảo
- https://github.com/jnicklas/capybara
- http://www.rubydoc.info/github/jnicklas/capybara/master