python+selenium面試題
selenium中如何判斷元素是否存在?
selenium中沒有提供原生的方法判斷元素是否存在,一般我們可以通過定位元素+異常捕獲的方式判斷。
# 判斷元素是否存在
try:
dr.find_element_by_id(‘none‘)
except NoSuchElementException:
print ‘element does not exist‘
selenium中hidden或者是display = none的元素是否可以定位到?
不可以,selenium不能定位不可見的元素。display=none
的元素實際上是不可見元素。
selenium中如何保證操作元素的成功率?也就是說如何保證我點擊的元素一定是可以點擊的?
- 當網速不好的情況下,使用合適的等待時間
- 被點擊的元素一定要占一定的空間,因為selenium默認會去點這個元素的中心點,不占空間的元素算不出來中心點;
- 被點擊的元素不能被其他元素遮擋;
- 被點擊的元素不能在viewport之外,也就是說如果元素必須是可見的或者通過滾動條操作使得元素可見;
- 判斷元素是否是可以被點擊的
如何提高selenium腳本的執行速度?
- 使用更高配置的電腦和選擇更快的網絡環境
- 使用效率更高的語言,比如java執行速度就快過python
- 優化代碼
- 不要盲目的加
sleep
,盡量使用顯式等待 - 對於firefox,考慮使用測試專用的profile,因為每次啟動瀏覽器的時候firefox會創建1個新的profile,對於這個新的profile,所有的靜態資源都是從服務器直接下載,而不是從緩存裏加載,這就導致網絡不好的時候用例運行速度特別慢的問題
- chrome瀏覽器和safari瀏覽器的執行速度看上去是最快的
- 可以考慮分布式執行或者使用selenium grid
用例在運行過程中經常會出現不穩定的情況,也就是說這次可以通過,下次就沒辦法通過了,如何去提升用例的穩定性?
- 測試專屬profile,盡量讓靜態資源緩存
- 盡量使用顯式等待
- 盡量使用測試專用環境,避免其他類型的測試同時進行,對數據造成幹擾
你的自動化用例的執行策略是什麽?
- 每日執行:比如每天晚上在主幹執行一次
- 周期執行:每隔2小時在開發分之執行一次
- 動態執行:每次代碼有提交就執行
自動化測試的時候是不是需要連接數據庫做數據校驗?
一般不需要,因為這是單元測試層做的事情,在自動化測試層盡量不要為單元測試層沒做的工作還債。
id,name,clas,xpath, css selector這些屬性,你最偏愛哪一種,為什麽?
xpath和css最為靈活,所以其他的答案都不夠完美。
如何去定位頁面上動態加載的元素?
顯式等待
如何去定位屬性動態變化的元素?
找出屬性動態變化的規律,然後根據上下文生成動態屬性。
點擊鏈接以後,selenium是否會自動等待該頁面加載完畢?
java binding在點擊鏈接後會自動等待頁面加載完畢。
selenium的原理是什麽?
selenium的原理涉及到3個部分,分別是
- 瀏覽器
- driver: 一般我們都會下載driver
- client: 也就是我們寫的代碼
client其實並不知道瀏覽器是怎麽工作的,但是driver知道,在selenium啟動以後,driver其實充當了服務器的角色,跟client和瀏覽器通信,client根據webdriver協議發送請求給driver,driver解析請求,並在瀏覽器上執行相應的操作,並把執行結果返回給client。這就是selenium工作的大致原理。
webdriver的協議是什麽?
client與driver之間的約定,無論client是使用java實現還是c#實現,只要通過這個約定,client就可以準確的告訴drier它要做什麽以及怎麽做。
webdriver協議本身是http協議,數據傳輸使用json。
這裏有webdriver協議的所有endpoint,稍微看一眼就知道這些endpoints涵蓋了selenium的所有功能。
啟動瀏覽器的時候用到的是哪個webdriver協議?
New Session,如果創建成功,返回sessionId和capabilities。
什麽是page object設計模式?
官方介紹,簡單來說就是用class去表示被測頁面。在class中定義頁面上的元素和一些該頁面上專屬的方法。
例子
public class LoginPage {
private final WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
// Check that we‘re on the right page.
if (!"Login".equals(driver.getTitle())) {
// Alternatively, we could navigate to the login page, perhaps logging out first
throw new IllegalStateException("This is not the login page");
}
}
// The login page contains several HTML elements that will be represented as WebElements.
// The locators for these elements should only be defined once.
By usernameLocator = By.id("username");
By passwordLocator = By.id("passwd");
By loginButtonLocator = By.id("login");
// The login page allows the user to type their username into the username field
public LoginPage typeUsername(String username) {
// This is the only place that "knows" how to enter a username
driver.findElement(usernameLocator).sendKeys(username);
// Return the current page object as this action doesn‘t navigate to a page represented by another PageObject
return this;
}
// The login page allows the user to type their password into the password field
public LoginPage typePassword(String password) {
// This is the only place that "knows" how to enter a password
driver.findElement(passwordLocator).sendKeys(password);
// Return the current page object as this action doesn‘t navigate to a page represented by another PageObject
return this;
}
// The login page allows the user to submit the login form
public HomePage submitLogin() {
// This is the only place that submits the login form and expects the destination to be the home page.
// A seperate method should be created for the instance of clicking login whilst expecting a login failure.
driver.findElement(loginButtonLocator).submit();
// Return a new page object representing the destination. Should the login page ever
// go somewhere else (for example, a legal disclaimer) then changing the method signature
// for this method will mean that all tests that rely on this behaviour won‘t compile.
return new HomePage(driver);
}
// The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
public LoginPage submitLoginExpectingFailure() {
// This is the only place that submits the login form and expects the destination to be the login page due to login failure.
driver.findElement(loginButtonLocator).submit();
// Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials
// expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
return new LoginPage(driver);
}
// Conceptually, the login page offers the user the service of being able to "log into"
// the application using a user name and password.
public HomePage loginAs(String username, String password) {
// The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
typeUsername(username);
typePassword(password);
return submitLogin();
}
}
什麽是page factory?
Page Factory實際上是官方給出的java page object的工廠模式實現。
怎樣去選擇一個下拉框中的value=xx的option?
使用select類,具體看這裏
如何在定位元素後高亮元素(以調試為目的)?
使用javascript將元素的border或者背景改成黃色就可以了。
什麽是斷言?
可以簡單理解為檢查點,就是預期和實際的比較
- 如果預期等於實際,斷言通過,測試報告上記錄pass
- 如果預期不等於實際,斷言失敗,測試報告上記錄fail
如果你進行自動化測試方案的選型,你會選擇哪種語言,java,js,python還是ruby?
- 哪個熟悉用哪個
- 如果都不會,團隊用哪種語言就用那種
page object設置模式中,是否需要在page裏定位的方法中加上斷言?
一般不要,除非是要判斷頁面是否正確加載。
Generally don’t make assertions
page object設計模式中,如何實現頁面的跳轉?
返回另一個頁面的實例可以代表頁面跳轉。
// The login page allows the user to submit the login form
public HomePage submitLogin() {
// This is the only place that submits the login form and expects the destination to be the home page.
// A seperate method should be created for the instance of clicking login whilst expecting a login failure.
driver.findElement(loginButtonLocator).submit();
// Return a new page object representing the destination. Should the login page ever
// go somewhere else (for example, a legal disclaimer) then changing the method signature
// for this method will mean that all tests that rely on this behaviour won‘t compile.
return new HomePage(driver);
}
自動化測試用例從哪裏來?
手工用例的子集,盡量
- 簡單而且需要反復回歸
- 穩定,也就是不要經常變來變去
- 核心,優先覆蓋核心功能
你覺得自動化測試最大的缺陷是什麽?
- 實現成本高
- 運行速度較慢
- 需要一定的代碼能力才能及時維護
什麽是分層測試?
畫給他/她看。
webdriver可以用來做接口測試嗎?
不用糾結,不可以。
selenium 是否可以調用js來對dom對象進行操作?
是
selenium 是否可以向頁面發送鼠標滾輪操作?
不能
selenium 是否可以模擬拖拽操作?
可以
selenium 對下拉列表的中的選項進行選擇操作時,需要被操作對象的標簽是什麽?
select
selenium 上傳文件操作,需要被操作對象的type屬性是什麽?
file
1. 什麽是頁面加載超時
Selenium中有一個 Page Load wait的方法,有時候,我們執行腳本的速度太快,但是網頁程序還有一部分頁面沒有完全加載出來,就會遇到元素不可見或者元素找不到的異常。為了解決問題,讓腳本流暢的運行,我們可以通過設置頁面加載超時時間。具體代碼是這個:driver.manage().timeouts().pageLoadTimeout(10,TimeUnit.SECONDS);
這行作用就是,如果頁面加載超過10秒還沒有完成,就拋出頁面加載超時的異常。
2.什麽是JavaScript Executor,你什麽時候會用到這個?
JavaScript Executor是一個接口,給driver對象提供一個執行javaScript並訪問和修改前端元素屬性和值。
還是有比較多的場景,我們可能或者需要借助javaScript來實現:
1.元素通過現有定位表達式不能夠實現點擊
2.前端頁面試用了ck-editor這個插件
3.處理時間日期插件(可能)
4.生成一個alert彈窗
5.拖拽滾動條
基本語法:
JavascriptExecutor js =(JavascriptExecutor) driver;
js.executeScript(Script,Arguments);
相關具體例子:http://blog.csdn.net/u011541946/article/details/73751252
http://blog.csdn.net/u011541946/article/details/73656609
3.在Selenium中如何實現截圖,如何實現用例執行失敗才截圖
在Selenium中提供了一個TakeScreenShot這麽一個接口,這個接口提供了一個getScreenshotAs()方法可以實現全屏截圖。然後我們通過java中的FileUtils來實現把這個截圖拷貝到保存截圖的路徑。
代碼舉例:
File src=((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
try {
// 拷貝到我們實際保存圖片的路徑
FileUtils.copyFile(src,new File("C:/selenium/error.png"));
}
catch (IOException e)
{
System.out.println(e.getMessage());
}
如果要實現執行用例發現失敗就自動截圖,那麽我們需要把這個截圖方法進行封裝。然後在測試代碼中的catch代碼塊去調用這個截圖方法。這個我們在POM的框架中一般是把截圖方法封裝到BasePage這個文件中。
4.在Selenium中如何實現拖拽滾動條?
在Selenium中通過元素定位會自動幫你拖拽到對應位置,所以是沒有自帶的scoll方法。但是這個是有限制,例如當前頁面高度太長,默認是頁上半部分,你定位的元素在頁尾,這個時候可能就會報元素不可見的異常。我們就需要利用javaScript來實現拖拽頁面滾動條。
我們一般可以兩個方法去拖拽,一個是根據拖拽的坐標(像素單位),另外一個是根據拖拽到一個參考元素附件。
代碼舉例(根據元素坐標拖拽):
JavascriptExecutor jse= (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(0,250)", "");
相關拖拽文章:http://blog.csdn.net/u011541946/article/details/73656609
5.如何實現文件上傳?
我們在web頁面實現文件上傳過程中,可以直接把文件在磁盤完整路徑,通過sendKeys方法實現上傳。如果這種方法不能實現上傳,我們就可能需要借助第三方工具,我用過一個第三方工具叫autoIT.
參考博客文章:http://blog.csdn.net/u011541946/article/details/74359517
還有一個方法是利用robot類:
http://blog.csdn.net/u011541946/article/details/74332938
6.如何處理“不受信任的證書”的問題?
例如,在登錄12306網站的時候,如果你沒有下載和安裝過這個網站的根證書,那麽你就會遇到打開12306網站提示證書不受信任的攔截頁面。
下面舉例火狐和谷歌上處理這個問題的基本代碼
火狐:
// 創建firefoxprofile
FirefoxProfile profile=new FirefoxProfile();
// 點擊繼續瀏覽不安全的網站
profile.setAcceptUntrustedCertificates(true);
// 使用帶條件的profile去創建一個driver對象
WebDriver driver=new FirefoxDriver(profile);
Chrome:
// 創建類DesiredCapabilities的對象
DesiredCapabilities cap=DesiredCapabilities.chrome();
// 設置ACCEPT_SSL_CERTS 變量值為true
cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
// 新建一個帶capability的chromedriver對象
WebDriver driver=new ChromeDriver(cap);
相關博客文章:http://blog.csdn.net/u011541946/article/details/74013466
7.什麽是Firefox Profile?
Profile是一組文件,主要用來記錄用戶在火狐瀏覽器上的私人信息,例如書簽,密碼,用戶首選項,下載文件夾保存路徑等。簡單來說,你打開火狐瀏覽器輸入about://config,這個頁面有些設置選項是可以通過profile來實現修改的。
在我博客中BrowserEngine.java中,就有profile的簡單使用,主要是用來設置下載文件的保存路徑。http://blog.csdn.net/u011541946/article/details/76598441
8.如何實現鼠標懸停,鍵盤事件和拖拽動作?
在Webdriver中,處理鍵盤事件和鼠標事件,一般使用Actions類提供的方法,包括鼠標懸停,拖拽和組合鍵輸入。
這裏介紹幾個方法
方法:clickAndHold()
使用場景:找到一個元素,點擊鼠標左鍵,不放手。自己可以點擊鼠標不松開試試這個場景。
方法:contentClick()
使用場景:模擬鼠標右鍵點擊,一般右鍵會帶出菜單來。
方法:doubelClick()
使用場景:模擬鼠標雙擊
方法:dragAndDrop(source,target)
使用場景:模擬從source這個位置,拖拽一個元素到target位置
鍵盤事件方法:keyDown(keys.ALT), keyUp(keys.SHIFT)
使用場景:點擊鍵盤事件,分為兩個動作,一個點擊鍵盤,第二個動作是釋放點擊(松開)
相關博客文章:http://blog.csdn.net/u011541946/article/details/74043595
python+selenium面試題