一. 什么是自動化測試
自動化測試指軟件測試的自動化,可以使用軟件工具或腳本來執(zhí)行測試任務的過程,以替代人工進行重復性、繁瑣或耗時的測試活動;是將人為驅動的測試行為轉化為機器執(zhí)行的過程 。
自動化測試包括 UI 自動化,接口自動化,單元測試自動化。
二. selenium的介紹
1. Selenium是什么
Selenium 是 Web 應用中基于 UI 的自動化測試框架,它的優(yōu)點如下:
- 開源免費。
- 支持多瀏覽器,比如 Chrome,Edge,F(xiàn)irefox,Safari 等。
- 支持多語言,包括 Java,Python,C# 等,都可以使用 Selenium 這個工具。
- 支持多操作系統(tǒng),比如 Windows,Linux,Mac 等。
- Selenium 的底層封裝了豐富的 API,可以直接拿來使用。
2. Selenium的工作原理
??用 Selenium 實現(xiàn)自動化,主要需要三個東西:
- 自動化測試代碼:自動化測試代碼發(fā)送請求給瀏覽器的驅動。
- 瀏覽器驅動:它來解析這些自動化測試的代碼,解析后把它們發(fā)送給瀏覽器。
- 瀏覽器:執(zhí)行瀏覽器驅動發(fā)來的指令,并最終完成工程師想要的操作。
??Selenium 腳本執(zhí)行時后端實現(xiàn)的流程:
- 對于編寫的每一條 Selenium 腳本測試代碼,都會創(chuàng)建一個 Http 請求并且發(fā)送給瀏覽器的驅動。
- 瀏覽器驅動中包含了一個 HTTP Server,用來接收這些 Http 請求。
- HTTP Server 接收到請求后,瀏覽器驅動程序會將請求解析成瀏覽器可以識別的命令并發(fā)送給瀏覽器。
- 瀏覽器執(zhí)行接收到的命令,例如導航至指定 URL、查找和操作頁面上的元素等。
- 瀏覽器將執(zhí)行結果返回給 HTTP Server。
- HTTP Server 又將結果返回給 Selenium 的腳本,以便進行進一步的處理和驗證。
3. Selenium 的環(huán)境搭建
我這里演示的是使用 Java + Selenium 來進行自動化測試的教程,使用的 JDK 的是 1.8 版本,JDK 1.8 可以兼容 Selenium 2.x、3.x 和 4.x 版本,瀏覽器使用的是 Chrome。
1??第一步,查看自己 Chrome 瀏覽器的版本。
2??第二步,點擊下面鏈接下載相應版本瀏覽器驅動。
ChromeDriver - WebDriver for Chrome - Downloads (chromium.org)
找版本前三位數(shù)一樣的,最后一位如果找不到一樣的就找一個最接近的。
3??第三步,解壓下載好的驅動壓縮包,將下載好的 chromedriver.exe 放到 java 系統(tǒng)環(huán)境變量下(我這里是C:\Program Files\Java\jdk1.8.0_192\bin
) 。
4??第四步,打開 IDEA,創(chuàng)建一個 Maven 項目:在 pom.xml 文件中添加以下依賴,添加后記得 reload。
<dependencies>
<!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
</dependencies>
5??第五步,驗證環(huán)境是否搭建成功,創(chuàng)建一個類驗證下面的代碼是否可以運行。
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
public class Main {
public static void main(String[] args) {
ChromeOptions options = new ChromeOptions();
// 允許所有請求
options.addArguments("--remote-allow-origins=*");
//創(chuàng)建一個驅動對象來打開瀏覽器
WebDriver webDriver = new ChromeDriver();
// 打開百度首頁
webDriver.get("https://www.baidu.com");
}
}
如果出現(xiàn)以下內容,則說明 Selenium 環(huán)境搭建已經(jīng)成功。
上述代碼的含義如下:
ChromeOptions options = new ChromeOptions();
// 允許所有請求
options.addArguments("--remote-allow-origins=*");
// 創(chuàng)建一個驅動對象來打開瀏覽器
WebDriver webDriver = new ChromeDriver();
前兩行代碼是為了解決跨域問題,第三行代碼是在創(chuàng)建 Chrome 驅動對象,要知道所有的 Selenium 操作都是通過驅動來完成的,所以我們首先需要獲取谷歌驅動對象,這三行代碼是固定寫法。
// 打開百度首頁
webDriver.get("https://www.baidu.com");
get() 方法就是獲取到對應頁面的地址打開頁面,也就是獲取一個 URL,比如這里就是獲取百度首頁的地址并打開頁面。
此時環(huán)境搭建就已經(jīng)完畢了,接下來介紹 Selenium 的常見 API。
三. webdriver API
1. 元素的定位
假如要測試一個百度網(wǎng)頁,輸入一個 “Test” ,是否返回 Test 相關數(shù)據(jù);此時我們需要找到百度的輸入框在哪里,然后輸入相關信息,再去找百度一下這個按鈕在哪里,然后去點擊它,那么代碼的測試也是一樣的,首先要做的就是定位元素,再進行一些操作。
定位一個元素最常用的是CSS
定位和XPath
定位,通過這兩種定位方式幾乎可以找到頁面幾乎所有的元素,但 CSS 選擇器定位元素的方式更高效。
1.1 CSS 定位
在 Web 頁面中可以通過以下方式找到 CSS 定位,以百度頁面為例,首先打開百度首頁,鼠標右鍵,點檢查,打開開發(fā)者工具,然后點擊箭頭,選中輸入框,找到對應代碼,然后鼠標右鍵,找到copy
,點擊Copy selector
即可。
有了定位就可以配合元素定位方法cssSelector()
和尋找元素的方法findElement()
使用,sendKeys()
里面的內容就是輸入框我們想輸入的內容;
driver.findElement(By.cssSelector("#kw")).sendKeys("軟件測試");
??測試案例:實現(xiàn)一個自動化操作,在百度框輸入“軟件測試”,點擊“百度一下”按鈕進行搜索。
此時在上面的基礎上我們還需要定位到“百度一下”這個按鈕,同時使用click()
方法來進行點擊操作,代碼如下:
private static void test() {
// 創(chuàng)建一個選項
ChromeOptions options = new ChromeOptions();
// 設置參數(shù)為允許所有請求
options.addArguments("--remote-allow-origins=*");
// 創(chuàng)建瀏覽器驅動, 傳入選項
WebDriver webDriver = new ChromeDriver(options);
// 打開百度首頁
webDriver.get("https://www.baidu.com");
// 找到百度搜索輸入框
webDriver.findElement(By.cssSelector("#kw")).sendKeys("軟件測試");
//找到“百度一下”按鈕,并點擊
webDriver.findElement(By.cssSelector("#su")).click();
}
public static void main(String[] args) throws InterruptedException {
test();
}
執(zhí)行結果:
??下面列出幾種常見的 CSS 選擇器:
- 標簽選擇器:通過標簽名稱來選擇對應的元素。語法形式為 “標簽名稱”,例如 “div” 表示選擇所有的 div 元素。
- 類選擇器:通過元素的 class 屬性值來選擇對應的元素。語法形式為 “.class值” ,例如 “.myClass” 表示選擇 class 屬性值為 “myClass” 的所有元素。
- id 選擇器:通過元素的 id 屬性值來選擇對應的元素。語法形式為 “#id值”,例如 “#myElement” 表示選擇 id 屬性值為 “myElement” 的元素
- 屬性選擇器:通過元素的屬性和屬性值來選擇對應的元素。語法形式為 “[屬性=‘屬性值’]”,例如 “[href=‘https://example.com’]” 表示選擇 href 屬性值為 “https://example.com” 的所有元素。
- 偽類選擇器:通過元素的特定狀態(tài)或位置來選擇對應的元素。常見的偽類選擇器包括 :hover(鼠標懸停)、:first-child(第一個子元素)、:last-child(最后一個子元素)等。
1.2 XPath 定位
類似的也可以找到 XPath 定位,鼠標右鍵,點檢查,打開開發(fā)者工具,然后點擊箭頭,選中輸入框,找到對應代碼,然后鼠標右鍵,找到copy
,點擊Copy XPath(相對路徑)/Copy full Xpath(絕對路徑)
即可。
同樣配合元素定位方法By.xpath()
和尋找元素的方法findElement()
使用即可。
WebElement element = webDriver.findElement(By.xpath("http://*[@id=\"kw\"]"));
這個就不做冗余的演示了.
??這里主要介紹幾種常用的 XPath 選擇語法:
1??絕對路徑:/html/head/title (不常用)
2??相對路徑:
-
相對路徑+索引(找下標):
//form/span[1]/input
,表示在 form 標簽下/選中第二個 span 標簽/找到 input 標簽。 -
相對路徑+屬性值(找相關屬性):
//input[@class="s_ipt"]
,表示選取 input 元素中 class 屬性值為 s_ipt 的標簽。 -
相對路徑+通配符:
//*[@*="s_ipt"]
,表示找到任意屬性值為的 s_ipt 的任意標簽。 -
相對路徑+文本匹配:
//a[text()="新聞"]
,表示選擇文本內容為"新聞"的所有標簽。
更多詳細的語法可以參考在線教程:w3school 在線教程
1.3 實現(xiàn)一個自動化需求
??自動化需求:實現(xiàn)一個在百度的輸入框中輸入”軟件測試“,是否返回對應的數(shù)據(jù)。
private static void test01() throws InterruptedException {
// 創(chuàng)建一個選項
ChromeOptions options = new ChromeOptions();
// 設置參數(shù)為允許所有請求
options.addArguments("--remote-allow-origins=*");
// 創(chuàng)建瀏覽器驅動, 傳入選項
WebDriver webDriver = new ChromeDriver(options);
// 打開百度首頁
webDriver.get("https://www.baidu.com");
// 找到百度搜索輸入框
WebElement element = webDriver.findElement(By.xpath("http://*[@id=\"kw\"]"));
// 輸入軟件測試
element.sendKeys("軟件測試");
// 找到搜索按鈕, 并進行點擊
webDriver.findElement(By.cssSelector("#su")).click();// 這里也可以使用 submit
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.HOURS);
// 校驗搜索出來的結果是不是和軟件測試相關的內容
List<WebElement> elements = webDriver.findElements(By.cssSelector("a em"));
int flag = 0;
for (WebElement e : elements) {
if (e.getText().contains("軟件測試")) {
flag = 1;
System.out.println("測試通過!");
break;
}
}
if (flag == 0) {
System.out.println("測試不通過!");
}
}
public static void main(String[] args) throws InterruptedException {
test01();
}
測試結果:
2. 操作測試對象
上面主要介紹了元素的定位,但是定位只是第一步,定位之后需要對元素素進行操作,是鼠標點擊還是鍵盤輸入,或者清除元素的內容,或者提交表單等。
webdriver 中比較常用的操作對象的方法有下面幾個:
操作 | 說明 |
---|---|
click | 點擊對象 |
send_keys | 在對象上模擬按鍵輸入 |
clear | 清除對象輸入的文本內容 |
submit | 提交 |
text | 用于獲取元素的文本信息 |
getAttribute | 獲取元素對應屬性的值 |
2.1 clear 清除對象輸入的文本內容
??自動化需求:打開一個百度的首頁,并且在輸入框中輸入“測試開發(fā)”,并且點擊“百度一下”按鈕,最后清除輸入框內容。
private static void test02() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com/");
// 找到百度搜索輸入框并輸入 "測試開發(fā)"
webDriver.findElement(By.cssSelector("#kw")).sendKeys("測試開發(fā)");
// 找到搜索按鈕, 并進行點擊
webDriver.findElement(By.cssSelector("#su")).click();
// 等待3秒
sleep(3000);
// 清空百度搜索輸入框中的數(shù)據(jù)
webDriver.findElement(By.cssSelector("#kw")).clear();
}
public static void main(String[] args) throws InterruptedException {
test02();
}
測試結果:
2.2 submit 提交
這個需要注意的是,如果點擊的元素是放在 form 標簽中的,此時使用 submit 實現(xiàn)的效果和 click 是一樣的;如果點擊的元素是放在非 form 標簽中,此時使用 submit 會報錯。
??測試案例:點擊百度中的“新聞”超鏈接,這個超鏈接沒有放在 form 標簽中,則會報錯。
private static void test03() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com/");
// 注意這里不能使用 submit, submit 的使用要求標簽元素必須在 from 表單內
webDriver.findElement(By.xpath("http://a[text()=\"新聞\"]")).submit();
}
public static void main(String[] args) throws InterruptedException {
test03();
}
報錯了:
2.3 getAttribute 獲取元素對應屬性的值
??自動化需求:找到“百度一下”按鈕,驗證這個按鈕 value 屬性值是不是“百度一下”,這個值不是放在標簽中間,不可以通過 test 來獲取,這個時候需要通過 getAttribute 獲取元素對應屬性的值。
private static void test04() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com/");
// getAttribute獲取標簽內的屬性值, 獲取搜索按鈕中的 value 屬性的值
String button_value = webDriver.findElement(By.cssSelector("#su")).getAttribute("value");
if(button_value.equals("百度一下")) {
System.out.println("測試通過!");
} else {
System.out.println(button_value);
System.out.println("測試不通過!");
}
}
public static void main(String[] args) throws InterruptedException {
test04();
}
測試結果:
3. 添加等待
等待方式可以分為兩大類:
- 強制等待:sleep(),這個平時也很常用,就不做過多的介紹了。
- 智能等待:隱式等待,顯示等待。
??隱式等待和顯示等待的區(qū)別如下:
- 顯示等待和隱式等待都可以設置一個時間范圍,在范圍內不斷尋找元素,超時找不到就會拋出異常。
- 可以把隱式等待當做全局變量,它影響整個頁面,所以程序需要等待整個頁面加載完成,才會執(zhí)行下一步;隱式等待對整個 WebDriver 的周期都起作用,所以只要設置一次即可。
- 相比隱式等待,顯式等待可以將它看成是局部變量,它只對指定元素生效,不再是在整個 WebDriver 生命周期內生效,可以根據(jù)需要定位的元素來設置顯式等待,無需等待頁面完全加載。
- 隱式等待是自動等待的,不需要在代碼中顯式調用,而顯示等待需要在代碼中顯式調用等待方法。
3.1 隱式等待
隱式等待可以通過添加implicitlyWait()
方法就可以方便的實現(xiàn)智能等待,implicitlyWait() 的用法比 sleep() 更智能,后者只能選擇一個固定的時間的等待,前者可以在一個時間范圍內智能的等待。
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
隱式地等待并非一個固定的等待時間,當腳本執(zhí)行所需要的元素都被定位到時,時間沒到也會則繼續(xù)執(zhí)行后續(xù)的代碼;如果還有元素定位不到,則它以輪詢的方式不斷的判斷元素是否被定位到,直到超出設置的時長。
??測試案例:這里假設等待 3 天時間,設置隱式等待最長等待為 3 天,如果 3 天內獲取到頁面上的元素,此時執(zhí)行下邊的代碼;如果等待 3 天時間還是沒有找到這個元素,此會報錯。
private static void test02() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com/");
// 找到百度搜索輸入框并輸入 "測試開發(fā)"
webDriver.findElement(By.cssSelector("#kw")).sendKeys("測試開發(fā)");
// 找到搜索按鈕, 并進行點擊
webDriver.findElement(By.cssSelector("#su")).click();
// 等待3秒后再清空
// sleep(3000);
// 隱式等待, 收集到后面代碼所需要的所有元素就會停止等待
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
// 清空百度搜索輸入框中的數(shù)據(jù)
webDriver.findElement(By.cssSelector("#kw")).clear();
}
public static void main(String[] args) throws InterruptedException {
test02();
}
執(zhí)行結果:
3.2 顯式等待
顯式等待與隱式不同,它是等待的是一定的條件,比如等待某個元素可以被被點擊,等待元素可見。
??這里設置等待條件為,等待頁面標題是否為"百度一下,你就知道"。
private static void test05() {
// 創(chuàng)建驅動
WebDriver webDriver = new ChromeDriver();
// 打開百度首頁
webDriver.get("https://www.baidu.com/");
// 判斷元素是否可以被點擊
WebDriverWait wait = new WebDriverWait(webDriver, 1);
wait.until(ExpectedConditions.titleIs("百度一下,你就知道"));
}
public static void main(String[] args) throws InterruptedException {
test05();
}
執(zhí)行結果:
4. 打印信息
??比如要檢驗百度首頁的 url 和 title 是否符合預期,這里主要會用到了兩個函數(shù) getCurrentUrl() 和 getTitle(),它們的返回值類型是 String,所以可以定義兩個 String 變量來接收。
private static void test06() {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
WebDriver webDriver = new ChromeDriver(options);
webDriver.get("https://www.baidu.com/");
String url = webDriver.getCurrentUrl();
String title = webDriver.getTitle();
if(url.equals("https://www.baidu.com/") && title.equals("百度一下,你就知道")) {
System.out.println("當前頁面url: " + url + ", 當前頁面title: " + title);
System.out.println("測試通過!");
} else {
System.out.println("測試不通過!");
}
}
public static void main(String[] args) throws InterruptedException {
test06();
}
測試結果:
5. 瀏覽器的操作
瀏覽器的操作包括設置瀏覽器的頁面大小,瀏覽器前進,后退,刷新,滾動條滑動等。
操作 | 說明 |
---|---|
webDriver.manage().window().maximize(); | 瀏覽器的最大化 |
webDriver.manage().window().setSize(new Dimension(width, high)); | 設置瀏覽器寬、高 |
webDriver.navigate().forward(); | 瀏覽器的前進 |
webDriver.navigate().back(); | 瀏覽器的后退 |
webDriver.navigate().refresh(); | 瀏覽器的刷新 |
document.documentElement.scrollTop=0 | 將瀏覽器滾動條滑到最頂端 |
document.documentElement.scrollTop=10000 | 將瀏覽器滾動條滑到最底端 |
??測試案例:先打開一個瀏覽器,繼續(xù)打開百度網(wǎng)頁,然后讓瀏覽器最大化,接著再讓瀏覽器變?yōu)楣潭ǖ膶捄透?,讓后搜索“白鹿”并且百度一下,進行瀏覽器回退、瀏覽器刷新、瀏覽器前進,再將滾動條滑動最底端,再到最頂部。
瀏覽器滾動條的控制需要依靠 js 腳本。
private static void test07() throws InterruptedException {
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
ChromeDriver driver = new ChromeDriver(options);
driver.get("https://www.baidu.com/");
// 最大化
driver.manage().window().maximize();
sleep(1000);
// 設置固定寬,高
driver.manage().window().setSize(new Dimension(1000,800));
driver.findElement(By.cssSelector("#kw")).sendKeys("白鹿");
driver.findElement(By.cssSelector("#su")).click();
sleep(2000);
// 瀏覽器回退
driver.navigate().back();
sleep(2000);
// 瀏覽器刷新
driver.navigate().refresh();
sleep(2000);
// 瀏覽器前進
driver.navigate().forward();
sleep(2000);
// 將瀏覽器滾動條滑到最底端 JS腳本強制轉換
((JavascriptExecutor)driver).executeScript("document.documentElement.scrollTop=10000");
sleep(2000);
// 將瀏覽器滾動條滑到最頂端
((JavascriptExecutor)driver).executeScript("document.documentElement.scrollTop=0");
}
public static void main(String[] args) throws InterruptedException {
test07();
}
測試結果:
6. 鍵盤事件
這個操作是讓自動化代碼在運行過程中可以進行點擊鍵盤上的按鍵操作,可以通過 send_keys() 方法和 Keys 類的常量來模擬鍵盤操作。
操作 | 說明 |
---|---|
send_keys(Keys.TAB) | # TAB |
send_keys(Keys.ENTER) | # 回車 |
send_keys(Keys.SPACE) | #空格鍵 |
send_keys(Keys.ESCAPE) | #回退鍵(Esc) |
send_keys(Keys.CONTROL,‘a(chǎn)’) | #全選(Ctrl+A) |
send_keys(Keys.CONTROL,‘c’) | #復制(Ctrl+C) |
send_keys(Keys.CONTROL,‘x’) | #剪貼(Ctrl+X) |
send_keys(Keys.CONTROL,‘v’) | #粘貼(Ctrl+V) |
例如:
private static void test08() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("白鹿");
sleep(3000);
//ctrl+A
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "A");
sleep(3000);
//ctrl+X
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "X");
//ctrl+V
sleep(3000);
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "V");
}
public static void main(String[] args) throws InterruptedException {
test08();
}
執(zhí)行結果:
7. 鼠標事件
要使用鼠標事件需要導入工具包:
import org.openqa.selenium.interactions.Actions;
語法:
#鼠標拖動事件
Actions(webDriver).moveToElement(webElement).contextClick().perform();
Actions(webDriver):生成用戶的行為。
moveToElement(element):移動鼠標到一個元素上。
perform():執(zhí)行所有存儲的行為。
常用鼠標事件如下:
操作 | 說明 |
---|---|
contextClick() | 右擊 |
doubleClick() | 雙擊 |
dragAndDrop() | 拖動 |
dragAndDrop() | 移動 |
??測試案例:打開百度首頁,搜索“520”并且百度一下,把鼠標放在圖片的按鈕上進行右擊。
private static void test09() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("520");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
// 找到圖片按鈕
WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-item_1CwH-.s-tab-pic_p4Uej.s-tab-pic"));
// 鼠標右擊出現(xiàn)框
Actions actions = new Actions(webDriver);
sleep(2000);
//contextClick()右擊鼠標
actions.moveToElement(webElement).contextClick().perform();
}
public static void main(String[] args) throws InterruptedException {
test09();
}
執(zhí)行結果:
7. 定位一組元素
webdriver 可以很方便的使用findElement
方法來定位某個特定的對象,不過有時候我們卻需要定位一組對象,這時候就需要使用findElements
方法。
定位一組對象一般用于以下場景:
- 批量操作對象,比如將頁面上所有的
checkbox
都勾上。 - 先獲取一組對象,再在這組對象中過濾出需要具體定位的一些對象。比如定位出頁面上所有的checkbox,然后選擇最后一個。
有以下頁面:
用瀏覽器打開這個如下頁面我們看到三個復選框和兩個單選框。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Checkbox</title>
</head>
<body>
<h3>checkbox</h3>
<div class="well">
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="c1">checkbox1</label>
<div class="controls">
<input type="checkbox" id="c1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c2">checkbox2</label>
<div class="controls">
<input type="checkbox" id="c2" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="c3">checkbox3</label>
<div class="controls">
<input type="checkbox" id="c3" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r1" />
</div>
</div>
<div class="control-group">
<label class="control-label" for="r">radio</label>
<div class="controls">
<input type="radio" id="r2" />
</div>
</div>
</form>
</div>
</body>
</html>
??下面我們就來定位這三個復選框,然后將這三個checkbox
都勾上。
private static void page01() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("http://localhost:63342/_20230925testcode/src/main/Page/test01.html?_ijt=hk3glm0bcb2222roak6kf4826i&_ij_reload=RELOAD_ON_SAVE");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
for(int i = 0; i < webElements.size(); i++) {
// 如果每個元素type值等于checkbox進行點擊
// getAttribute獲取頁面上的元素屬性值,里面的type是當前元素屬性
if(webElements.get(i).getAttribute("type").equals("checkbox")){
webElements.get(i).click();
} else {
// 否則什么也不操作
;
}
}
}
public static void main(String[] args) throws InterruptedException {
page01();
}
這個代碼使用 List 來存儲所有是 input 標簽的元素,其中每個可以勾選的按鈕都帶有 type 屬性,那么就可以使用方法 getAttribute(“type”) 來定位到一些指定元素,定位到之后進行 click() 點擊操作即可。
執(zhí)行結果:
8. 多層框架/窗口定位
對于一個web應用,經(jīng)常會出現(xiàn)框架(yrame或)窗口(window)的應用,這也就給我們的定位帶來了一定的困難。
- 定位一個frame :
switchTo.frame(name or id or frameElement)
,通過 frame 的 id 或者 name 或者 frame 自帶的其它屬性來定位框架,這里switchTo.frame()
把當前定位的主體切換了frame
里。 -
switchTo.defaultContent
:從 frame 中嵌入的頁面里跳出,跳回到最外面的默認頁面中。 - 定位一個窗口window:
switchTo.window(name_or_id_or_frame_element)
有以下頁面:
frame.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>frame</title>
<!-- <link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet" />-->
<script type="text/javascript">$(document).ready(function(){
});
</script>
</head>
<body>
<div class="row-fluid">
<div class="span10 well">
<h3>frame</h3>
<iframe id="f1" src="inner.html" width="800", height="600"></iframe>
</div>
</div>
</body>
<!--<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>-->
</html>
inner.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>inner</title>
</head>
<body>
<div class="row-fluid">
<div class="span6 well">
<h3>inner</h3>
<iframe id="f2" src="https://www.baidu.com/"
width="700"height="500"></iframe>
<a href="javascript:alert('watir-webdriver better than selenium webdriver;')">click</a>
</div>
</div>
</body>
</html>
??這里我們要定位到頁面中 click 這個彈窗元素。
要注意不可以直接用 webDriver.findElement(By.cssSelector(" ")).click();,此時這個頁面中 frame 里邊的元素是獲取不到的。
正確的做法是先通過 switchTo.frame() 方法將定位到指定框架,再通過一般方式定位框架中的元素。
private static void page02() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("http://localhost:63342/T-20230515/src/main/Page/test02.html");
webDriver.switchTo().frame("f1");
webDriver.findElement(By.cssSelector("body > div > div > a")).click();
}
public static void main(String[] args) throws InterruptedException {
page02();
}
執(zhí)行結果:
9. 下拉框處理
下拉框是我們最常見的一種頁面元素,對于一般的元素,我們只需要一次就定位,但下拉框里的內容需要進行兩次定位,先定位到下拉框select
,再定位到下拉框內里的選項option
。
這里主要會用到一個 Select 方法,使用先要創(chuàng)建一個 Select 對象,然后去調用里面對應的方法,常見的使用下標定位(Index,從0開始)或者通過 Value 來進行定位。
有以下界面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>select</title>
</head>
<body>
<select id="ShippingMethod" onchange="updateShipping(options[selectedIndex]);" name="ShippingMethod">
<option value="12.51">UPS Next Day Air ==> $12.51</option>
<option value="11.61">UPS Next Day Air Saver ==> $11.61</option>
<option value="10.69">UPS 3 Day Select ==> $10.69</option>
<option value="9.03">UPS 2nd Day Air ==> $9.03</option>
<option value="8.34">UPS Ground ==> $8.34</option>
<option value="9.25">USPS Priority Mail Insured ==> $9.25</option>
<option value="7.45">USPS Priority Mail ==> $7.45</option>
<option value="3.20" selected="">USPS First Class ==> $3.20</option>
</select>
</body>
</html>
??我們分別用下標定位第 4 個元素,用 值 Value 值 定位第一個元素。
代碼實現(xiàn):
private static void page03() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("http://localhost:63342/T-20230515/src/main/Page/test03.html");
WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));
Select select = new Select(webElement);
// 通過下標來選擇
// select.selectByIndex(3);
// 通過value值來選擇
select.selectByValue("12.51");
}
public static void main(String[] args) throws InterruptedException {
page03();
}
執(zhí)行結果:
10. alert彈窗的處理
通過 switchTo.alert() 處理原生的 alert 彈窗。
操作 | 說明 |
---|---|
webDriver.switchTo().alert().text() | 返回 alert 中的文字信息 |
webDriver.switchTo().alert().accept() | 點擊確認按鈕 |
webDriver.switchTo().alert().dismiss() | 點擊取消按鈕 |
webDriver.switchTo().alert().sendKeys(“輸入的值”) | 輸入值,如果 alert 沒有對話框就不能用了,不然會報錯 |
有以下頁面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>title</title>
</head>
<body>
<button onclick="Click()">這是一個彈窗</button>
</body>
<script type="text/javascript">
function Click() {
let name = prompt("請輸入姓名:");
let parent = document.querySelector("body");
let child = document.createElement("div");
child.innerHTML = name;
parent.appendChild(child)
}
</script>
</html>
??測試案例:代碼編寫一個 alert 彈窗,在彈窗中輸入"韻秋梧桐",隨后 alert 彈窗確認。
private static void page04() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("http://localhost:63342/T-20230515/src/main/Page/test04.html");
webDriver.findElement(By.cssSelector("button")).click();
sleep(3000);
// alert彈窗取消
webDriver.switchTo().alert().dismiss();
sleep(3000);
// 點擊按鈕
webDriver.findElement(By.cssSelector("button")).click();
// 在alert彈窗中輸入"韻秋梧桐"
webDriver.switchTo().alert().sendKeys("韻秋梧桐");
// alert彈窗確認
sleep(3000);
webDriver.switchTo().alert().accept();
}
public static void main(String[] args) throws InterruptedException {
page04();
}
執(zhí)行結果:
11. 上傳文件操作
手動的上傳操作一般要打開一個本地窗口,從窗口選擇本地文件添加。
而這里只需要要定位上傳按鈕,通過 sendKeys() 添加本地文件路徑就可以了,絕對路徑和相對路徑都可以,關鍵是上傳的文件存在。
有如下頁面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>upload_file上傳文件</title>
</head>
<body>
<input type="file">
</body>
</html>
??測試案例:實現(xiàn)一個上傳文件需求
private static void page05() {
WebDriver webDriver = new ChromeDriver();
webDriver.get("http://localhost:63342/T-20230515/src/main/Page/test05.html");
webDriver.findElement(By.cssSelector("input")).sendKeys("D:\\img\\cat1.jpg");
}
public static void main(String[] args) throws InterruptedException {
page05();
}
測試結果:
12. 關閉瀏覽器
關閉操作分為兩種:
- quit() :關閉整個瀏覽器,并且清空緩存。
- close() :只是關閉原始窗口(源頁面),不會清空緩存。
??測試案例:打開百度首頁,點擊新聞按鈕,通過 quit 和 click 方法關閉瀏覽器。
private static void test10() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
// 找到新聞按鈕并點擊
webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
sleep(2000);
webDriver.quit();
// webDriver.close();
}
public static void main(String[] args) throws InterruptedException {
test10();
}
使用 quit 執(zhí)行結果:
使用 close 執(zhí)行結果:
13. 切換窗口
我們在設計自動化代碼的時候,可能會遇到頁面從當前頁面跳轉到另一個新的頁面,那么這個時候再直接去使用 cssSelector 或者 Xpath 方法去定位元素的話,肯定是定位不到的,因為跳轉到了新的頁面,get 方法打開的是舊的頁面,比如當我們從百度頁面打開新聞頁面的時候,此時我們如果想要在新聞頁面操作百度一下,那么就得切換窗口。
此時我們可以使用getWindowHandles()
獲取全部的窗口句柄(getWindowHandle 是獲取 get 打開的頁面窗口句柄),遍歷存儲全部句柄的Set
獲取到我們需要的最后一個句柄,然后就通過webDriver.switchTo().window()
來切換窗口了。
??測試案例:打開百度首頁,點擊新聞按鈕,在百度新聞框輸入“新聞聯(lián)播”并且點擊百度一下
private static void test11() throws InterruptedException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
// 找到新聞按鈕并點擊
webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
sleep(1000);
// 通過getWindowHandles獲取所有的窗口句柄
// 通過getWindowHandle獲取的get打開的頁面窗口句柄
System.out.println(webDriver.getWindowHandle());
Set<String> handles = webDriver.getWindowHandles();
String target_handle = "";
for(String handle:handles) {
target_handle = handle;
}
webDriver.switchTo().window(target_handle);
sleep(3000);
// 在輸入框中搜索新聞聯(lián)播
webDriver.findElement(By.cssSelector("#ww")).sendKeys("新聞聯(lián)播");
// 點擊"百度一下"
webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
}
執(zhí)行結果:
14. 截圖
這個操作的話就是會在指定的頁面進行截圖,然后保存到對應的路徑,在實際工作中對比與我們的預期結果是否一致。
首先需要在我們的配置文件pom.xml中導入依賴;
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
截圖操作:((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
復制到硬盤:FileUtils.copyFile(File srcFile, File destFile);
??測試案例:打開百度首頁,輸入“軟件測試”,對測試頁面進行截圖
private static void test12() throws InterruptedException, IOException {
WebDriver webDriver = new ChromeDriver();
webDriver.get("https://www.baidu.com/");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("軟件測試");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
// 強轉成截圖對象
File file = ((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
// 將截圖好的圖片存儲到D:\img\jietu01.png路徑下
FileUtils.copyFile(file, new File("D:\\img\\jietu01.png"));
}
public static void main(String[] args) throws InterruptedException, IOException {
test12();
}
測試結果:
截圖已經(jīng)保存到了指定路徑文章來源:http://www.zghlxwxcb.cn/news/detail-855453.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-855453.html
到了這里,關于Selenium之路: UI自動化測試的必備指南的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!