一、自動(dòng)化測(cè)試介紹
1. 概念
??自動(dòng)化測(cè)試是指軟件測(cè)試的自動(dòng)化,在預(yù)設(shè)狀態(tài)下運(yùn)行應(yīng)用程序或者系統(tǒng),預(yù)設(shè)條件包括正常和異常,最后評(píng)估運(yùn)行結(jié)果,將人為驅(qū)動(dòng)的測(cè)試行為轉(zhuǎn)化為機(jī)器執(zhí)行的過程
??自動(dòng)化測(cè)試包括UI自動(dòng)化、接口自動(dòng)化、單元測(cè)試自動(dòng)化。按照這個(gè)金字塔模型來進(jìn)行自動(dòng)化測(cè)試規(guī)劃,可以產(chǎn)生最佳的自動(dòng)化測(cè)試產(chǎn)出投入比,可以用較少的投入獲得很好的收益
(1)單元測(cè)試
??最大的投入應(yīng)該在單元測(cè)試上,單元測(cè)試運(yùn)行的頻率也更高。Java的單元測(cè)試框架就是Junit
(2)接口測(cè)試
??接口測(cè)試就是API測(cè)試,相對(duì)于UI自動(dòng)化API自動(dòng)化更加容易實(shí)現(xiàn),執(zhí)行起來也更加穩(wěn)定
接口自動(dòng)化有以下幾個(gè)特點(diǎn):
- 可在產(chǎn)品前期,接口完成后介入
- 用例維護(hù)量小
- 適合接口變動(dòng)較小,界面變動(dòng)頻繁的項(xiàng)目
常見的接口自動(dòng)化測(cè)試工具:Postman
(3)UI測(cè)試
UI層的自動(dòng)化測(cè)試更加貼近用戶的需求和軟件系統(tǒng)的實(shí)際業(yè)務(wù),并且有時(shí)候不得不進(jìn)行UI層的測(cè)試
UI自動(dòng)化測(cè)試的特點(diǎn):
- 用例維護(hù)量大
- 頁(yè)面相關(guān)性強(qiáng),必須后期項(xiàng)目頁(yè)面開發(fā)完成后介入
- UI測(cè)試適合于界面變動(dòng)較小的項(xiàng)目
UI層自動(dòng)化測(cè)試框架:selenium
2. 為什么要進(jìn)行自動(dòng)化測(cè)試
??自動(dòng)化測(cè)試能夠代替一部分手工測(cè)試。自動(dòng)化測(cè)試能夠提高測(cè)試效率。比如隨著功能的增加,版本越來越多,回歸測(cè)試的壓力也越來越大,所以僅僅通過人工測(cè)試來回歸所有的版本不現(xiàn)實(shí),所以我們需要借助自動(dòng)化來進(jìn)行回歸
二、驅(qū)動(dòng)
1. 概念
??首先驅(qū)動(dòng)是指驅(qū)動(dòng)計(jì)算機(jī)里軟件的程序,是添加到操作系統(tǒng)中的特殊程序,其中包含有關(guān)硬件設(shè)備的信息。對(duì)于自動(dòng)化測(cè)試來說,代碼可以借助驅(qū)動(dòng)協(xié)助打開瀏覽器,不需要人為的幫助
2. 本質(zhì)
??瀏覽器驅(qū)動(dòng)就是一個(gè)服務(wù)器,我們通過代碼向驅(qū)動(dòng)發(fā)送操作瀏覽器的請(qǐng)求,驅(qū)動(dòng)進(jìn)行解析并執(zhí)行,最后將結(jié)果返回給我們。說它是一個(gè)服務(wù)器最直接的證據(jù)就是它占用了9515端口號(hào)
三、selenium
1. 為什么選擇selenium作為我們的web自動(dòng)化工具
- 開源免費(fèi)
- 支持多瀏覽器
- 支持多系統(tǒng)
- 支持多語(yǔ)言
- selenium包底層有很多可使用的API
2. 環(huán)境部署
- selenium工具包
- Chrome瀏覽器
- Chromedriver谷歌驅(qū)動(dòng)
- jdk8
四、 webdriver API
1. 元素定位
一個(gè)簡(jiǎn)單的自動(dòng)化示例
/**
* 創(chuàng)建驅(qū)動(dòng)對(duì)象并返回
* @param url 驅(qū)動(dòng)里的地址
* @return
*/
private static ChromeDriver getDriver(String url) {
ChromeDriver driver = new ChromeDriver();
driver.get(url);
return driver;
}
/**
* 退出瀏覽器
* @param driver
*/
private static void closeDriver(ChromeDriver driver) {
driver.quit();
}
public static void test() throws InterruptedException {
Thread.sleep(2000);
// 輸入百度網(wǎng)址
ChromeDriver driver = getDriver("https://www.baidu.com");
Thread.sleep(2000);
// 找到百度輸入框并輸入“胡歌”
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
Thread.sleep(2000);
// 找到百度一下按鈕,并點(diǎn)擊
driver.findElement(By.xpath("http://*[@id=\"su\"]")).click();
Thread.sleep(2000);
// 釋放驅(qū)動(dòng)對(duì)象/關(guān)閉瀏覽器
closeDriver(driver);
}
(1)id
??id是頁(yè)面元素的屬性,我們最常用元素定位方式,但是不是所有的元素都有id的。id只能使用一次,如果某一個(gè)元素有id屬性,那么我們就能通過id來唯一的定位這個(gè)元素。例如百度首頁(yè)輸入框的id就是"kw"
(2)name
如果這個(gè)元素有name,并且元素的name命名在整個(gè)頁(yè)面是唯一的,那么我們可以用name來定位這個(gè)元素。例如百度首頁(yè)輸入框的name就是"wd",并且是唯一的
(3)class name 和 tag name
tag name(標(biāo)簽名)
和 class name
也是定位元素的兩種方式,如果那個(gè)標(biāo)簽或者類在頁(yè)面中只使用了一次,那么我們就可以使用這兩種方式來唯一的定位元素,但是并不常用,因?yàn)檫€需要我們對(duì)唯一性進(jìn)行判斷。例如百度首頁(yè)輸入框的class=“s_ipt”,標(biāo)簽名是"input"(但是百度首頁(yè)有多個(gè)input標(biāo)簽)
(4)CSS
??CSS(Cascading Style Sheets)是一種語(yǔ)言,它被用來描述 HTML 和 XML 文檔的表現(xiàn)
??CSS比較靈活,可以選擇控件的任意屬性,比如id屬性,在百度首頁(yè)要選中輸入框也可以這樣寫:driver.findElement(By.cssSelector("#kw"))
??CSS的獲取可以用chrome的F12開發(fā)者模式中Element-右鍵-copy-copy selector來獲取
(5)XPath
??XPath 是一種在XML文檔中定位元素的語(yǔ)言。因?yàn)镠TML 可以看做XML的一種實(shí)現(xiàn),所以selenium用戶可以使用這種語(yǔ)言在web應(yīng)用中定位元素
??Xpath的獲取可以用chrome的F12開發(fā)者模式中Element-右鍵-copy-copy xpath來獲取
??需要注意的是,Xpath在一個(gè)頁(yè)面也會(huì)有重復(fù)的情況,并不是一個(gè)Xpath在一個(gè)頁(yè)面就是唯一存在的
(4)link text
??有時(shí)候不是一個(gè)輸入框也不是一個(gè)按鈕,而是一個(gè)文字鏈接,我們可以通過鏈接內(nèi)容,也就是 link text 來定位。需要注意的是鏈接內(nèi)容必須這個(gè)頁(yè)面唯一,否則會(huì)報(bào)錯(cuò)。比如百度首頁(yè)左上角的"新聞"等文字鏈接,就可以通過link text來定位
(5)partial link text
??通過部分鏈接定位,這個(gè)有時(shí)候也會(huì)用到
2. 操作測(cè)試對(duì)象
??上述的API都是定位元素的方法,但是定位元素只是操作的第一步,之后我們要對(duì)這個(gè)元素進(jìn)行操作
(1)鼠標(biāo)點(diǎn)擊和鍵盤輸入
-
click
,用于點(diǎn)擊,但是不局限于按鈕,一個(gè)頁(yè)面所有位置都能點(diǎn)擊 -
sendKeys
,鍵盤輸入內(nèi)容 -
clear
,清除元素中輸入的文本內(nèi)容
代碼示例:
public static void test5() throws InterruptedException {
Thread.sleep(2000);
ChromeDriver driver = getDriver("https://www.baidu.com");
Thread.sleep(2000);
// 在輸入框中輸入內(nèi)容
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
Thread.sleep(2000);
// 點(diǎn)擊按鈕
driver.findElement(By.xpath("http://*[@id=\"su\"]")).click();
Thread.sleep(2000);
// 清除內(nèi)容
driver.findElement(By.cssSelector("#kw")).clear();
Thread.sleep(2000);
closeDriver(driver);
}
(2)submit提交表單
??一般來說,submit
和click
效果幾乎相同,但是不同的是,submit
只能點(diǎn)擊按鈕用于提交表單,無(wú)法點(diǎn)擊其他地方。因此我們說,提交有的功能點(diǎn)擊都有,所以建議直接用click()
(3)獲取元素文本和屬性
??getText
是用來獲得標(biāo)簽之間的文本內(nèi)容,而由于單標(biāo)簽只有一個(gè)標(biāo)簽,因此也就無(wú)法獲取文本內(nèi)容;getAttribute
用來獲得元素的屬性
代碼示例:
public static void test6() throws InterruptedException {
Thread.sleep(2000);
ChromeDriver driver = getDriver("https://www.baidu.com");
Thread.sleep(2000);
// 獲取輸入框元素屬性
String textAttribute = driver.findElement(By.cssSelector("#kw")).getAttribute("class");
System.out.println(textAttribute);
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
Thread.sleep(2000);
// 獲取胡歌人物介紹:"中國(guó)內(nèi)地影視男演員流行樂歌手"
String text = driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div:nth-child(2)")).getText();
System.out.println(text);
Thread.sleep(2000);
closeDriver(driver);
}
3. 添加等待
等待的意義:我們?cè)谧鰓eb網(wǎng)站自動(dòng)化測(cè)試的過程中,代碼的執(zhí)行速度比較快,而前端頁(yè)面渲染的速度相對(duì)較慢,那么有可能我們進(jìn)行元素定位時(shí)頁(yè)面的元素還沒加載完成,此時(shí)對(duì)元素進(jìn)行定位就會(huì)出現(xiàn)異常,降低自動(dòng)化腳本的穩(wěn)定性和測(cè)試效率
(1)sleep休眠
??sleep休眠就是通過Thread.sleep(毫秒)來進(jìn)行定時(shí)休眠
- 優(yōu)點(diǎn):語(yǔ)法簡(jiǎn)單,適合調(diào)試的時(shí)候用
- 缺點(diǎn):需要等待固定的時(shí)間,造成測(cè)試時(shí)間的大量消耗,大大降低了自動(dòng)化測(cè)試的效率
(2)隱式等待
??隱式等待不同于sleep休眠,隱式等待是在頁(yè)面加載完畢或者等待時(shí)間超過設(shè)置的最長(zhǎng)等待時(shí)間的情況下結(jié)束等待,如果超出等待時(shí)間,就會(huì)拋出異常
- 特點(diǎn):隱式等待是作用于webDriver的整個(gè)生命周期,它并不需要知道用戶要查詢哪個(gè)元素
- 優(yōu)點(diǎn):節(jié)省大量的等待時(shí)間,元素展現(xiàn)后可以直接執(zhí)行下一步,執(zhí)行效率高
- 缺點(diǎn):需要等待頁(yè)面所有元素都展現(xiàn)才會(huì)執(zhí)行下一步,仍然會(huì)有額外的時(shí)間浪費(fèi)
代碼示例:
public static void test7() {
ChromeDriver driver = getDriver("https://www.baidu.com");
// 設(shè)置隱式等待的最長(zhǎng)等待時(shí)間為2s
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
driver.findElement(By.cssSelector("#su")).click();
// 獲取胡歌人物介紹:"中國(guó)內(nèi)地影視男演員流行樂歌手"
String text = driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div:nth-child(2)")).getText();
System.out.println(text);
closeDriver(driver);
}
(3)顯式等待
??顯式等待和隱式等待類似,但是它是針對(duì)某一個(gè)元素進(jìn)行等待,在固定的時(shí)間范圍內(nèi)頻繁的輪詢?cè)厥欠翊嬖?/p>
- 優(yōu)點(diǎn):可以針對(duì)某一個(gè)元素來進(jìn)行等待,不需要等待整個(gè)頁(yè)面渲染完成,極大降低了自動(dòng)化整體的等待時(shí)間
- 缺點(diǎn):寫法更加復(fù)雜
代碼示例:
public static void test8() {
ChromeDriver driver = getDriver("https://www.baidu.com");
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
driver.findElement(By.cssSelector("#su")).click();
// 第一個(gè)參數(shù)是WebDriver對(duì)象
// 第二個(gè)參數(shù)是Duration類方法,用于設(shè)置強(qiáng)制等待的最長(zhǎng)時(shí)間
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
// ExpectedConditions類提供了很多方法可以用來測(cè)試
// presenceOfElementLocated返回當(dāng)前頁(yè)面的web元素,即查看我們指定的元素是否存在
wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div:nth-child(2)")));
// 獲取胡歌人物介紹:"中國(guó)內(nèi)地影視男演員流行樂歌手"
String text = driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div:nth-child(2)")).getText();
System.out.println(text);
// 檢查頁(yè)面元素對(duì)應(yīng)的文本信息是否正確
wait.until(ExpectedConditions.textToBe(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > a > div > p > span > span"), "胡歌"));
closeDriver(driver);
}
補(bǔ)充:ExpectedConditions類提供了很多方法可以用來測(cè)試,例如presenceOfElementLocated,檢查頁(yè)面是否存在對(duì)應(yīng)的元素;textToBe,檢查頁(yè)面元素對(duì)應(yīng)的文本信息是否正確
注意
- 隱式等待和顯式等待都檢測(cè)不到彈窗的加載,因此如果對(duì)彈窗的信息進(jìn)行操作,必須加入強(qiáng)制等待
- 隱式等待和顯式等待不建議一起使用,會(huì)產(chǎn)生意想不到的效果,每次等待的時(shí)間也是不確定的
4. 信息打印
(1)title打印
??將webDriver控制的當(dāng)前標(biāo)簽頁(yè)的頁(yè)面的title打印出來。言外之意,就是如果新打開了一個(gè)標(biāo)簽頁(yè),webDriver仍然打印的是原來標(biāo)簽頁(yè)的title,這里注意瀏覽器標(biāo)簽頁(yè)和頁(yè)面的區(qū)別
(2)url打印
??打印當(dāng)前webDriver驅(qū)動(dòng)對(duì)象控制的標(biāo)簽頁(yè)的url。這里需要注意的和title打印需要注意的一樣
代碼示例:
public static void test9() {
ChromeDriver driver = getDriver("https://www.baidu.com");
System.out.println(driver.getTitle());
System.out.println(driver.getCurrentUrl());
closeDriver(driver);
}
5. 瀏覽器操作
??上述webDriver以一個(gè)標(biāo)簽頁(yè)為單位進(jìn)行操作,實(shí)際是selenium為每一個(gè)標(biāo)簽頁(yè)設(shè)置了唯一標(biāo)識(shí),稱之為句柄,如果我們想操作新打開的標(biāo)簽頁(yè),就必須明確修改webDriver的句柄(注意,句柄是實(shí)時(shí)生成的,每次測(cè)試時(shí)句柄都不一樣)
(1)獲取當(dāng)前webDriver操作的標(biāo)簽頁(yè)的句柄
driver.getWindowHandle() // 返回值是字符串類型
(2)獲取瀏覽器所有標(biāo)簽頁(yè)的句柄
driver.getWindowHandles() // 返回值是Set<String>類型
(3)修改webDriver操作的句柄
??跳轉(zhuǎn)到最新的標(biāo)簽頁(yè),最簡(jiǎn)單粗暴的做法就是維護(hù)兩個(gè)Set,一個(gè)保存舊的所有句柄,一個(gè)保存新的所有句柄,通過遍歷新的Set,在舊的Set里找是否存在,如果不存在,那么該句柄所對(duì)應(yīng)的標(biāo)簽頁(yè)就是新打開的標(biāo)簽頁(yè)。個(gè)人建議,善用driver的close操作,保證測(cè)試的整個(gè)過程中瀏覽器最多只有兩個(gè)標(biāo)簽頁(yè),然后我們就不需要維護(hù)兩個(gè)Set,就可以實(shí)現(xiàn)句柄的快速切換,因?yàn)槲覀冞M(jìn)行測(cè)試的時(shí)候,最多就是點(diǎn)擊原標(biāo)簽頁(yè)的某個(gè)鏈接打開了另一個(gè)標(biāo)簽頁(yè),驗(yàn)證兩個(gè)頁(yè)面之間的關(guān)系,不會(huì)說一下打開兩個(gè)新頁(yè)面的情況,因此完全可以只保存當(dāng)前標(biāo)簽頁(yè)和新標(biāo)簽頁(yè)的句柄
??如果真的打開標(biāo)簽頁(yè)很多又想要跳轉(zhuǎn)到指定的標(biāo)簽頁(yè),建議是在剛打開那個(gè)標(biāo)簽頁(yè)的時(shí)候就對(duì)它的句柄進(jìn)行保存
代碼示例:
public static void test10() throws InterruptedException {
ChromeDriver driver = getDriver("https://www.baidu.com");
// 設(shè)置隱式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
// 點(diǎn)擊百度首頁(yè)的新聞鏈接
driver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
Thread.sleep(3000);
// 獲取當(dāng)前標(biāo)簽頁(yè)的句柄
String handle = driver.getWindowHandle();
System.out.println("當(dāng)前句柄:" + handle);
// 關(guān)閉當(dāng)前driver操作的標(biāo)簽頁(yè)
driver.close();
Thread.sleep(3000);
System.out.println("==================");
// 獲取所有標(biāo)簽頁(yè)的句柄
Set<String> handles = driver.getWindowHandles();
for (String str: handles) {
// 切換 WebDriver 控制的句柄
if(!str.equals(handle)) {
driver.switchTo().window(str);
}
System.out.println(str);
}
System.out.println("當(dāng)前句柄:" + driver.getWindowHandle());
closeDriver(driver);
}
(4)瀏覽器窗口大小的控制
- 窗口最大化
driver.manage.window().maxmize();
- 窗口最小化
driver.manage.window().minmize();
- 設(shè)置窗口尺寸
driver.manage.window().setSize(new Dimension(寬度,高度));(單位是像素)
代碼示例:
public static void test11() throws InterruptedException {
ChromeDriver driver = getDriver("https://www.baidu.com");
Thread.sleep(2000);
// 窗口最大化
driver.manage().window().maximize();
Thread.sleep(2000);
// 窗口最小化
driver.manage().window().minimize();
Thread.sleep(2000);
// 設(shè)置窗口尺寸,參數(shù)是一個(gè)Dimension對(duì)象,這個(gè)對(duì)象的構(gòu)造方法的參數(shù)分別是寬度,高度
driver.manage().window().setSize(new Dimension(1200, 600));
Thread.sleep(2000);
closeDriver(driver);
}
(5)瀏覽器頁(yè)面滑動(dòng)
??WebDriver本身是無(wú)法控制頁(yè)面滑動(dòng)的,但是它可以通過方法執(zhí)行js語(yǔ)句來實(shí)現(xiàn)頁(yè)面滑動(dòng)
- 滑動(dòng)到底部
String js1 = "window.scrollTo(0, document.body.scrollHeight)"; // WebDriver通過關(guān)于執(zhí)行js語(yǔ)言的字符串來實(shí)現(xiàn)窗口滑動(dòng) driver.executeScript(js1);
- 滑動(dòng)到頂部
String js2 = "window.scrollTo(0, 0)"; driver.executeScript(js2);
代碼示例:
public static void test12() throws InterruptedException {
ChromeDriver driver = getDriver("https://www.baidu.com");
// 點(diǎn)擊新聞鏈接并將driver的句柄切換到新聞標(biāo)簽頁(yè)
driver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
String handle = driver.getWindowHandle();
Set<String> handles = driver.getWindowHandles();
for (String str: handles) {
if(!str.equals(handle)) {
driver.switchTo().window(str);
break;
}
}
Thread.sleep(2000);
// 將窗口滑動(dòng)到底部
// 但是如果頁(yè)面不完全是由html寫成,那么可能就無(wú)法滑動(dòng)到最下面
String js1 = "window.scrollTo(0, document.body.scrollHeight)";
// WebDriver通過關(guān)于執(zhí)行js語(yǔ)言的字符串來實(shí)現(xiàn)窗口滑動(dòng)
driver.executeScript(js1);
Thread.sleep(4000);
// 再寫一遍是為了測(cè)試是否能夠通過多次滑動(dòng)將頁(yè)面滑到底部
// 實(shí)驗(yàn)發(fā)現(xiàn)百度新聞頁(yè)并不是一次性加載完成,而是隨著滑動(dòng)而加載
// 因此我們才無(wú)法一次將它滑動(dòng)到底部
driver.executeScript(js1);
Thread.sleep(4000);
driver.executeScript(js1);
Thread.sleep(4000);
driver.executeScript(js1);
Thread.sleep(4000);
// 將窗口滑動(dòng)到頂部
String js2 = "window.scrollTo(0, 0)";
driver.executeScript(js2);
Thread.sleep(2000);
closeDriver(driver);
}
(6)控制一個(gè)標(biāo)簽頁(yè)頁(yè)面的前進(jìn)和后退
??注意,前進(jìn)和后退操作都是針對(duì)當(dāng)前標(biāo)簽頁(yè)的,如果打開了新的標(biāo)簽頁(yè),除非通過修改WebDriver保存的句柄,否則新標(biāo)簽頁(yè)將無(wú)法操作
- 前進(jìn)
driver.navigate().forward()
- 后退
driver.navigate().back()
代碼示例:
public static void test13() throws InterruptedException {
ChromeDriver driver = getDriver("https://www.baidu.com");
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
driver.findElement(By.xpath("http://*[@id=\"su\"]")).click();
Thread.sleep(2000);
// 后退
driver.navigate().back();
Thread.sleep(2000);
// 前進(jìn)
driver.navigate().forward();
Thread.sleep(2000);
closeDriver(driver);
}
(7)彈窗操作(警告彈窗)
??我們?cè)谇岸舜a里能定位到的普通彈窗都可以使用driver.findElement()方法來定位元素,但是有的彈窗我們無(wú)法定位到,就需要借助WebDriver的特殊接口,比如alert的警告彈窗,我們需要通過使用Selenium中提供的alert接口來處理
Alert alert = driver.switchTo().alert();
// 點(diǎn)擊確認(rèn)按鈕
alert.accept();
// 點(diǎn)擊取消按鈕
alert.dismiss();
// 往彈窗的輸入框輸入信息
alert.sendKeys("hello");
代碼示例:
public static void test14() throws InterruptedException {
ChromeDriver driver = getDriver("file:///D:/study/%E6%AF%94%E7%89%B9/gitee%E4%B8%8A%E4%BC%A0%E4%BB%A3%E7%A0%81/javaweb_study/H-20230106/test2.html");
Thread.sleep(2000);
// 點(diǎn)擊按鈕,觸發(fā)警告框
driver.findElement(By.cssSelector("body > form > input[type=button]:nth-child(14)")).click();
Thread.sleep(2000);
// 點(diǎn)擊警告框
Alert alert = driver.switchTo().alert();
// 點(diǎn)擊確認(rèn)按鈕
alert.accept();
// 點(diǎn)擊取消按鈕
alert.dismiss();
// 往彈窗的輸入框輸入信息
alert.sendKeys("hello");
Thread.sleep(2000);
closeDriver(driver);
}
6. 模擬鼠標(biāo)操作
??點(diǎn)擊操作我們雖然可以通過click()實(shí)現(xiàn),但是我們無(wú)法直觀的看到點(diǎn)擊操作,只能通過數(shù)據(jù)改變或者頁(yè)面跳轉(zhuǎn)來看到效果。selenium提供了Actions接口,我們就可以通過設(shè)置,直觀的看到某個(gè)元素被選中
WebElement ele = driver.findElement(元素標(biāo)識(shí));
Actions actions = new Actions(driver);
// clickAndHold()參數(shù)必不可少,該方法表示鼠標(biāo)移動(dòng)到指定元素并保持
// perform表示演示
actions.clickAndHold(ele).perform();
// 該方法表示鼠標(biāo)移動(dòng)到元素并點(diǎn)擊
actions.click(ele).perform();
代碼示例:
public static void test15() throws InterruptedException {
ChromeDriver driver = getDriver("https://www.baidu.com");
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
driver.findElement(By.cssSelector("#su")).click();
WebElement ele = driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > a > div > p > span > span"));
Actions actions = new Actions(driver);
actions.clickAndHold(ele).perform();
Thread.sleep(2000);
actions.click(ele).perform();
Thread.sleep(2000);
closeDriver(driver);
}
7. 選中下拉框的選項(xiàng)
??關(guān)于下拉框,我們是可以通過click進(jìn)行選擇的,但是可能有些麻煩,因此Selenium提供了接口Select,通過Select來選擇下拉框的選項(xiàng)
WebElement ele = driver.findElement(By.cssSelector("body > form > select"));
Select select = new Select(ele);
// 索引從0開始遞增
select.selectByIndex(0);
// 通過元素的value屬性選擇
select.selectByValue("計(jì)算機(jī)網(wǎng)絡(luò)");
// 通過可見到的文本進(jìn)行選擇
select.selectByVisibleText("計(jì)算機(jī)網(wǎng)絡(luò)");
//
代碼示例:
public static void test16() throws InterruptedException {
ChromeDriver driver = getDriver("file:///D:/study/%E6%AF%94%E7%89%B9/gitee%E4%B8%8A%E4%BC%A0%E4%BB%A3%E7%A0%81/javaweb_study/H-20230106/test2.html");
Thread.sleep(2000);
WebElement ele = driver.findElement(By.cssSelector("body > form > select"));
Select select = new Select(ele);
select.selectByIndex(0);
Thread.sleep(2000);
closeDriver(driver);
}
8. 文件上傳
??由于驅(qū)動(dòng)只能控制瀏覽器的操作,但是文件在本地,因此我們就需要想個(gè)其他的方法,通過sendKeys(文件路徑)來實(shí)現(xiàn)上傳本地文件
代碼示例:
public static void test17() throws InterruptedException {
ChromeDriver driver = getDriver("file:///D:/study/%E6%AF%94%E7%89%B9/gitee%E4%B8%8A%E4%BC%A0%E4%BB%A3%E7%A0%81/javaweb_study/H-20230106/test2.html");
// 點(diǎn)擊上傳文件按鈕,并輸入要輸入文件的文件路徑+文件名
driver.findElement(By.cssSelector("body > form > input[type=file]:nth-child(16)")).sendKeys("C:\\Users\\DELL\\Desktop\\面試復(fù)習(xí)計(jì)劃.png");
Thread.sleep(2000);
closeDriver(driver);
}
9. 屏幕截圖
??由于代碼執(zhí)行速度比頁(yè)面渲染的速度要快,因此我們有時(shí)報(bào)錯(cuò)不是因?yàn)榇a問題,而是因?yàn)樗俣葐栴},但是這種問題如果不是提前知道,就很難想到,也很難定位問題,因此我們就可以通過截圖來留證,通過查看對(duì)每個(gè)頁(yè)面進(jìn)行測(cè)試時(shí)的屏幕截圖,就能更容易的定位問題
語(yǔ)法:文章來源:http://www.zghlxwxcb.cn/news/detail-743926.html
// 截圖后產(chǎn)生的文件,創(chuàng)建截圖文件對(duì)象
File srcFile = driver.getScreenshotAs(OutputType.FILE);
// 將截圖文件保存到我們指定路徑下
File fileName = new File("./src/test/java/screenshot/test1.png");
// 將截圖文件保存到指定路徑下
FileUtils.copyFile(srcFile, fileName);
代碼示例:文章來源地址http://www.zghlxwxcb.cn/news/detail-743926.html
public static void test18() throws IOException {
ChromeDriver driver = getDriver("https://www.baidu.com");
// 設(shè)置隱式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
driver.findElement(By.cssSelector("#kw")).sendKeys("胡歌");
driver.findElement(By.cssSelector("#su")).click();
// 截圖后產(chǎn)生的文件,創(chuàng)建截圖文件對(duì)象
File srcFile = driver.getScreenshotAs(OutputType.FILE);
// 將截圖文件保存到我們指定路徑下
File fileName = new File("./src/test/java/screenshot/test1.png");
// 將截圖文件保存到指定路徑下
FileUtils.copyFile(srcFile, fileName);
driver.findElement(By.cssSelector("#\\31 > div > div > div > div > div.cos-row.row-text_Johh7.row_5y9Az > div > div:nth-child(2) > span:nth-child(1)"));
File srcFile2 = driver.getScreenshotAs(OutputType.FILE);
File fileName2 = new File("./src/test/java/screenshot/test2.png");
FileUtils.copyFile(srcFile2, fileName2);
closeDriver(driver);
}
到了這里,關(guān)于selenium-基于UI的自動(dòng)化測(cè)試框架的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!