Bài viết gốc: https://hackernoon.com/how-to-integrate-selenium-with-capybara-iq2n30dg
Đôi khi bạn muốn biết các test case capybara
của bạn tương tác với trang của bạn như thế nào, đôi khi việc xem log trên console để tìm hiểu tại sao các test case không hoạt động là không đủ, đó là lý do tại sao bạn muốn làm cho nó hiển thị các bước trên trình duyệt trong thời gian thực. Bạn có thể thực hiện việc này thực sự dễ dàng với việc sử dụng Selenium, nó cung cấp cho chúng ta các chức năng cần thiết để tương tác với giao diện của tất cả các trình duyệt phổ biến.
Hãy bắt đầu bằng cách xem những gì chúng ta sẽ sử dụng trong bài viết này, bạn có thể sử dụng các phiển bản của riêng mình nhưng sẽ tốt hơn nếu chúng là:
1 2 3 4 5 6 7 | $ lsb_release -a Ubuntu 18.04.4 LTS $ rails -v Rails 6.0.3.1 $ ruby --version ruby 2.6.5p114 (2019–10–01 revision 67812) [x86_64-linux] |
Ok, giờ chúng ta có thể bắt đầu tạo dự án mới:
1 2 | $ rails new myApp -T |
chúng ta sử dụng cờ -T để không khởi tạo dự án cùng các file test bởi vì chúng ta sẽ tạo các file này theo cách thủ công. Sau khi lệnh chạy xong, chúng ta cần vào trong folder của dự án:
1 2 | $ cd myApp |
Tôi luôn kiểm tra xem server có thể chạy hay không để đảm bảo mọi thứ hoạt động chính xác, nếu có lỗi nào hiện nên trên console thì cũng có thể biết được.
1 2 | $ rails s |
Nếu mọi thứ đều ổn, chúng ta có thể tiếp tục.
Để tuân theo TDD, đầu tiên, chúng ta cần tạo các test case với RSpec và Capybara, vì thế hãy bắt đầu bằng việc thêm các Gem cần thiết trong nhóm development và test trong Gemfile:
1 2 3 4 5 6 7 8 9 | group <span class="token symbol">:development</span><span class="token punctuation">,</span> <span class="token symbol">:test</span> <span class="token keyword">do</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> gem <span class="token string">'rspec-rails'</span><span class="token punctuation">,</span> <span class="token string">'~> 4.0'</span><span class="token punctuation">,</span> <span class="token string">'>= 4.0.1'</span> gem <span class="token string">'capybara'</span><span class="token punctuation">,</span> <span class="token string">'~> 3.32'</span><span class="token punctuation">,</span> <span class="token string">'>= 3.32.2'</span> gem <span class="token string">'selenium-chúng tabdriver'</span><span class="token punctuation">,</span> <span class="token string">'~> 3.142'</span><span class="token punctuation">,</span> <span class="token string">'>= 3.142.7'</span> <span class="token keyword">end</span> |
Chú ý, 3 dấu dấu chấm ở trên là để biểu thị các gem đã có sẵn trong dự án của bạn.
Giờ chúng ta có thể cài đặt các gem trên (bạn có thể sử dụng lệnh bundle install
cũng được, hai lệnh này giống nhau):
1 2 | $ bundle |
Nếu mọi thứ đã cài đặt thành công, chúng ta cần cài đặt, và thiết lập cho các gem trên, Để cài đặt RSpec, chúng ta chỉ cần chạy lệnh sau:
1 2 | rails g rspec:install |
Người bạn gặm nhấm nhỏ bé của chúng ta, Capybara sẽ cần nhiều công sức hơn một chút. Đầu tiên, chúng ta cần đặt đoạn mã sau vào dòng đầu tiên của file /spec/rspec_helper.rb
:
1 2 | <span class="token keyword">require</span> <span class="token string">'capybara/rspec'</span> |
Trong file /spec/rails_helper.rb
:
1 2 3 4 5 6 | <span class="token constant">Capybara</span><span class="token punctuation">.</span>register_driver <span class="token symbol">:selenium_chrome</span> <span class="token keyword">do</span> <span class="token operator">|</span>app<span class="token operator">|</span> <span class="token constant">Capybara</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Selenium</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Driver</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span>app<span class="token punctuation">,</span> browser<span class="token punctuation">:</span> <span class="token symbol">:chrome</span><span class="token punctuation">)</span> <span class="token keyword">end</span> <span class="token constant">Capybara</span><span class="token punctuation">.</span>javascript_driver <span class="token operator">=</span> <span class="token symbol">:selenium_chrome</span> |
chúng ta cũng cần đổi tham số use_transactional_fixtures
thành false
:
1 2 | config<span class="token punctuation">.</span>use_transactional_fixtures <span class="token operator">=</span> <span class="token boolean">false</span> |
Đây là đoạn code cho thấy file rails_helper.rb
sẽ trông như thế nào sau tất cả các thay đổi, và xoá đi các bình luận:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <span class="token keyword">require</span> <span class="token string">'spec_helper'</span> <span class="token constant">ENV</span><span class="token punctuation">[</span><span class="token string">'RAILS_ENV'</span><span class="token punctuation">]</span> <span class="token operator">||</span><span class="token operator">=</span> <span class="token string">'test'</span> <span class="token keyword">require</span> <span class="token builtin">File</span><span class="token punctuation">.</span>expand_path<span class="token punctuation">(</span><span class="token string">'../config/environment'</span><span class="token punctuation">,</span> __dir__<span class="token punctuation">)</span> abort<span class="token punctuation">(</span><span class="token string">'The Rails environment is running in production mode!'</span><span class="token punctuation">)</span> <span class="token keyword">if</span> <span class="token constant">Rails</span><span class="token punctuation">.</span>env<span class="token punctuation">.</span>production<span class="token operator">?</span> <span class="token keyword">require</span> <span class="token string">'rspec/rails'</span> <span class="token keyword">require</span> <span class="token string">'./spec/support/factory_bot'</span> <span class="token keyword">begin</span> <span class="token constant">ActiveRecord</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Migration</span><span class="token punctuation">.</span>maintain_test_schema<span class="token operator">!</span> <span class="token keyword">rescue</span> <span class="token constant">ActiveRecord</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">PendingMigrationError</span> <span class="token operator">=</span><span class="token operator">></span> e puts e<span class="token punctuation">.</span>to_s<span class="token punctuation">.</span>strip exit <span class="token number">1</span> <span class="token keyword">end</span> <span class="token constant">Capybara</span><span class="token punctuation">.</span>register_driver <span class="token symbol">:selenium_chrome</span> <span class="token keyword">do</span> <span class="token operator">|</span>app<span class="token operator">|</span> <span class="token constant">Capybara</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Selenium</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Driver</span><span class="token punctuation">.</span><span class="token keyword">new</span><span class="token punctuation">(</span>app<span class="token punctuation">,</span> browser<span class="token punctuation">:</span> <span class="token symbol">:chrome</span><span class="token punctuation">)</span> <span class="token keyword">end</span> <span class="token constant">Capybara</span><span class="token punctuation">.</span>javascript_driver <span class="token operator">=</span> <span class="token symbol">:selenium_chrome</span> <span class="token constant">RSpec</span><span class="token punctuation">.</span>configure <span class="token keyword">do</span> <span class="token operator">|</span>config<span class="token operator">|</span> config<span class="token punctuation">.</span>fixture_path <span class="token operator">=</span> <span class="token string">"<span class="token interpolation"><span class="token delimiter tag">#{</span><span class="token punctuation">:</span><span class="token punctuation">:</span><span class="token constant">Rails</span><span class="token punctuation">.</span>root<span class="token delimiter tag">}</span></span>/spec/fixtures"</span> config<span class="token punctuation">.</span>use_transactional_fixtures <span class="token operator">=</span> <span class="token boolean">false</span> config<span class="token punctuation">.</span>infer_spec_type_from_file_location<span class="token operator">!</span> config<span class="token punctuation">.</span>filter_rails_from_backtrace<span class="token operator">!</span> <span class="token keyword">end</span> |
Ngoài ra, chúng ta cũng cần phải cài đặt chromium chrome driver, Nếu bạn vẫn chưa cài đặt nó. Với Ubuntu, bạn chỉ cần chạy lệnh sau:
1 2 3 | sudo apt-get update sudo apt-get install chromium-chromedriver |
Nếu bạn sử dụng hệ điều hành khác, bạn có thể truy cập vào trang chủ của chromedriver và thực hiện theo hướng dẫn https://chromedriver.chromium.org/downloads.
Được rồi, vì chúng ta đã làm khá nhiều việc mà thậm chí chưa viết một test case nào, cuối cùng chúng ta có thể viết nó. Chúng ta cần tạo một folder tên là features
bên trong thư mục /spec
, và bên trong nó, chúng ta tạo file posts_spec.rb
bao gồm test case của chúng ta.
/spec/features/posts_spec.rb
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">require</span> <span class="token string">'rails_helper'</span> <span class="token constant">RSpec</span><span class="token punctuation">.</span>describe <span class="token constant">Post</span><span class="token punctuation">,</span> driver<span class="token punctuation">:</span> <span class="token symbol">:selenium_chrome</span><span class="token punctuation">,</span> js<span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token keyword">do</span> describe <span class="token string">'the create posts process'</span> <span class="token keyword">do</span> it <span class="token string">'should create a post'</span> <span class="token keyword">do</span> visit new_post_path fill_in <span class="token string">'Title'</span><span class="token punctuation">,</span> with<span class="token punctuation">:</span> <span class="token string">'Post title'</span> fill_in <span class="token string">'Content'</span><span class="token punctuation">,</span> with<span class="token punctuation">:</span> <span class="token string">'Post content'</span> click_button <span class="token string">'Create Post'</span> expect<span class="token punctuation">(</span>page<span class="token punctuation">)</span><span class="token punctuation">.</span>to have_content <span class="token string">'Post was successfully created.'</span> <span class="token keyword">end</span> <span class="token keyword">end</span> <span class="token keyword">end</span> |
Dòng đầu tiên yêu cầu file rails_helper
và nạp các đoạn code trong nó, sau đó, như được mô tả trong tài liệu của RSpec, ta sử dụng RSpec.describe
để gói gọn các đoạn code của bạn theo test case, điều quan trọng là chỉ ra việc sử dụng driver cụ thể nào, trong trường hợp này, là :selenium_chrome
driver. Ngoài ra, chúng ta cần cho phép sử dụng JavaScript với js: true
bởi vì đôi khi selenium gặp vấn đề nếu không có nó.
Và test case của chúng ta đã hoàn thành!
Tuy nhiên, nó sẽ thất bại, như mong đợi.
Bởi vì chúng ta vẫn chưa triển khai tính năng này trong dự án của chúng ta. Nhưng đừng lo lắng, chúng ta sẽ làm nó ngay bây giờ.
Để có thể đạt được mục tiêu của chúng ta một cách trực tiếp, tôi sẽ bỏ qua các cấu trúc cần thiết thường thấy, ví dụ như là liên quan đến post thì sẽ là một user. Trong ứng dụng của chúng ta, một post sẽ được tạo ẩn danh, nghĩa là, nó không thuộc sở hữu của user nào cả.
Và để tiết kiệm thời gian, tôi sẽ sử dụng scaffold
để tạo một module CRUD đơn giản, chỉ việc sử dụng câu lệnh sau:
1 2 | $ rails g scaffold Post title content:text |
Sau đó chạy migrate database:
1 2 | $ rails db:migrate |
Hiện giờ, chúng ta có thể truy cập vào đường dẫn localhost:3000/posts
trên trình duyệt, là nơi liệt kê tất cả các post được tạo trong ứng dụng của tôi.
chúng ta vẫn chưa có post nào được tạo, nhưng chúng ta có thể tiến hành tạo một cái với capybara test
, chỉ cần chạy lệnh sau:
1 2 | $ rspec spec/features/posts_spec.rb |
Trình duyệt của bạn sẽ tự động mở và điền vào form.
Bây giờ chúng ta có thể ăn mừng vì test case đã thành công!
Một chú ý cuối cùng: đảm bảo điều này hoạt động chỉ với ứng dụng ruby on rails của bạn, nếu không thì, không phải Capybara
đang chạy trên trang web của bạn.
Và đó là tất cả cho bài viết này. Tôi hy vọng nó sẽ hữu ích cho bạn.