面試准備——(三)Selenium(1)基礎問題及自動化測試


滴滴面試:

1. 自己負責哪部分功能?

農餐對接系統分為了兩大子系統,一個是個人訂餐系統,二是餐館、個人與農產品供應商進行農產品交易系統。我主要負責組織測試人員對該系統進行測試。

我們測試分為兩個階段

一、功能測試階段。主要負責編寫測試計划、測試用例、部署禪道BUG管理系統,進行功能測試。

首先,我們將系統分為了訂餐平台、采購平台、登錄注冊、消費者/餐館/供應商后台等七個模塊。

其次,使用等價類划分和邊界值分析法相結合,針對每個模塊設計測試用例。

二、 UI層自動化測試。使用PO設計模式,工具是Selenium+Unit test+Jenkins。

2.1 目的

這個階段,是在我們項目需求已經明確,版本已經穩定的情況下開始的,主要考慮了幾個方面

1. UI層在多平台、多瀏覽器下運行結果存在不同。也就是需要我們在不同平台、瀏覽器下運行相同的測試案例,大量的重復勞作力

2. 其次,我們項目因為前期設計不夠嚴謹、版本部署不夠規范,會出現BUG重復出現的情況,也就是需要我們每日構建后進行回歸測試。

3. 同時,自己希望能夠鍛煉編程能力。

2.2 內容

在設計UI層自動化測試用例的時候,使用的是PO設計模式,也就是把每一個頁面所需要操作的元素和步驟都封裝在一個頁面類中。然后 Selenium+Unit test搭建四層框架——實現數據、腳本、業務邏輯分離(關鍵字驅動)

1)基礎層(BasePage)

設計一個基本的Page類,所有頁面皆繼承該類。提供了一個頁面需要實現的基本功能及公共方法。

2)業務邏輯層(Pages):

按照PO設計模式,將每個頁面抽象為一個類,放在Pages包里面,每個頁面繼承Basepage,可調用Data層數據,內容包括:

  • 該頁面所有的操作對象屬性
  • 實現的功能

3)數據層(Data)

該層存放相關數據,例如:用戶數據和密碼。在測試用例可通過調用數據層的數據來進行操作。

4)測試用例層(Testcases)

每一個測試用例testcase都對應Pages里面的一個頁面,繼承unnitest.TestCase類。通過調用對應頁面類的方法,數據層的數據、增加斷言(assert)來驗證功能的正確性。

此外通過Jenkins自動執行測試、代碼質量檢測和部署到測試服務器、部署到生產服務器上

 

2.3 自動化測試執行策略——三個階段

使用Jenkins持續集成工具來執行測試腳本和部署,主要設置了三個任務:

  • tm_test:用於執行自動化測試腳本,檢測代碼質量
  • tm_staging_deploy:用於在測試服務器上部署代碼
  • tm_deploy:用於在生產服務器上部署

我們將測試分為三個階段

1. 開發新的需求時,創建分支devN。當在這個分支中,需求開發完成或者Bug修復,就配合測試人員利用JUNit框架進行單元測試以及功能測試。通過測試后,合並到master上。

2. 當master有變動,則觸發tm_test任務,執行自動化測試腳本和代碼質量檢測。如果通過則自動觸發tm_staging_deploy,部署到測試服務器,如果沒有通過,自動化測試腳本會將Bug截圖發送給測試人員。

3. 登陸生產服務器上,對網站進行功能測試。如果通過測試,則手動觸發tm_deploy,部署到生產服務器。如果沒有通過,在禪道管理系統上把bug指派給相應模塊的開發人員。

 

2. 在使用Selenium中遇到的最大的問題?如何解決?——測試用例的可靠性

http://blog.csdn.net/kufei123/article/details/47375065

誤報通常是我們在使用selenium的最頭疼的問題,這使得很難把selenium測試用例加入到自動構建中。有些構建是必須要成功的,如果失敗將會阻塞整個發布流程。

解決方法——重試我們的解決方案是在測試步驟和測試集中都加入重試機制

產生誤報最大原因是selenium在頁面加載完成之前就開始請求頁面資源。

重試機制:

利用遞歸封裝了一個等待元素的方法。其中,設置最大等待時間為1s,輪詢時間為50ms,這個方法會不斷輪詢,直到方法執行成功或者超過設置的最大等待時間。在我們最好的一次實踐中,我們把一個測試用例的誤報率從10%降低到0,並且執行時間從原先的45秒降低到33秒。

