12/08/2018, 11:57

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 ...

capybara.jpg

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

  1. https://github.com/jnicklas/capybara
  2. http://www.rubydoc.info/github/jnicklas/capybara/master
0