Day 24 介绍 Capybara 及设定

该文章同步发布於:我的部落格

在我们 new 出一个全新的 Rails 专案时,会在 Gemfile 里面看到预设的测试套件,分别是:capybara & selenium-webdriver & webdrivers

後面两个从名字上就可以很明显的感受的,像是要操纵网页的概念,而事实也是如此喔!

Capybara 本身就是模仿一个真实使用者来测试你的应用程序,所以我们会需要有 selenium 这样的工具来帮助我们自动化的启动浏览器。

有点像我们撰写程序语言,来操控一个虚拟的人物和浏览器互动的概念,从等等的程序码就能感受得到了!

基於 Rails 专案本身就有安装 capybara 了,我们就会直接用 RSpec 的视角来讲一下这个东西该怎麽使用。

Capybara 的优点

为什麽 Rails 会选择 Capybara 做为预设的套件呢?

其实我也不清楚,但我自己有几个觉得还蛮不错的地方可以分享一下!

1. 不需要特别的 set up

这件事情对於我来说就很好,因为像是这种要脱离 Rails 专案设定一些关於网际网路的参数,或是一些看起来很麻烦的事情。

其实都会打断开发的时程,所以有一个好的套件,可以让你即插即用是很赞的一件事!

2. 直观的 API 像人类的语言

等等示范的程序码里面,就会看到很有趣的 capybara API,都是一些超级简单的英文,非常直观。

例如:访问一个网站

visit ( 访问的 url )

这样就会模拟一个用户造访这个网站,是不是看起来真的非常直白呢?

3. 可以无痛切换无头模式以及实际浏览器

一般来说 capybara 会在无头模式下进行测试网站,而无头模式的浏览器是什麽意思?

无头浏览器就是没有我们现在使用的这些介面,通常透过 command line 来进行沟通。

而切换浏览器模式就是,我们可以在测试的时候让他弹出浏览器的画面,并且在你面前输入帐号密码等等,以便测试!

而 Capybara 可以让你在这两者间作切换,但不需要更动你原先的程序码。

上面是三个我自己觉得很厉害的地方,可能因为 capybara 实在是太实用了吧,就被 Rails 官方给绑定了~

实际使用

在 RSpec 中,前天有提到的 Feature test,重要度非常高,就是使用 capybara 来完整整个流程。

那我们要如何在 RSpec 中使用它呢?

我们只要给他正确的 tag 就可以了。

像这样:

RSpec.feature 'test something', type: :feature do
 ....
end

使用 RSpec.feature 并加入了 type: :feature / type: :system 就可以使用了喔!

有没有真的很符合我提到的优点呢? 基本上真的不太需要什麽特别的设定就可以简单地使用了喔!

使用情境

接着会用一些简单的程序码让人可以快速理解 capybara 在做些什麽,以及 feature test 到底在做些什麽呢?

假设我们要针对 登入 这项功能来做 feature test,我们可以先试想一下整个情境以及流程。

# 进入登入页面 > 填写帐号以及密码 > 登入成功

这边先不考虑失败的情境,因为其实就是反过来而已!

我们先上程序码再慢慢解说:

RSpec.feature 'Sign In', type: :feature do
  
  before do
    create(:user)
    # 先让资料库有这笔资料
  end

  scenario 'sign in process' 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

这边的 scenario 等同於之前我们使用的 it, 但语意更明确一些像是创造一个情境的概念。

接着我们看到第 9 行的程序码,拜访 /sessins/new 这个网站,但这边的写法不太好,其实我们可以用 rails 的 routes prefix 来造访网站喔!

visit new_user_session # users/sessions#new

而看到第 10 行 within('#session') 是找到这个表格,而 #session 这就是我们熟悉的 CSS 选择器找 ID 的用法。

进入表格後呢,找到 Email 以及 Password 这两个栏位并且填入我们事先创建好的 User 的帐号密码!