@annotation.tailrec
private def retry[A](maxWaitMillis: Long, pollIntervalMillis: Long)(callback: => A): A = {
 val start = System.currentTimeMillis

 Try {
   callback
 } match {
   case Success(value) => value
   case Failure(thrown) => {
     val timeForTest = System.currentTimeMillis - start
     val maxTimeToSleep = Math.min(maxWaitMillis - pollIntervalMillis, pollIntervalMillis)
     val timeLeftToSleep = maxTimeToSleep - timeForTest

     if (maxTimeToSleep <= 0) {        throw thrown      }      else {        if (timeLeftToSleep > 0) {
         Thread.sleep(timeLeftToSleep)
       }
       retry(maxWaitMillis - pollIntervalMillis, pollIntervalMillis)(callback)
     }
   }
 }
}

 

 

其余還有元素定位問題:

我們主要通過Selenium WebDriver進行元素定位。但是會遇到兩大類定位不到元素的情況:

1. ElementNotVisible元素不可見

對於這種情況,這個元素display = none/hidden,通過JS更改display = block來解決

2. NoSuchElementException沒有這種元素

1)最常見的:頁面沒有加載完全,我們就去定位這個元素。

2)動態ID無法定位元素——1)直接使用Xpath相對路徑;2)根據部分元素定位

3)Iframe——switch_to_iframe

4) Alert——switch_to_alert

5)下拉框——Select標簽下拉框、二次定位

 

3. UI層自動化測試的作用?發現什么BUG?

他就是功能測試,使用WebDriver真實的模擬了用戶的操作過程。

 

4.有無發現selenium的BUG

 

5. 與人工測試相比,Selenium測試的產出,相對的優勢?

 

6. 有沒有封裝過Selenium方法?

有,在BasePage層,我們就對實現一個頁面的基本功能進行了封裝。

例如:

1. 設置重試機制。

2. 對webdriver各種方法進行封裝。

 

7. JUnit如何實現,它的功能是什么?什么時候使用?

 

 一、Selenium基本認識

1. 什么是Selenium?

Selenium是瀏覽器自動化工具,主要用來Web的自動化測試,以及基於Web的任務管理自動化。它支持的語言有:python、Java、ruby、JavaScript等,並且幾乎能在主流的瀏覽器上運行。

Selenium2.0、Selenium3.0主要由三大部分組成:SeleniumIDE、Selenium WebDriver、Selenoium Grid。

  • Selenium IDE錄制和回放腳本,可以模擬用戶對頁面的真實操作,區別於其他工具:是通過攔截http請求。
    • 一般只把錄制腳本當作一個輔助功能,因為一個UI節點的細微變化,都可能導致自動化測試工具無法識別,當測試項目項目大時,定位、更新十分困難。
    • 其次,錄制的腳本有時候人工難以理解。
  • Selenium Grid實現在多台機器上、和異構環境中並行執行測試用例。並行執行不僅節省時間,而且可以同時在不同的瀏覽器、平台上運行自動化測試腳本。
  • Selenium Web Driver:針對各個瀏覽器而開發,通過原生瀏覽器支持或者擴展(Chrome webDrive、FireFox WebDriver)直接控制瀏覽器

    VS Selenium RC(Selenium1.0):在瀏覽器中運行javaScript,使用瀏覽器內置的JavaScript來翻譯和執行selense

2. Selenium的特點有:

  • 支持錄制和回放(Selenium IDE)
  • 通過WebDriver,直接控制瀏覽器,而不是通過攔截HTTP請求,實現真正模仿了用戶的操作;同時使用WebDriver能夠靈活的獲取頁面元素(WebDriver),並且提供執行JS的接口
  • 能夠分布式運行在不同機器和異構環境中(不同瀏覽器)

 

3. Selenium的內部運行機制?如何能夠跨瀏覽器使用?——WebDriver原理(&RC原理)

1)RC原理

在Selenium1.0中,是通過Selenium RC服務器作為代理服務器去訪問應用從而達到測試的目的。

