Capybara membantu Anda menguji aplikasi web dengan menyimulasikan bagaimana pengguna sebenarnya berinteraksi dengan aplikasi Anda. Ini agnostik tentang driver yang menjalankan pengujian Anda dan dilengkapi dengan dukungan Rack::Test dan Selenium bawaan. WebKit didukung melalui permata eksternal.
Jika Anda dan/atau perusahaan Anda menemukan nilai di Capybara dan ingin berkontribusi secara finansial untuk pemeliharaan dan pengembangan berkelanjutan, silakan kunjungi Patreon
Butuh bantuan? Tanyakan dalam diskusi (mohon jangan membuka masalah): https://github.com/orgs/teamcapybara/discussions/categories/qa
Capybara membutuhkan Ruby 3.0.0 atau lebih baru. Untuk menginstal, tambahkan baris ini ke Gemfile
Anda dan jalankan bundle install
:
gem 'capybara'
Jika aplikasi yang Anda uji adalah aplikasi Rails, tambahkan baris ini ke file pembantu pengujian Anda:
require 'capybara/rails'
Jika aplikasi yang Anda uji adalah aplikasi Rack, namun bukan Rails, setel Capybara.app ke aplikasi Rack Anda:
Capybara . app = MyRackApp
Jika Anda perlu menguji JavaScript, atau jika aplikasi Anda berinteraksi dengan (atau terletak di) URL jarak jauh, Anda perlu menggunakan driver lain. Jika menggunakan Rails 5.0+, tetapi tidak menggunakan pengujian sistem Rails dari 5.1, Anda mungkin juga ingin menukar "server" yang digunakan untuk meluncurkan aplikasi Anda ke Puma agar sesuai dengan default Rails.
Capybara . server = :puma # Until your setup is working
Capybara . server = :puma , { Silent : true } # To clean up your test output
Permata cucumber-rails
dilengkapi dengan dukungan Capybara bawaan. Jika Anda tidak menggunakan Rails, muat modul capybara/cucumber
secara manual:
require 'capybara/cucumber'
Capybara . app = MyRackApp
Anda dapat menggunakan Capybara DSL dalam langkah Anda, seperti:
When /I sign in/ do
within ( "#session" ) do
fill_in 'Email' , with : '[email protected]'
fill_in 'Password' , with : 'password'
end
click_button 'Sign in'
end
Anda dapat beralih ke Capybara.javascript_driver
( :selenium
secara default) dengan menandai skenario (atau fitur) dengan @javascript
:
@javascript
Scenario : do something Ajaxy
When I click the Ajax link
...
Ada juga tag eksplisit untuk setiap driver terdaftar yang disiapkan untuk Anda ( @selenium
, @rack_test
, dll).
Muat dukungan RSpec 3.5+ dengan menambahkan baris berikut (biasanya ke file spec_helper.rb
Anda):
require 'capybara/rspec'
Jika Anda menggunakan Rails, letakkan spesifikasi Capybara Anda di spec/features
atau spec/system
(hanya berfungsi jika Anda telah mengonfigurasinya di RSpec) dan jika Anda memiliki spesifikasi Capybara di direktori berbeda, tandai grup contoh dengan type: :feature
atau type: :system
tergantung pada jenis tes yang Anda tulis.
Jika Anda menggunakan spesifikasi sistem Rails, silakan lihat dokumentasinya untuk memilih driver yang ingin Anda gunakan.
Jika Anda tidak menggunakan Rails, tandai semua grup contoh di mana Anda ingin menggunakan Capybara dengan type: :feature
.
Anda sekarang dapat menulis spesifikasi Anda seperti ini:
describe "the signin process" , type : :feature do
before :each do
User . create ( email : '[email protected]' , password : 'password' )
end
it "signs me in" do
visit '/sessions/new'
within ( "#session" ) do
fill_in 'Email' , with : '[email protected]'
fill_in 'Password' , with : 'password'
end
click_button 'Sign in'
expect ( page ) . to have_content 'Success'
end
end
Gunakan js: true
untuk beralih ke Capybara.javascript_driver
( :selenium
secara default), atau berikan opsi :driver
untuk beralih ke satu driver tertentu. Misalnya:
describe 'some stuff which requires js' , js : true do
it 'will use the default js driver'
it 'will switch to one specific driver' , driver : :selenium
end
Capybara juga dilengkapi dengan DSL bawaan untuk membuat tes penerimaan deskriptif:
feature "Signing in" do
background do
User . create ( email : '[email protected]' , password : 'caplin' )
end
scenario "Signing in with correct credentials" do
visit '/sessions/new'
within ( "#session" ) do
fill_in 'Email' , with : '[email protected]'
fill_in 'Password' , with : 'caplin'
end
click_button 'Sign in'
expect ( page ) . to have_content 'Success'
end
given ( :other_user ) { User . create ( email : '[email protected]' , password : 'rous' ) }
scenario "Signing in as another user" do
visit '/sessions/new'
within ( "#session" ) do
fill_in 'Email' , with : other_user . email
fill_in 'Password' , with : other_user . password
end
click_button 'Sign in'
expect ( page ) . to have_content 'Invalid email or password'
end
end
feature
sebenarnya hanya sebuah alias untuk describe ..., type: :feature
, background
adalah alias untuk before
, scenario
untuk it
, dan given
/ given!
alias untuk let
/ let!
, masing-masing.
Terakhir, pencocokan Capybara juga didukung dalam spesifikasi tampilan:
RSpec . describe "todos/show.html.erb" , type : :view do
it "displays the todo title" do
assign :todo , Todo . new ( title : "Buy milk" )
render
expect ( rendered ) . to have_css ( "header h1" , text : "Buy milk" )
end
end
Catatan: Bila Anda memerlukan metode proxy 'capybara/rspec' dipasang untuk mengatasi tabrakan nama antara metode Capybara::DSL all
/ within
dan pencocokan RSpec bawaan yang bernama sama. Jika Anda memilih untuk tidak memerlukan 'capybara/rspec', Anda dapat menginstal metode proxy dengan mewajibkan 'capybara/rspec/matcher_proxies' setelah memerlukan RSpec dan 'capybara/dsl'
Jika Anda menggunakan Test::Unit
, tentukan kelas dasar untuk pengujian Capybara Anda seperti:
require 'capybara/dsl'
class CapybaraTestCase < Test :: Unit :: TestCase
include Capybara :: DSL
def teardown
Capybara . reset_sessions!
Capybara . use_default_driver
end
end
Jika Anda menggunakan pengujian sistem Rails, silakan lihat dokumentasinya untuk informasi tentang pemilihan driver yang ingin Anda gunakan.
Jika Anda menggunakan Rails, namun tidak menggunakan pengujian sistem Rails, tambahkan kode berikut di file test_helper.rb
Anda untuk membuat Capybara tersedia di semua kasus pengujian yang berasal dari ActionDispatch::IntegrationTest
:
require 'capybara/rails'
require 'capybara/minitest'
class ActionDispatch :: IntegrationTest
# Make the Capybara DSL available in all integration tests
include Capybara :: DSL
# Make `assert_*` methods behave like Minitest assertions
include Capybara :: Minitest :: Assertions
# Reset sessions and driver between tests
teardown do
Capybara . reset_sessions!
Capybara . use_default_driver
end
end
Jika Anda tidak menggunakan Rails, tentukan kelas dasar untuk pengujian Capybara Anda seperti:
require 'capybara/minitest'
class CapybaraTestCase < Minitest :: Test
include Capybara :: DSL
include Capybara :: Minitest :: Assertions
def teardown
Capybara . reset_sessions!
Capybara . use_default_driver
end
end
Ingatlah untuk memanggil super
di subkelas mana pun yang mengesampingkan teardown
.
Untuk mengganti driver, atur Capybara.current_driver
. Misalnya,
class BlogTest < ActionDispatch :: IntegrationTest
setup do
Capybara . current_driver = Capybara . javascript_driver # :selenium by default
end
test 'shows blog posts' do
# ... this test is run with Selenium ...
end
end
Ikuti instruksi di atas untuk Minitest dan tambahan memerlukan capybara/minitest/spec
page . must_have_content ( 'Important!' )
Capybara menggunakan DSL yang sama untuk menggerakkan berbagai browser dan driver tanpa kepala.
Secara default, Capybara menggunakan driver :rack_test
, yang cepat namun terbatas: tidak mendukung JavaScript, juga tidak dapat mengakses sumber daya HTTP di luar aplikasi Rack Anda, seperti API jarak jauh dan layanan OAuth. Untuk mengatasi keterbatasan ini, Anda dapat mengatur driver default yang berbeda untuk fitur Anda. Misalnya, jika Anda lebih suka menjalankan semuanya di Selenium, Anda dapat melakukan:
Capybara . default_driver = :selenium # :selenium_chrome and :selenium_chrome_headless are also registered
Namun, jika Anda menggunakan RSpec atau Cucumber (dan aplikasi Anda berjalan dengan benar tanpa JS), Anda mungkin ingin mempertimbangkan untuk membiarkan :rack_test
yang lebih cepat sebagai default_driver , dan hanya menandai pengujian yang memerlukan driver berkemampuan JavaScript menggunakan js: true
atau @javascript
, masing-masing. Secara default, pengujian JavaScript dijalankan menggunakan driver :selenium
. Anda dapat mengubahnya dengan menyetel Capybara.javascript_driver
.
Anda juga dapat mengubah driver untuk sementara (biasanya di blok Sebelum/penyiapan dan Setelah/pembongkaran):
Capybara . current_driver = :selenium # temporarily select different driver
# tests here
Capybara . use_default_driver # switch back to default driver
Catatan : mengganti driver akan membuat sesi baru, jadi Anda mungkin tidak dapat mengganti driver di tengah pengujian.
RackTest adalah driver default Capybara. Itu ditulis dalam Ruby murni dan tidak memiliki dukungan apa pun untuk mengeksekusi JavaScript. Karena driver RackTest berinteraksi langsung dengan antarmuka Rack, maka tidak memerlukan server untuk memulai. Namun, ini berarti jika aplikasi Anda bukan aplikasi Rack (Rails, Sinatra, dan sebagian besar kerangka kerja Ruby lainnya adalah aplikasi Rack) maka Anda tidak dapat menggunakan driver ini. Selain itu, Anda tidak dapat menggunakan driver RackTest untuk menguji aplikasi jarak jauh, atau untuk mengakses URL jarak jauh (misalnya, pengalihan ke situs eksternal, API eksternal, atau layanan OAuth) yang mungkin berinteraksi dengan aplikasi Anda.
capybara-mechanize menyediakan driver serupa yang dapat mengakses server jarak jauh.
RackTest dapat dikonfigurasi dengan serangkaian header seperti ini:
Capybara . register_driver :rack_test do | app |
Capybara :: RackTest :: Driver . new ( app , headers : { 'HTTP_USER_AGENT' => 'Capybara' } )
end
Lihat bagian tentang menambahkan dan mengkonfigurasi driver.
Capybara mendukung Selenium 3.5+ (Webdriver). Untuk menggunakan Selenium, Anda harus menginstal permata selenium-webdriver
, dan menambahkannya ke Gemfile jika Anda menggunakan bundler.
Capybara melakukan pra-registrasi sejumlah driver bernama yang menggunakan Selenium - yaitu:
Ini seharusnya berfungsi (dengan instalasi perangkat lunak yang relevan) dalam konfigurasi desktop lokal tetapi Anda mungkin perlu menyesuaikannya jika digunakan dalam lingkungan CI di mana opsi tambahan mungkin perlu diteruskan ke browser. Lihat bagian tentang menambahkan dan mengkonfigurasi driver.
Catatan : driver yang menjalankan server di thread berbeda mungkin tidak berbagi transaksi yang sama dengan pengujian Anda, menyebabkan data tidak dibagikan antara pengujian dan server pengujian Anda, lihat Transaksi dan pengaturan database di bawah.
Referensi lengkap tersedia di rubydoc.info .
Catatan: Secara default Capybara hanya akan mencari elemen yang terlihat. Hal ini karena pengguna sebenarnya tidak akan dapat berinteraksi dengan elemen yang tidak terlihat.
Catatan : Semua penelusuran di Capybara peka huruf besar-kecil . Hal ini karena Capybara banyak menggunakan XPath, yang tidak mendukung ketidakpekaan huruf besar/kecil.
Anda dapat menggunakan metode kunjungan untuk menavigasi ke halaman lain:
visit ( '/projects' )
visit ( post_comments_path ( post ) )
Metode kunjungan hanya membutuhkan satu parameter, metode permintaan selalu GET.
Anda bisa mendapatkan jalur sesi penjelajahan saat ini, dan mengujinya menggunakan pencocokan have_current_path
:
expect ( page ) . to have_current_path ( post_comments_path ( post ) )
Catatan : Anda juga dapat menegaskan jalur saat ini dengan menguji nilai current_path
secara langsung. Namun, menggunakan pencocokan have_current_path
lebih aman karena menggunakan perilaku menunggu Capybara untuk memastikan bahwa tindakan sebelumnya (seperti click_link
) telah selesai.
Referensi lengkap: Capybara::Node::Actions
Anda dapat berinteraksi dengan aplikasi web dengan mengikuti tautan dan tombol. Capybara secara otomatis mengikuti pengalihan apa pun, dan mengirimkan formulir yang terkait dengan tombol.
click_link ( 'id-of-link' )
click_link ( 'Link Text' )
click_button ( 'Save' )
click_on ( 'Link Text' ) # clicks on either links or buttons
click_on ( 'Button Value' )
Referensi lengkap: Capybara::Node::Actions
Ada sejumlah alat untuk berinteraksi dengan elemen formulir:
fill_in ( 'First Name' , with : 'John' )
fill_in ( 'Password' , with : 'Seekrit' )
fill_in ( 'Description' , with : 'Really Long Text...' )
choose ( 'A Radio Button' )
check ( 'A Checkbox' )
uncheck ( 'A Checkbox' )
attach_file ( 'Image' , '/path/to/image.jpg' )
select ( 'Option' , from : 'Select Box' )
Referensi lengkap: Capybara::Node::Matchers
Capybara memiliki serangkaian pilihan untuk menanyakan keberadaan elemen tertentu pada halaman, dan bekerja dengan serta memanipulasi elemen tersebut.
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' )
Catatan: Bentuk negatif seperti has_no_selector?
berbeda dengan not has_selector?
. Baca bagian tentang JavaScript asinkron untuk penjelasannya.
Anda dapat menggunakan ini dengan pencocokan ajaib RSpec:
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' )
Referensi lengkap: Capybara::Node::Finders
Anda juga dapat menemukan elemen tertentu untuk memanipulasinya:
find_field ( 'First Name' ) . value
find_field ( id : 'my_field' ) . value
find_link ( 'Hello' , :visible => :all ) . visible?
find_link ( class : [ 'some_class' , 'some_other_class' ] , :visible => :all ) . visible?
find_button ( 'Send' ) . click
find_button ( value : '1234' ) . click
find ( :xpath , ".//table/tr" ) . click
find ( "#overlay" ) . find ( "h1" ) . click
all ( 'a' ) . each { | a | a [ :href ] }
Jika Anda perlu menemukan elemen berdasarkan atribut/properti tambahan, Anda juga dapat melewati blok filter, yang akan diperiksa di dalam perilaku menunggu normal. Jika Anda merasa perlu sering menggunakan ini, Anda mungkin lebih baik menambahkan pemilih khusus atau menambahkan filter ke pemilih yang sudah ada.
find_field ( 'First Name' ) { | el | el [ 'data-xyz' ] == '123' }
find ( "#img_loading" ) { | img | img [ 'complete' ] == true }
Catatan : find
akan menunggu elemen muncul di halaman, seperti yang dijelaskan di bagian Ajax. Jika elemen tersebut tidak muncul maka akan memunculkan error.
Semua elemen ini memiliki semua metode Capybara DSL yang tersedia, sehingga Anda dapat membatasinya pada bagian halaman tertentu:
find ( '#navigation' ) . click_link ( 'Home' )
expect ( find ( '#navigation' ) ) . to have_button ( 'Sign out' )
Capybara memungkinkan untuk membatasi tindakan tertentu, seperti berinteraksi dengan formulir atau mengklik link dan tombol, ke dalam area halaman tertentu. Untuk tujuan ini Anda dapat menggunakan metode generik dalam . Secara opsional, Anda dapat menentukan jenis pemilih yang akan digunakan.
within ( "li#employee" ) do
fill_in 'Name' , with : 'Jimmy'
end
within ( :xpath , ".//li[@id='employee']" ) do
fill_in 'Name' , with : 'Jimmy'
end
Ada metode khusus untuk membatasi cakupan ke kumpulan bidang tertentu, yang diidentifikasi dengan id atau teks tag legenda kumpulan bidang, dan ke tabel tertentu, yang diidentifikasi dengan id atau teks tag keterangan tabel.
within_fieldset ( 'Employee' ) do
fill_in 'Name' , with : 'Jimmy'
end
within_table ( 'Employee' ) do
fill_in 'Name' , with : 'Jimmy'
end
Capybara menyediakan beberapa metode untuk memudahkan mencari dan berpindah jendela:
facebook_window = window_opened_by do
click_button 'Like'
end
within_window facebook_window do
find ( '#login_email' ) . set ( '[email protected]' )
find ( '#login_password' ) . set ( 'qwerty' )
click_button 'Submit'
end
Di driver yang mendukungnya, Anda dapat dengan mudah menjalankan JavaScript:
page . execute_script ( "$('body').empty()" )
Untuk ekspresi sederhana, Anda dapat mengembalikan hasil skrip.
result = page . evaluate_script ( '4 + 4' ) ;
Untuk skrip yang lebih rumit, Anda harus menuliskannya sebagai satu ekspresi.
result = page . evaluate_script ( <<~JS , 3 , element )
(function(n, el){
var val = parseInt(el.value, 10);
return n+val;
})(arguments[0], arguments[1])
JS
Pada driver yang mendukungnya, Anda dapat menerima, mengabaikan, dan merespons peringatan, konfirmasi, dan perintah.
Anda dapat menerima pesan peringatan dengan menggabungkan kode yang menghasilkan peringatan dalam satu blok:
accept_alert 'optional text or regex' do
click_link ( 'Show Alert' )
end
Anda juga dapat menerima atau menolak konfirmasi dengan membungkusnya dalam satu blok:
accept_confirm 'optional text' do
click_link ( 'Show Confirm' )
end
dismiss_confirm 'optional text' do
click_link ( 'Show Confirm' )
end
Anda juga dapat menerima atau menolak perintah, dan juga menyediakan teks untuk diisi sebagai respons:
accept_prompt ( 'optional text' , with : 'Linus Torvalds' ) do
click_link ( 'Show Prompt About Linux' )
end
dismiss_prompt ( 'optional text' ) do
click_link ( 'Show Prompt About Linux' )
end
Semua metode modal mengembalikan pesan yang disajikan. Jadi, Anda dapat mengakses pesan prompt dengan menetapkan return ke variabel:
message = accept_prompt ( with : 'Linus Torvalds' ) do
click_link ( 'Show Prompt About Linux' )
end
expect ( message ) . to eq ( 'Who is the chief architect of Linux?' )
Akan berguna untuk mengambil cuplikan halaman seperti saat ini dan melihatnya:
save_and_open_page
Anda juga dapat mengambil status DOM saat ini sebagai string menggunakan page.html .
print page . html
Ini sebagian besar berguna untuk debugging. Anda sebaiknya menghindari pengujian terhadap konten page.html
dan menggunakan metode pencari yang lebih ekspresif.
Terakhir, di driver yang mendukungnya, Anda dapat menyimpan tangkapan layar:
page . save_screenshot ( 'screenshot.png' )
Atau simpan dan buka secara otomatis:
save_and_open_screenshot
Tangkapan layar disimpan ke Capybara.save_path
, relatif terhadap direktori aplikasi. Jika Anda memerlukan capybara/rails
, Capybara.save_path
akan default ke tmp/capybara
.
Helper dan matcher yang menerima Selector berbagi tanda tangan metode umum yang mencakup:
Argumen-argumen ini biasanya bersifat opsional dalam satu atau lain hal.
Argumen nama menentukan Pemilih yang akan digunakan. Argumennya opsional ketika helper secara eksplisit menyampaikan nama pemilih (misalnya, find_field
menggunakan :field
, find_link
menggunakan :link
, dll):
page . html # => '<a href="/">Home</a>'
page . find ( :link ) == page . find_link
page . html # => '<input>'
page . find ( :field ) == page . find_field
Argumen locator biasanya mewakili informasi yang dapat membedakan elemen yang cocok dengan pemilih dari elemen yang tidak:
page . html # => '<div id="greeting">Hello world</div>'
page . find ( :css , 'div' ) . text # => 'Hello world'
page . find ( :xpath , './/div' ) . text # => 'Hello world'
Metode pencari tujuan umum seperti find
dan all
dapat menerima pencari lokasi sebagai argumen posisi pertama ketika metode tersebut dapat menyimpulkan nilai default dari konfigurasi Capybara.default_selector
: