滴滴面試:java
1. 本身負責哪部分功能?
農餐對接系統分爲了兩大子系統,一個是我的訂餐系統,二是餐館、我的與農產品供應商進行農產品交易系統。我主要負責組織測試人員對該系統進行測試。python
咱們測試分爲兩個階段:web
1、功能測試階段。主要負責編寫測試計劃、測試用例、部署禪道BUG管理系統,進行功能測試。面試
首先,咱們將系統分爲了訂餐平臺、採購平臺、登陸註冊、消費者/餐館/供應商後臺等七個模塊。編程
其次,使用等價類劃分和邊界值分析法相結合,針對每一個模塊設計測試用例。設計模式
2、 UI層自動化測試。使用PO設計模式,工具是Selenium+Unit test+Jenkins。瀏覽器
2.1 目的
這個階段,是在咱們項目需求已經明確,版本已經穩定的狀況下開始的,主要考慮了幾個方面:安全
1. UI層在多平臺、多瀏覽器下運行結果存在不一樣。也就是須要咱們在不一樣平臺、瀏覽器下運行相同的測試案例,大量的重複勞做力ruby
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如何實現,它的功能是什麼?何時使用?
1、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的請求並做出響應。
具體的工做流程:
- webDriver打開瀏覽器並綁定到指定端口。啓動的瀏覽器做爲遠程服務器remote server
- client經過CommandExecuter發送http請求給遠程服務器的偵聽端口(the wire protocal)
- 遠程服務器根據原生的瀏覽器組件來轉化爲瀏覽器的本地(native)調用
因此web Driver用到的協議:
- 打開瀏覽器時:HTTP協議
- 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. 高質量自動化腳本特色
- 業務和代碼分離,封裝性好。
- 用例之間耦合性低,獨立性強,易於擴展維護
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元素並控制用戶代理的行爲。
2、自動化測試設計
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建立一個任務,須要執行的時候人工去構建便可。
3、Jenkins
Jenkins是持續集成的工具,可以自動執行測試和代碼檢測,以及部署到服務器上。