Selenium RC分為三個部分,Launcher、HttpProxy、Core。

  • Launcher用於啟動瀏覽器,把Selenium Core加載到瀏覽器中,並且把瀏覽器的代理設置為Selenium Server的Http Proxy。
  • Core是一堆JavaScript的集合,所以本質相當於運行這些JavaScript函數來實現對Html頁面的操作。——這也是為什么可以運行在幾乎所有主流的瀏覽器上。

然而直接運行JavaScript會有極大的安全漏洞,所以會受到“同源限制”,在這個基礎上,Selenium2.0引入了WebDriver。

2)Web Driver原理

webDriver是按照client/server模式設計的。client是我們的測試腳本,發送請求;server就是打開的瀏覽器,用來接收client的請求並作出響應。

具體的工作流程:

  1. webDriver打開瀏覽器並綁定到指定端口。啟動的瀏覽器作為遠程服務器remote server
  2. client通過CommandExecuter發送http請求給遠程服務器的偵聽端口(the wire protocal)
  3. 遠程服務器根據原生的瀏覽器組件來轉化為瀏覽器的本地(native)調用

所以web Driver用到的協議

  1. 打開瀏覽器時:HTTP協議
  2. client端發送http請求到遠程服務器的偵聽端口:the wire protocol

其中:

  • 有線協議:指的是從點到點獲取數據的方式,是應用層的協議。
  • HTTP協議:是用於從服務器傳輸超文本標記語言HTML到客戶端的通信協議。是一個應用層協議,由請求/響應構成,是一個標准的客戶/服務器模式。是一個無狀態的協議。(無狀態:對事務沒有記憶能力,不會保存這次傳輸的信息——節約內存)

4. 如何提高selenium腳本的執行速度?

1)優化測試用例。

  • 盡可能不用sleep、減少使用implicityWait,而使用WebDriverWait/FluentWait,這樣可以優化等待時間
  • 減少不必要的操作步驟。

2)使用Selenium grid,通過testNG實現並發執行。 

說到這里,在編寫測試用例的時候,一定要實現松耦合,然后再服務器允許的情況下,盡量設置多線程實現並發運行。

3)設置等待時間、中斷頁面加載。如果頁面加載內容太多,我們可以查看一下加載緩慢的原因,在不影響測試的情況下,可以設置超時時間,中斷頁面加載。

 

5. 提高自動化腳本穩定性

首先我們要分析出不穩定的原因,然后有針對的去解決。

1)頁面加載內容太多。如果頁面加載內容太多,在不影響測試的情況下,我們可以設置超時時間,中斷頁面加載。

2)網絡原因。設置等待時間,如果在響應時間內沒有加載成功,則重新執行測試。

3)優化代碼,減少容易沖突的函數。

4)多線程運行時,測試用例間相互影響。在並發操作時,如果用例之間的耦合性沒有設計好,就會有影響。

綜上所述,我們就可以用線程的方式來監控測試進程的WEB加載執行狀態

  • 在頁面會發生跳轉時,啟動一個Thread來監控進程的狀況。
  • 在Thread的run方法中定義一個計時器。
    • 如果計時器超時,則可以刷新頁面,計時器清零;
    • 若此時刷新頁面再次超時,則關閉當前瀏覽器進程,fail掉這個測試用例,繼續執行其他的測試用例。

6. 高質量自動化腳本特點

  1. 業務和代碼分離,封裝性好。
  2. 用例之間耦合性低,獨立性強,易於擴展維護

7. 你覺得自動化測試最大的缺陷是什么?

1. 一旦項目發生變化,測試用例就需要改進,工作量大。

2. 驗證的范圍有限,操作更加復雜,比如說簡單的一個驗證驗證碼,如果是人工識別很快就可以輸入,但是自動化測試中會增添很多困難。那么這個時候速度也不如人工。

3. 不穩定

4. 可靠性不強

5. 成本與收益

 

8. Selenium用JavaScript去操作頁面元素會碰到什么問題?Selenium是如何解決這個問題的?

然而直接在瀏覽器中運行JavaScript會有很大的安全漏洞,所以就會受到“同源策略”的限制。也就是,當你去要運行一個腳本的時候,會進行同源檢查,只有和被操控網頁同源的腳本才能被運行。

