Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)

Richaaaard發表於2016-01-04

Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)


jvm版本: 1.8.0_65

selenium版本: v2.48.0 (Standalone Selenium Server)

參考來源:

Selenium官方下載

Use Selenium Grid to enhance testing of web applications

Homebrew

Selenium WebDriver + Grid2 + RSpec之旅

rspec.info

Selenium (1) —— Selenium安裝與測試(101 Tutorial)

準備

依照Selenium (1) —— Selenium安裝與測試(101 Tutorial)搭建Selenium Grid環境,並且啟動hub與瀏覽器代理

程式碼

  • 一個簡單的指令碼(示例一)

    我們以cnblogs登陸行為舉例

    Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)

    在工作目錄下新建檔案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 (2) —— Selenium WebDriver + Grid2(101 Tutorial)

    檢視selenium hub輸出

    Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)

    如果一切正常,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”字樣,我們需要做的就是獲取這段提示資訊元素的內容,並檢視期望的資訊是否與之相同

    Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)

    命令列執行

      $ 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代理下的輸出

    Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)

  • 重構(示例三)

    以上只是一個簡單的測試,所有的資訊都雜糅在一個檔案中,要讓測試用例變得健壯,易閱讀,易維護。那就是通過物件導向的方式,再加上邏輯和資料分離的方式來處理,這個才是自動化測試的核心思想。

    • 設計思路

      設想對登入進行手工測試,會想到一些測試用例(驗證錯誤的使用者名稱正確的密碼;使用者名稱和密碼為空直接點選登陸按鈕。等等),如果每個用例都要寫一套程式碼的話,會發現有些地方出現程式碼重複,不利於測試程式碼的維護。進一步研究發現, 有些測試物件也是可以複用的,比如在登陸的時候我們會用到密碼輸入框、點選登入按鈕等,可以把這些“基本動作”封裝到一個類中,這樣程式碼的靈活性和適用性 將會更強。即,物件導向程式設計。

    • 因此對測試目錄結構做了一些調整:

      新建一個資料夾tool,用來定義一些獲取控制元件的方法

      新建一個資料夾action,用來定義一下頁面操作的方法

      新建一個資料夾spec,用來存放測試用例

      新建一個資料夾config,用來存放測試用例所涉及到的測試資料

      Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)

    • 對於測試資料的管理,採用yaml來管理

      1. 在我們的工作目錄下建立資料夾Login_Page (表示這個是一個登入頁面的測試)
      2. 在Login_Page下分別建立資料夾tool,action,spec,config

      3. action資料夾中新建檔案login_page.rb

      4. config資料夾中新建檔案login_data.yml

      5. spec資料夾中新建檔案login_cnblogs_spec.rb

      6. 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

可以得到示例二中相同的結果

Selenium (2) —— Selenium WebDriver + Grid2(101 Tutorial)

結束

相關文章