0. 引言
在 上一篇 《Rails 在 Docker container 测试找不到浏览器》中讲了如何避免 Rails 默认的 :rack_test
驱动依赖浏览器,但是毕竟有需要浏览器模拟的前端测试,在 docker 中是如何实现的呢?
1. 下载 selenium chrome 镜像
Selenium 官方提供了 chrome 和 firefox 的镜像,我们使用 standalone 的方式,下载的是 selenium/standalone-chrome-debug
,因为 -debug
镜像是带有 VNC 服务的,可以提供可视化测试过程。
直接来看 docker-compose.yml
文件:
version: '3.7'
services:
[... other services]
web:
[... other configs]
depends_on:
- chrome
chrome:
image: selenium/standalone-chrome-debug
ports:
- 5900:5900
volumes:
- /dev/shm:/dev/shm
注:5900 是 VNC 服务器的端口,我们需要在 host 上访问所以要讲端口 export 出来,另外 4444 是 selenium 的端口,直接在 capybara 中配置就行了
2. 配置 RSpec
之前讲过用 :rack_test
驱动是不用依赖浏览器的,包括 Capybara 支持的一些 click_on
和 fill_in
等交互操作,但是 :rack_test
是不支持 JavaScript 测试的,所以为了测试 JS,以及看到自动化的浏览器模拟测试过程,需要在 RSpec 测试用例中指定是 JS 测试,然后配置 JS 测试相应的驱动以及服务器。
启用 JS 测试很简单,如下加入 js: true
即可:
RSpec.feature "test", type: :feature do # 也可以加在外层
scenario "test", js: true do
然后就是最关键的一步配置,可以直接写到 rails_helper.rb
,不过我更推荐去掉 rails_helper.rb
中 Dir[Rails.root.join('spec', 'support', '**', '*.rb')].each { |f| require f }
的注释,然后在 spec/support/
中新建配置文件:
Capybara.javascript_driver = :selenium_remote_chrome # 自定义 driver
Capybara.register_driver :selenium_remote_chrome do |app|
Capybara::Selenium::Driver.new(
app,
browser: :remote,
url: "http://chrome:4444/wd/hub", # remote chrome 就来自于 docker-compose.yml 中的 selenium/standalone-chrome-debug
desired_capabilities: :chrome)
end
RSpec.configure do |config|
config.before(:each, type: :feature) do
# 获取 server ip,需要根据 OS 调整命令
ip = `/sbin/ip route|awk '/scope/ { print $9 }'`
ip = ip.gsub "\n", ""
Capybara.server_port = "3000"
Capybara.server_host = ip
Capybara.app_host = "http://#{Capybara.current_session.server.host}:#{Capybara.current_session.server.port}"
end
config.after(:each, type: :feature) do
Capybara.reset_sessions!
Capybara.use_default_driver
Capybara.app_host = nil
end
end
这里有一个难点,就是在 web
中可以很容易的利用 docker 提供的方法通过 service name 访问到 http://chrome:4444/wd/hub
,但是在 chrome
中却不知道服务器的地址,于是我们直接用 shell 命令获取 ip 传给 Capybara,3000
端口是自己指定的,只要不与开发端口冲突就行。
至此,Capybara 的配置就完成了,在运行测试的时候可以在 console 观察到如下输出:
Capybara starting Puma...
* Version 4.3.1 , codename: Mysterious Traveller
* Min threads: 0, max threads: 4
* Listening on tcp://[web-ip]:3000 # web-ip 就是通过 ip 命令获取的地址
可见浏览器的依赖问题已经解决,并且测试也已经通过。
3. 通过 VNC 观察自动化测试过程
因为浏览器是跑在容器里的,所以需要安装 VNC 客户端连进去看,Docker for Mac
默认有安装 VNC 的客户端,在此我就直接介绍这种方式了。
在『Terminal』中直接输入:open vnc://localhost:5900
,在弹出的密码框输入 secret
,就会看到 Selenium 官方提供的准备界面了。
接下来只要跑 rspec
命令即可看到 VNC 窗口中自动弹出 chrome 浏览器并且自动完成测试内容。