Selenium1.0是通過采用代理模式來解決這個問題的。

  • 首先測試腳本向Selenium Server發出Http請求建立,那么Selenium Server通過Launcher來啟動服務器,將Core加載到瀏覽器頁面中,並將瀏覽器代理設置為Http Proxy。
  • 其次,測試腳本發送Http請求,Selenium Server對這個Http進行解析,然后通過代理服務器發送JS命令通知Core執行操作瀏覽器的動作,Core接受到指令后,執行操作。
  • Selenium Server得到瀏覽器的Http的請求后,重組請求,獲取對應的頁面。
  • 最后代理服務器將這個頁面返回給瀏覽器。

在這個基礎上,Selenium2.0是通過webDriver來時先跨平台的。WebDriver是針對各個瀏覽器來開發,是一個遠程控制界面,提供了一組接口來發現和操作Web文檔中的DOM元素並控制用戶代理的行為。

二、自動化測試設計

1. 為什么想到做UI自動化測試?

在前期,我們也配合了開發人員使用JUnit框架進行單元測試,測試覆蓋率從0提升到50%。

但是隨着版本的穩定,我們開始考慮UI層是與客戶交互最多的界面,如果要提高用戶體驗,必須從UI層入手。其次,大量並且重復的勞動力都集中在UI層,所以我們考慮到進行UI層自動化測試解放勞動力

 

2. 如何設計Selenium的自動化測試腳本?

我們從以下幾個方面來回答:

1. 自動化測試的內容?

2. 自動化測試用例設計的原則

3. 使用的框架/設計模式

 

3. PO設計模式,四層框架——數據、業務邏輯、測試腳本分離(關鍵字驅動)

2.1 PO設計模式

將一個頁面內的操作對象(按鈕框、輸入框等)和操作的步驟封裝在每個Page里面,也Page為單位進行管理。這樣Selenium測試用例能夠通過調用頁面類來獲取頁面元素,從而巧妙的避開了當頁面元素的ID等屬性發生變化時,修改代碼的情況。——>提高了代碼的復用性、可讀性及減少工作量。

2.2 四層架構:

1. 基礎層(BasePage)

設計一個基本的Page類,所有頁面皆繼承該類。提供了一個類需要實現的基本功能及公共方法。

2. 業務邏輯層(Pages):

按照PO設計模式,將每個頁面抽象為一個類,放在Pages包里面,每個頁面繼承Basepage,可調用Data層數據,內容包括:

  • 該頁面所有的操作對象屬性
  • 實現的功能

3. 數據層(Data)

該層存放相關數據,例如:用戶數據和密碼。在業務邏輯層可通過調用數據層的數據來進行操作。

4. 測試層(Testcases)

每一個測試用例testcase都對應Pages里面的一個頁面,繼承unnitest.TestCase類。通過調用對應頁面類的方法,增加斷言(assert)來驗證功能的正確性。其中每個測試用例都以test_開頭。

 

此外通過Jenkins自動執行測試、代碼質量檢測和部署到測試服務器、部署到生產服務器上

 

4. 自動化測試執行策略

自動化測試用例的執行主要是通過Jenkins來實現的。而執行的策略是根據測試用例的類別、目的來設計的。

在Jenkins中,我們設定了三個任務

  • tm_test:用於執行自動化測試腳本,檢測代碼質量
  • tm_staging_deploy:用於在測試服務器上部署代碼
  • tm_deploy:用於在生產服務器上部署

測試用例的目的分為三種情況:

1)用來監控。

在此目的下,我們就把自動化測試用例設置成定時執行的,如果每五分鍾或是一個小時執行一次,在jenkins上創建一個定時任務即可。

2)必須回歸的用例

當修復了新功能或者Bug以后,首先開發人員進行冒煙測試,如果通過了JUnit單元測試,交給測試人員進行功能測試。通過測試后,合並到master。

master一旦有變化,則觸發tm_test任務執行自動化測試腳本和代碼質量檢測。如果通過,則自動觸發tm_staging_deploy,部署到staging服務器上,沒有通過的話,自動化測試腳本會自動發送Bug截圖給測試人員。

3)不需要經常執行的測試用例/生產服務器上的代碼

有些非主要業務線的代碼,或者生產服務器上的代碼已經很穩定了,不需要時時回歸,所以我們采用人工執行,在jenkins創建一個任務,需要執行的時候人工去構建即可。

 

三、Jenkins

Jenkins是持續集成的工具,能夠自動執行測試和代碼檢測,以及部署到服務器上。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM