Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)
jvm版本: 1.8.0_65
selenium版本: v2.48.0 (Standalone Selenium Server)
参考来源:
Use Selenium Grid to enhance testing of web applications
Selenium WebDriver + Grid2 + RSpec之旅
Selenium (1) —— Selenium安装与测试(101 Tutorial)
准备
依照Selenium (1) —— Selenium安装与测试(101 Tutorial)搭建Selenium Grid环境,并且启动hub与浏览器代理
代码
-
一个简单的脚本(示例一)
我们以cnblogs登陆行为举例
在工作目录下新建文件login_cnblogs.rb,并添加以下代码
#encoding:utf-8 require 'selenium-webdriver' # 向hub请求一个firefox的webdriver dr = Selenium::WebDriver.for(:remote,:url => 'http://localhost:4444/wd/hub', :desired_capabilities => :firefox) #将浏览器导航至cnblogs网站的登陆页 dr.navigate.to 'http://passport.cnblogs.com/user/signin' #输入用户名 dr.find_element(:id,'input1').send_keys('weizhe_2008') #输入密码 dr.find_element(:id,'input2').send_keys(‘********’) #点击登录 dr.find_element(:id,'signin').click sleep 10 #关闭浏览器 dr.close
保存后在当前目录下,运行
$ ruby login_cnblogs.rb
查看firefox webdriver输出
查看selenium hub输出
如果一切正常,hub会自动运行一个firefox代理,然后执行我们以上的脚本并自动登陆cnblogs
以上我们只是完成了一个简单的自动化登陆的脚本,还不是一个完整的测试,下面我们引入rspec来将这个测试补充完整。
-
一个rspec测试脚本(示例二)
首先gem安装rspec
$ sudo gem install rspec
执行结果:
Successfully installed rspec-3.4.0 Parsing documentation for rspec-3.4.0 1 gem installed
新建文件login_cnblogs_spec.rb
#encoding:utf-8 # $ sudo gem install rspec require 'selenium-webdriver' require 'logger' RSpec.describe 'cnblogs main login page' do context 'input the wrong passwd' do it 'login failed,and return "用户名或密码错误"' do dr = Selenium::WebDriver.for(:remote,:url => 'http://localhost:4444/wd/hub',:desired_capabilities => :firefox) dr.navigate.to 'http://passport.cnblogs.com/user/signin' #输入用户名 dr.find_element(:id,'input1').send_keys('weizhe_2008') #输入密码 dr.find_element(:id,'input2').send_keys('********') #点击登录 dr.find_element(:id,'signin').click sleep 10 #result = dr.find_element(:id,'tip_btn').text result = dr.find_element(:id,'tip_btn').attribute("innerHTML") logger = Logger.new(STDOUT) logger.info(result) #rspec eq会自动为换行符加上 expect = '用户名或密码错误<br><br>联系 contact@cnblogs.com' expect(result).to eq(expect) #关闭浏览器 dr.close end end end
以上测试为一个登陆错误行为提供验证,如果登陆错误,页面上会提示“用户名或密码错误
联系 contact@cnblogs.com”字样,我们需要做的就是获取这段提示信息元素的内容,并查看期望的信息是否与之相同命令行运行
$ rspec login_cnblogs_spec.rb --format doc
返回信息
cnblogs main login page input the wrong passwd I, [2016-01-04T10:00:07.578980 #12150] INFO -- : 用户名或密码错误<br><br>联系 contact@cnblogs.com login failed,and return "用户名或密码错误" Finished in 12.21 seconds (files took 0.1758 seconds to load) 1 example, 0 failures
查看firefox代理下的输出
-
重构(示例三)
以上只是一个简单的测试,所有的信息都杂糅在一个文件中,要让测试用例变得健壮,易阅读,易维护。那就是通过面向对象的方式,再加上逻辑和数据分离的方式来处理,这个才是自动化测试的核心思想。
-
设计思路
设想对登录进行手工测试,会想到一些测试用例(验证错误的用户名正确的密码;用户名和密码为空直接点击登陆按钮。等等),如果每个用例都要写一套代码的话,会发现有些地方出现代码重复,不利于测试代码的维护。进一步研究发现, 有些测试对象也是可以复用的,比如在登陆的时候我们会用到密码输入框、点击登录按钮等,可以把这些“基本动作”封装到一个类中,这样代码的灵活性和适用性 将会更强。即,面向对象编程。
-
因此对测试目录结构做了一些调整:
新建一个文件夹tool,用来定义一些获取控件的方法
新建一个文件夹action,用来定义一下页面操作的方法
新建一个文件夹spec,用来存放测试用例
新建一个文件夹config,用来存放测试用例所涉及到的测试数据
-
对于测试数据的管理,采用yaml来管理
-
在我们的工作目录下创建文件夹Login_Page (表示这个是一个登录页面的测试)
-
在Login_Page下分别创建文件夹tool,action,spec,config
-
action文件夹中新建文件login_page.rb
-
config文件夹中新建文件login_data.yml
-
spec文件夹中新建文件login_cnblogs_spec.rb
-
tool文件夹中新建文件login_dialog.rb
-
-
-
../login/action/login_page.rb
#encoding:utf-8 require 'selenium-webdriver' require File.dirname(__FILE__)+'/../tool/login_dialog' class Login_Page include Login_Dialog def initialize(dr) @dr ||= dr end def login(username,passwd) get_username.send_keys(username) get_passwd.send_keys(passwd) get_submit.click end def message get_message.attribute("innerHTML") end end
-
../login/config/login_data.yml
data: mainpage: huburl: http://localhost:4444/wd/hub url: http://passport.cnblogs.com/login.aspx title: 用户登录 - 博客园用户中心 logindata: wrong: username: weizhe_2008 password: 12345678 message: '用户名或密码错误<br><br>联系 contact@cnblogs.com'
-
../login/spec/login_cnblogs_spec.rb
#encoding:utf-8 require 'selenium-webdriver' require 'rspec' require 'yaml' require File.dirname(__FILE__)+'/../tool/login_dialog' require File.dirname(__FILE__)+'/../action/login_page' describe 'cnblogs main login page' do include Login_Dialog before (:all) do @data = YAML.load (File.open(File.dirname(__FILE__)+'/../config/login_data.yml')) end before (:each) do @dr = Selenium::WebDriver.for(:remote,:url => @data["huburl"],:desired_capabilities => :firefox) @dr.navigate.to @data["url"] @dr.manage.window.maximize() @driver = Login_Page.new(@dr) end after (:each) do @dr.quit end context 'input the wrong passwd' do it 'login failed,and return "用户名或密码错误"' do @driver.login(@data["username"], @data["password"]) sleep 10 expect(@driver.message).to eql (@data["message"]) end end end
-
../login/tool/login_dialog.rb
#encoding:utf-8 require 'selenium-webdriver' module Login_Dialog def get_username @dr.find_element(:id,'input1') end def get_passwd @dr.find_element(:id,'input2') end def get_submit @dr.find_element(:id,'signin') end def get_message @dr.find_element(:id,'tip_btn') end end
在../login/spec下运行
:ruby Richard$ cd login
:login Richard$ ls
action config spec tool
:login Richard$ cd spec/
:spec Richard$ ls
login_cnblogs_spec.rb
:spec Richard$ rspec login_cnblogs_spec.rb --format doc
可以得到示例二中相同的结果