RSpec Integration Tests and Capybara

Đối với một lập trình ROR(ruby on rails) đều biết đến rspec một công cụ viết test trên ROR. Rspec dẽ dàng giúp chúng ta viêt test cho các controller, các model.. hơn thế nữa khi đi cùng simplecov chúng ta còn dẽ dàng biết được số lương Code Coverage. Tuy nhiên, khi viết test với controller, model chúng ta chỉ có thể kiểm tra được sự đúng sai của từng phương thức,. Nhưng sự hoạt động đúng đắn của hệ thống vẫn chưa chắc chắn. Chúng ta không thể khẳng định là khi click vào nút Login thì giao diện đã hiển thị đúng hay chức năng login đã chạy chính xác... Tất cả những vấn đề trên sẽ được Capybara giúp chúng ta giải quết. Vì vậy mà trong bài viết này tôi muốn trình bày cách sử dụng Capybara.

Cài đặt

  • Bước 1: Capybara chạy được trên Ruby 1.9.3 trở lên. Để cài đặt, thêm dòng sau vào Gemfile and chạy bundle install:
gem 'capybara'
  • Bước 2: Trong Rails app ta thêm dòng sau vào file rspec_helper.rb:
require 'capybara/rails'
  • Cuối cùng là tạo thư mục spec/features.

Sử dụng

Để bắt đầu ta xét ví dụ với test cho trang login như sau:

# spec/features/visitor_signs_up_spec.rb
require 'spec_helper'

feature 'Visitor signs up' do
  scenario 'with valid email and password' do
    sign_up_with '[email protected]', 'password'

    expect(page).to have_content('Sign out')
  end

  scenario 'with invalid email' do
    sign_up_with 'invalid_email', 'password'

    expect(page).to have_content('Sign in')
  end

  scenario 'with blank password' do
    sign_up_with '[email protected]', ''

    expect(page).to have_content('Sign in')
  end

  def sign_up_with(email, password)
    visit sign_up_path
    within("//form[@id='sessions']") do
         fill_in 'Email', with: email
         fill_in 'Password', with: password
    end
    click_button 'Sign up'
  end
end

Trong đó:

  • visit: Khai báo đừng link trang web. mà ở đây là trang login
  • within : tìm kiếm 1 phần tử trên trang web mà cụ thể trong ví dụ trên là tìm tới form có id là sessions
  • fill_in : tìm kiếm các phần tử trên trang web. Ở đây ta tìm kiếm tới id là email và passoword và gán các giá trị tương ứng tại key with
  • page : Là giá trị mặc đinh được trả về sai khi submit nút login.

Để chạy test ta sử dụng câu lệnh rspec -fd và được kết quả như sau:

$ rspec -fd
Visitor signs up
 with valid email and password
 with invalid email
 with blank password

Finished in 0.35837 seconds
3 examples, 0 failures

Trong ví dụ trên ta có expect kết quả page trả về phải có chứa nội dung "Sign up" hoặc "Sign out". Ngoài ra Capybara còn hỗ trợ một số phương thức khác để expect. Ví dụ:

expect(page).to have_selector('table tr')
expect(page).to have_selector(:xpath, '//table/tr')
expect(page).to have_no_selector(:content)

expect(page).to have_xpath('//table/tr')
expect(page).to have_css('table tr.foo')
expect(page).to have_content('foo')
expect(page).to have_no_content('foo')
...

Để biết thêm các phương thức và cách sử dụng của Capybara, các bạn xem tại: https://github.com/teamcapybara/capybara#the-dsl

Mở rộng

Không chỉ dừng lại ở đó. Capybara còn có thể kết hợp với selenium để tạo test tự động. Ta cũng có thể chụp lại màn hình kết quả sau khi chạy test. Để thực hiện ta phải cài đặt các gem sau:

gem "capybara-webkit"
gem "selenium-webdriver"
gem "capybara-screenshot"

Để chạy được selenium ta chỉ cần tạo dirver chạy selenium. Thêm các config sau vào spec_helper.rb:

...
Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, browser: :chrome)
end

Capybara.javascript_driver = :chrome

Capybara.configure do |config|
  config.default_max_wait_time = 10 # seconds
  config.default_driver        = :selenium
end

Để hiểu rõ hơn cùng xem ví dụ đơn giản sau:

describe SessionsController do
  include Capybara::DSL
  it "signs super ok" do
    session = Capybara::Session.new(:selenium)

    session.visit 'http://testSelenium/signin'

    session.fill_in 'email', with: '[email protected].com'
    session.fill_in 'Password', with: '123456789'

    session.find('#btn_submit').click

    Capybara.default_wait_time = 3

    session.save_screenshot("file.png")

    expect(session.find('.navbar-nav .active a')).to have_text("Client List")
  end
end

Chúng ta dễ dàng thấy chỉ cần khai báo Capybara::Session.new(:selenium). Khi chạy qua dòng này chương trình sẽ tự gọi trình duyệt web chrome lên và thực hiện những câu lệnh được cài đặt ở dưới. Chúng ta sẽ dễ dàng nhìn thấy sự hoạt động của nó trên màn hình. Điều cần chú ý ở đây khác với chạy thông thường là ta phải chỉ định đường link thực sự của web (http://testSelenium/signin).

Tài liệu tham khảo