在到 第 14 行,按下登入按钮,并且期待页面会有 Success 的文字出现!

这样算是完成了一个简易的 feature test,这边的示范也呼应了我提到的第二个优点,Capybara 使用超级简单的英文,让呼叫 API 的过程变得流畅和舒服!

所以我们这次的测试流程是:

# 拜访登入网站 > 找到登入的表格 > 填写帐号密码 > 按下登入按钮 > 期待看到成功讯息!

因为是自动化的测试程序,所以机器其实比我们想像的还要笨,你必要要给予他很琐碎的指令,你可以往上拉看到,以人类的我们来说想像的测试流程非常简便。

是因为人类的脑袋帮助我们节省了很多习以为常的事情,但对於写程序来说,这些都是要考虑进去的喔!

常见问题

1. 我想看到浏览器弹出来的样子!

我们只需要在 spec_helper.rb 里面加入:

Capybara.javascript_driver = :selenium_chrome

他就会在执行 feature test 的时候,从无头模式切换到浏览器模式喔!

第一次看到的时候真的觉得超酷的,他会自动的填写帐号密码等等,真的像一个真实的使用者!

2. 为什麽我的页面找不到按钮了?

常常会遇到在 click_button 的时候找不到按钮的情形。

最常遇到的有三种可能:

第一种:你的按钮是跟随着资料出现的,例如:编辑这颗按钮,在你没有资料的情境下,画面上就真的没有,所以要记得在 before do 的时候先建立好相关的资料,让测试的情境更写实喔!

第二种:你的按钮在 mobile 的情形下会消失,有些专案可能会需要在 mobile 的情境时 hidden 某些按钮,那就会造成 capybara 找不到它,所以我们也可以设定在测试时的视窗大小喔!

一样在 spec_helper.rb 加入:

config.before(:each, js: true) do
  Capybara.page.current_window.resize_to(1080, 1920)
end

这样在每次测试前,都会以这样的视窗太小在进行测试。

第三种:你的按钮是伴随着事件出现的,例如你点了某个按钮後,会利用 Ajax 到後端并且 render 出新的按钮,但对於 capybara 来说,一切都太快了,他还没等到按钮出现,就已经在 click 了,自然而然就找不到。

所以我们也可以在 spec_helper.rb 加入:

Capybara.default_max_wait_time = 5

其实原先的 default 是两秒,但我们可以提高秒数,来试试看会不会通过测试!

3. 怎麽找我要的元素?

capybara 有提供 css selector 以及 xpath 两种方式来找到网页上的元素,当你找不到的时候,可以检查是不是资料在测试前写入的顺序不对,或是关联没建立好等等。

小结

今天的 capybara 就介绍到这边,关於他的使用方法实在是太多了,但在官方文件都有详细的说明,各个方法要如何使用。

但大部分都脱离不了以使用者角度出发的,拜访网站、点击按钮、填写等等

也有一些有趣的小功能,说不定会在你需要的时候使用到喔!


<<:  LeetCode 双刀流:70. Climbing Stairs

>>:  练习严谨

Day 22 Context

第 22 天 ! 当我们资料项下传递的时候, 会发现, component 的阶层越深, 传递资讯会...

1. STM32-STM32CubeIDE 安装/程序码补齐功能

STM32CubeIDE安装 首先可以到官网下载对应系统的安装档 STM32官网 选择对应系统下载後...

Day 2 | 游戏发想过程

主题发想 最一开始我们希望做一个以妖怪为主题的AR游戏,经过讨论以及资料收集後,发现山海经里的神兽与...

[DAY17] 关於 DAL 的一些问题

Q: 为甚麽原本 ActiveRecord 提供的 ORM 不用,要再包一层自己的 ORM? 在本系...

Day11 iPhone捷径-媒体Part1

Hello 大家, 明明是普通的周末, 不知为何这周一堆人出去玩@@ 我错过了甚麽吗? 今天来讲媒体...