中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

西寧微網(wǎng)站建設(shè)拉新充場(chǎng)app推廣平臺(tái)

西寧微網(wǎng)站建設(shè),拉新充場(chǎng)app推廣平臺(tái),夏天做哪些網(wǎng)站能致富,網(wǎng)站制作首先文章目錄Selenium環(huán)境部署自動(dòng)化測(cè)試?yán)映R?jiàn)的元素操作窗口等待瀏覽器的操作彈窗選擇器執(zhí)行腳本文件上傳瀏覽器參數(shù)Junit 5導(dǎo)入依賴Junit 4 和 Junit5 注解對(duì)比斷言測(cè)試順序參數(shù)化單參數(shù)多參數(shù)動(dòng)態(tài)參數(shù)測(cè)試套件指定類來(lái)運(yùn)行測(cè)試用例指定包名來(lái)運(yùn)行包下測(cè)試用例Selenium 為什么…

文章目錄

  • Selenium
    • 環(huán)境部署
    • 自動(dòng)化測(cè)試?yán)?/li>
    • 常見(jiàn)的元素操作
    • 窗口
    • 等待
    • 瀏覽器的操作
    • 彈窗
    • 選擇器
    • 執(zhí)行腳本
    • 文件上傳
    • 瀏覽器參數(shù)
  • Junit 5
    • 導(dǎo)入依賴
    • Junit 4 和 Junit5 注解對(duì)比
    • 斷言
    • 測(cè)試順序
    • 參數(shù)化
      • 單參數(shù)
      • 多參數(shù)
      • 動(dòng)態(tài)參數(shù)
    • 測(cè)試套件
      • 指定類來(lái)運(yùn)行測(cè)試用例
      • 指定包名來(lái)運(yùn)行包下測(cè)試用例

Selenium

為什么選擇selenium作為我們的web自動(dòng)化測(cè)試工具?

  1. 開(kāi)源免費(fèi)
  2. 支持多瀏覽器
  3. 支持多系統(tǒng)
  4. 支持多語(yǔ)言【Java,Python,C#,Rubby,JavaScript,Kolin】
  5. selenium包提供了很多可供測(cè)試使用的API

環(huán)境部署

Chrome瀏覽器
在這里插入圖片描述
Chrome驅(qū)動(dòng)【驅(qū)動(dòng)器版本要和瀏覽器版本對(duì)應(yīng)越詳細(xì)越好】
在這里插入圖片描述
然后把驅(qū)動(dòng)包放在安裝jdk的bin目錄下
在這里插入圖片描述

selenium工具包
在這里插入圖片描述

自動(dòng)化測(cè)試?yán)?/h2>

分為接口自動(dòng)化測(cè)試和UI自動(dòng)化測(cè)試

UI自動(dòng)化測(cè)試包含界面測(cè)試

我們都知道用戶的設(shè)備很多,有手機(jī),平板和電腦。這些設(shè)備運(yùn)行的項(xiàng)目在發(fā)布之初都需要經(jīng)過(guò)測(cè)試,這些測(cè)試又分為web自動(dòng)化測(cè)試 和 移動(dòng)端自動(dòng)化測(cè)試。這里以 web自動(dòng)化測(cè)試 為主。
自動(dòng)化測(cè)試的工具有很多,比如 QTP、Selenium,Jmeter、Loadrunner。本期就以 Selenium 為主進(jìn)行介紹最簡(jiǎn)單的自動(dòng)化測(cè)試

測(cè)試點(diǎn)擊百度

import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;private class AutoTest {// 模擬百度搜索關(guān)鍵詞public static void baiduSearchKey() {String url = "https://www.baidu.com";String keyWords = "新聞";ChromeDriver chromeDriver=new ChromeDriver();try {Thread.sleep(5000);// 輸入框輸入文字chromeDriver.findElement(new By.ByXPath("//*[@id=\"kw\"]")).sendKeys(keyWords);Thread.sleep(5000);// 點(diǎn)擊搜索按鈕chromeDriver.findElement(new By.ByXPath("//*[@id=\"su\"]")).click();Thread.sleep(5000);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();}public static void main(String[] args) {baiduSearchKey();}
}

獲取元素方法有很多,但經(jīng)常用的是 ByXPath和ByCssSelector
在這里插入圖片描述
ByXpath
/:相當(dāng)于子級(jí)一層一層的完整xpath路徑
//:相當(dāng)于越級(jí),直接越過(guò)之前的html標(biāo)簽,根據(jù)id來(lái)查詢標(biāo)簽

后文中只有之前的幾個(gè)操作時(shí)獲取部分xpath,以后的獲取都是完整的獲取xpath路徑【看//數(shù)量即可知道是否根據(jù)帶通配符或者id查詢來(lái)區(qū)別】

常見(jiàn)的元素操作

  1. 輸入文本 sendKeys(str)
    對(duì)元素操作的前提是元素能夠被找到,如果查詢的元素不是可編輯的文本標(biāo)簽,那么前端不受影響,后端也不報(bào)錯(cuò)。按照程序的設(shè)定正常退出
  2. 點(diǎn)擊操作 click()&提交操作 submit()
private static void TestBlogLogin() {// 輸入郵箱String url = "http://localhost:8080/index.html";String email = "1969612859@qq.com";String password = "admin";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {Thread.sleep(3000);// 輸入郵箱chromeDriver.findElement(new By.ByXPath("//*[@id=\"login\"]/div[1]/input")).sendKeys(email);Thread.sleep(3000);// 輸入密碼chromeDriver.findElement(new By.ByXPath("//*[@id=\"login\"]/div[2]/input")).sendKeys(password);Thread.sleep(3000);// 點(diǎn)擊登錄【也可以回車登錄】chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div/form[1]/button")).click();//chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div/form[1]/button")).submit();Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

提交操作 submit 僅適用于form表單之類的submit操作,一般用的少
Selenium更推薦使用 click ,功能比 submit 更豐富

  1. 清除操作 clear()
private static void TestBlogLogin() {// 輸入正確的郵箱和密碼String url = "http://localhost:8080/index.html";String email = "1969612859@qq.com";String password = "admin";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {Thread.sleep(3000);chromeDriver.findElement(new By.ByXPath("//*[@id=\"login\"]/div[1]/input")).sendKeys("手滑輸入錯(cuò)了");Thread.sleep(3000);// 清除文本chromeDriver.findElement(new By.ByXPath("//*[@id=\"login\"]/div[1]/input")).clear();Thread.sleep(3000);chromeDriver.findElement(new By.ByXPath("//*[@id=\"login\"]/div[1]/input")).sendKeys(email);Thread.sleep(3000);chromeDriver.findElement(new By.ByXPath("//*[@id=\"login\"]/div[2]/input")).sendKeys(password);Thread.sleep(3000);chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div/form[1]/button")).click();Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}
  1. 獲取文本值 getText()
private static void TestBlogLogin() {// 輸入正確的郵箱和密碼String url = "http://localhost:8080/index.html";String email = "1969612859@qq.com";String password = "admin";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {// 獲取第一道題目的標(biāo)題String text = chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div[2]/div/div/div/div/div/div/table/tbody/tr[1]/td[2]")).getText();System.out.println("getText()獲取到的文本:" + text);Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

在這里插入圖片描述

在這里插入圖片描述

發(fā)現(xiàn)即使 URL 跳轉(zhuǎn)到了別的網(wǎng)頁(yè),由于線程休眠3s的緣故,并不會(huì)很快就去獲取頁(yè)面元素而是給了頁(yè)面一個(gè)加載的時(shí)間,因此可以完全獲取到跳轉(zhuǎn)到其它頁(yè)面的標(biāo)簽

  1. 獲取屬性 getAttribute(attr)
    在這里插入圖片描述
private static void TestBlogLogin() {// 輸入正確的郵箱和密碼String url = "http://localhost:8080/index.html";String email = "1969612859@qq.com";String password = "admin";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {// 獲取屬性String role = chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div[2]/div/div/div/div/div/div/table/tbody/tr[1]/td[5]/div/div")).getAttribute("role");Thread.sleep(3000);String aria_valuenow = chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div[2]/div/div/div/div/div/div/table/tbody/tr[1]/td[5]/div/div")).getAttribute("aria-valuenow");Thread.sleep(3000);String aria_valuemin = chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div[2]/div/div/div/div/div/div/table/tbody/tr[1]/td[5]/div/div")).getAttribute("aria-valuemin");Thread.sleep(3000);String aClass = chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div[2]/div/div/div/div/div/div/table/tbody/tr[1]/td[5]/div/div")).getAttribute("class");Thread.sleep(3000);String style = chromeDriver.findElement(new By.ByXPath("/html/body/div/div/div[2]/div/div/div/div/div/div/table/tbody/tr[1]/td[5]/div/div")).getAttribute("style");Thread.sleep(3000);System.out.printf("role=%s\naria_valuenow=%s\naria_valuemin=%s\naClass=%s\nstyle=%s\n", role, aria_valuenow, aria_valuemin, aClass, style);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

在這里插入圖片描述
6. 獲取標(biāo)題getTitle()和urlgetCurrenturl()

// 模擬百度搜索關(guān)鍵詞
private static void baiduSearchKey() {String url = "https://www.baidu.com";String keyWords = "新聞";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);HashMap<String, List<String>> info = new HashMap<>();try {Thread.sleep(5000);ArrayList<String> before = new ArrayList<String>() {{add(chromeDriver.getTitle());add(chromeDriver.getCurrentUrl());}};// 輸入框輸入文字chromeDriver.findElement(new By.ByXPath("//*[@id=\"kw\"]")).sendKeys(keyWords);Thread.sleep(5000);// 點(diǎn)擊搜索按鈕chromeDriver.findElement(new By.ByXPath("//*[@id=\"su\"]")).click();Thread.sleep(5000);System.out.println("搜索之后");ArrayList<String> after = new ArrayList<String>() {{add(chromeDriver.getTitle());add(chromeDriver.getCurrentUrl());}};info.put("before", before);info.put("after", after);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();System.out.println(info);
}

在這里插入圖片描述

窗口

  1. 窗口大小
    窗口大小的設(shè)置:最大/小化,全屏窗口,手動(dòng)設(shè)置窗口大小
private static void windControl() {String url = "https://www.baidu.com";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {Thread.sleep(1500);// 窗口最大化chromeDriver.manage().window().maximize();Thread.sleep(1500);// 窗口最小化chromeDriver.manage().window().minimize();Thread.sleep(1500);// 全屏chromeDriver.manage().window().fullscreen();Thread.sleep(1500);// 手動(dòng)設(shè)置窗口大小chromeDriver.manage().window().setSize(new Dimension(1024, 768));Thread.sleep(1500);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}
  1. 切換窗口
    一般的窗口切換可能會(huì)導(dǎo)致找不到元素的BUG
private static void windControl() {String url = "https://www.baidu.com";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {Thread.sleep(1500);// 點(diǎn)擊準(zhǔn)備跳轉(zhuǎn)chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[3]/a[6]")).click();String value = chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[3]/div/div/div/div/div/div[2]/form/span[2]/input")).getAttribute("value");System.out.println(value);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

在這里插入圖片描述
由于無(wú)法獲取跳轉(zhuǎn)頁(yè)面的元素,所以就會(huì)報(bào)錯(cuò)。因此需要一個(gè)頁(yè)面切換功能

private static void windControl() {String url = "https://www.baidu.com";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {Thread.sleep(1500);// 獲取當(dāng)前頁(yè)面句柄String currentHandle = chromeDriver.getWindowHandles().toString();System.out.println("當(dāng)前首頁(yè)句柄:"+currentHandle);Thread.sleep(1500);// 點(diǎn)擊準(zhǔn)備跳轉(zhuǎn)chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[3]/a[6]")).click();// 獲取跳轉(zhuǎn)之后所有標(biāo)簽頁(yè)的句柄Set<String> handles = chromeDriver.getWindowHandles();for (String handle : handles) {if (currentHandle != handle){chromeDriver.switchTo().window(handle);}}String value = chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[3]/div/div/div/div/div/div[2]/form/span[2]/input")).getAttribute("value");System.out.println(value);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

運(yùn)行的退出碼已經(jīng)恢復(fù)正常
在這里插入圖片描述
3. 屏幕截圖
需要導(dǎo)入一個(gè)常用的commons-io庫(kù)

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>
private static void windControl() {String url = "https://www.baidu.com";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);try {Thread.sleep(1500);// 點(diǎn)擊準(zhǔn)備跳轉(zhuǎn)chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[3]/a[6]")).click();File screenshotAs = chromeDriver.getScreenshotAs(OutputType.FILE);// 把屏幕截圖好的文件放在指定的路徑下String fileName = "my.png";try {FileUtils.copyFile(screenshotAs, new File(fileName));} catch (IOException e) {throw new RuntimeException(e);}String value = chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[3]/div/div/div/div/div/div[2]/form/span[2]/input")).getAttribute("value");System.out.println(value);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

這里會(huì)發(fā)生報(bào)錯(cuò),由于屏幕截圖原因。所以會(huì)保存當(dāng)時(shí)的獲取狀態(tài)。
在這里插入圖片描述
會(huì)把當(dāng)前的現(xiàn)場(chǎng)截圖保存下來(lái)【由于沒(méi)有切換頁(yè)面,所以也就會(huì)報(bào)錯(cuò),截圖代碼發(fā)生在報(bào)錯(cuò)之前的代碼,所以也就保留了事故現(xiàn)場(chǎng)

等待

程序執(zhí)行的速度比頁(yè)面渲染速度快很多,因此之前的等待都是使用線程的強(qiáng)制等待,這并不合理。等待一共分為四種。
強(qiáng)制等待、隱式等待、顯示等待、流暢等待

  1. 強(qiáng)制等待
    程序阻塞運(yùn)行,Thread.sleep()。會(huì)用到,但是自動(dòng)化里不能用的特別多,否則拖慢速度
  2. 隱式等待
    隱式等待會(huì)一直輪詢判斷元素是否存在,如果不存在就等待設(shè)置好的時(shí)間里不斷地進(jìn)行輪詢知道元素能夠被找到
private static void waitController(){String url = "https://www.baidu.com";ChromeDriver chromeDriver=new ChromeDriver();// 添加隱式等待:會(huì)作用于chromeDriver整個(gè)生命周期chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));chromeDriver.get(url);chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input")).sendKeys("迪麗熱巴");chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[5]/div/div/form/span[2]/input")).click();chromeDriver.findElement(new By.ByXPath("/html/body/div[2]/div[3]/div[1]/div[3]/div[1]/div[1]/div/div/div/div/div[2]/div/a/div/p/span/span"));chromeDriver.quit();
}
  1. 顯示等待
    隱式等待針對(duì)的是 driver的整個(gè)生命周期,所以對(duì)全部元素有效,但有時(shí)候并非全部都需要等待,我們可以只針對(duì)其中一個(gè)元素進(jìn)行等待操作,其余元素交給程序快速運(yùn)行進(jìn)而提高自動(dòng)化測(cè)試的效率
private static void webDriverWait() {String url = "https://www.baidu.com";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.get(url);chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input")).sendKeys("迪麗熱巴");chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[5]/div/div/form/span[2]/input")).click();// 只針對(duì)某個(gè)元素顯示等待new WebDriverWait(chromeDriver, Duration.ofSeconds(3)).until(lambda -> chromeDriver.findElement(new By.ByXPath("/html/body/div[2]/div[3]/div[1]/div[3]/div[1]/div[1]/div/div/div/div/div[2]/div/a/div/p/span/span")));chromeDriver.get(url);
}

這里使用了 lambda表達(dá)式 的語(yǔ)法,我們查看一下 until的源碼
在這里插入圖片描述
參數(shù)是一個(gè)泛型,所以可以傳入任何泛型函數(shù)。然后就是執(zhí)行的循環(huán),獲取頁(yè)面元素操作。

  • 隱式等待 和 顯式等待 并不能同時(shí)使用,可能會(huì)出現(xiàn)意想不到的結(jié)果
  • 隱式等待 和 顯示等待 均不出現(xiàn)效果的時(shí)候可以使用 強(qiáng)制等待

瀏覽器的操作

瀏覽器的回退,前進(jìn)和刷新操作

private static void navigateControl() {String url = "https://www.baidu.com";ChromeDriver chromeDriver = new ChromeDriver();// 簡(jiǎn)寫
//        chromeDriver.get(url);// 非簡(jiǎn)寫chromeDriver.navigate().to(url);chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));// 想要回退到訪問(wèn)百度網(wǎng)址之前的狀態(tài)chromeDriver.navigate().back();// 前進(jìn),有進(jìn)入到了百度首頁(yè)chromeDriver.navigate().forward();// 刷新百度首頁(yè)chromeDriver.navigate().refresh();chromeDriver.quit();
}

彈窗

彈窗一共有3大類型,如下所示分別為:alert、confirm和prompt
在這里插入圖片描述
但是卻發(fā)現(xiàn),瀏覽器進(jìn)入檢查時(shí)候無(wú)法獲取到彈窗的元素
處理彈窗的步驟

  1. 將driver對(duì)象作用到彈窗上(切換到彈窗)
  2. 選擇確認(rèn)/取消(提示彈窗輸入文本)
    作用到彈窗上:driver.switchTo.alert()
    確認(rèn):driver.accept()
    取消:`driver.dismiss()
    輸入:driver.sendKeys()

前端代碼

<div id="alertVue"><button v-on:click="f()">{{value}}</button>
</div>
<div id="confirmVue"><button v-on:click="f()">{{value}}</button>
</div>
<div id="promptVue"><button v-on:click="f()">{{value}}</button>
</div><script type="text/javascript" src="vue.js"></script>
<script>const alertVue = new Vue({el: '#alertVue',data: {value: "Alert彈窗",},methods: {f() {window.alert("alert彈窗");}}});const confirmVue = new Vue({el: '#confirmVue',data: {value: "Confirm確認(rèn)框",},methods: {f() {if (window.confirm("是否確認(rèn)?")) {confirmVue.value = "true";} else {confirmVue.value = "false";}}}});const promptVue = new Vue({el: '#promptVue',data: {value: "輸入框",},methods: {f() {promptVue.value = window.prompt("輸入框");}}});
</script>

測(cè)試代碼

private static void alertController(){String url = "file:///D:/Documents/Program/Java/SeleniumTest/Autotest/src/test/java/alertHTML.html";ChromeDriver chromeDriver=new ChromeDriver();chromeDriver.navigate().to(url);try {Thread.sleep(1500);// 點(diǎn)擊 alertchromeDriver.findElement(new By.ByXPath("/html/body/div[1]/button")).click();Thread.sleep(1500);// 切換到彈窗Alert alert = chromeDriver.switchTo().alert();// 確認(rèn)操作:accept/取消操作:dismissalert.dismiss();Thread.sleep(1500);// 點(diǎn)擊 confirmchromeDriver.findElement(new By.ByXPath("/html/body/div[2]/button")).click();Thread.sleep(1500);// 切換到彈窗alert = chromeDriver.switchTo().alert();// 確認(rèn)操作alert.accept();Thread.sleep(1500);// 點(diǎn)擊 promptchromeDriver.findElement(new By.ByXPath("/html/body/div[3]/button")).click();Thread.sleep(1500);// 切換到彈窗alert = chromeDriver.switchTo().alert();Thread.sleep(1500);// 在頁(yè)面上看不到輸入的文本效果,但是其實(shí)已經(jīng)輸入了alert.sendKeys("阿斯頓馬丁");// 接受文本alert.accept();Thread.sleep(1500);// 確認(rèn)操作} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}
  • prompt 彈窗進(jìn)行 sendKeys(str) 的時(shí)候不會(huì)在頁(yè)面出現(xiàn)效果,但是程序已經(jīng)輸入有文本信息
  • alert 警告彈窗雖然只有確認(rèn)選項(xiàng),但是也可以用 dismiss和accept 都可以進(jìn)行取消操作
  • url 一定要復(fù)制瀏覽器中選擇而不是從資源路徑中選擇【瀏覽器的url前邊會(huì)多一個(gè)file:///

選擇器

選擇框的處理困難在于無(wú)法將下拉框的元素進(jìn)行定位,每當(dāng)點(diǎn)擊檢查的時(shí)候,下拉框就會(huì)消失
這個(gè)時(shí)候我們可以根據(jù)三個(gè)條件進(jìn)行選擇

  1. 文本
  2. 屬性
  3. 下標(biāo)

html代碼

<div id="selectVue"><select><option v-for="(month, index) in monthes" v-bind:value="index+1">{{month}}</option></select>
</div><script>
const selectVue = new Vue({el: '#selectVue',data: {monthes: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December",],},
});
</script>

Java代碼

private static void alertController() {String url = "file:///D:/Documents/Program/Java/SeleniumTest/Autotest/src/test/java/alertHTML.html";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.navigate().to(url);try {// option選擇器WebElement element = chromeDriver.findElement(new By.ByXPath("/html/body/div[4]/select"));Thread.sleep(1500);// 先創(chuàng)建選擇框?qū)ο?/span>Select select = new Select(element);Thread.sleep(1500);// 根據(jù)文本來(lái)選擇【并不會(huì)像正常操作一樣點(diǎn)擊一下選擇框而是直接選中下拉框】select.selectByVisibleText("September");Thread.sleep(1500);// 根據(jù)屬性值選擇select.selectByValue("1");Thread.sleep(1500);// 根據(jù)下標(biāo)選擇【0開(kāi)始】,選取九月select.selectByIndex(8);Thread.sleep(1500);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

XPath的選擇器是從1開(kāi)始;而下標(biāo)選擇從0開(kāi)始

執(zhí)行腳本

執(zhí)行 js 代碼,有時(shí)候會(huì)遇到輸入文本不完全或者不生效的情況下,可以使用執(zhí)行原生js腳本進(jìn)行解決

private static void scriptControl(){String url = "https://image.baidu.com/";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.navigate().to(url);try {// 執(zhí)行 js 代碼讓頁(yè)面置底chromeDriver.executeScript("document.documentElement.scrollTop = 500");Thread.sleep(1500);// 執(zhí)行 js 代碼讓頁(yè)面置頂chromeDriver.executeScript("document.documentElement.scrollTop = 0");Thread.sleep(1500);// 百度輸入框輸入指定文本chromeDriver.navigate().to("https://www.baidu.com/");chromeDriver.executeScript("var ss=document.querySelector('#kw'); ss.value='英雄鋼筆'");Thread.sleep(1500);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

文件上傳

文件上傳的難點(diǎn)在于當(dāng)點(diǎn)擊上傳文件時(shí)的彈窗是系統(tǒng)自己的彈窗,并不是瀏覽器的彈窗。對(duì)于Selenium而言并不能控制系統(tǒng)。
在這里插入圖片描述

private static void fileUploadControl(){String url = "file:///D:/Documents/Program/Java/SeleniumTest/Autotest/src/test/java/alertHTML.html";ChromeDriver chromeDriver = new ChromeDriver();chromeDriver.navigate().to(url);try {Thread.sleep(1500);chromeDriver.findElement(new By.ByXPath("/html/body/div[5]/input")).sendKeys("D:\\Documents\\Program\\Java\\SeleniumTest\\Autotest\\src\\test\\java\\alertHTML.html");Thread.sleep(1500);} catch (InterruptedException e) {throw new RuntimeException(e);}chromeDriver.quit();
}

這里運(yùn)行完畢之后并不是把文件上傳到服務(wù)器而是要把上傳的文件路徑+文件以名稱的方式放到這里

瀏覽器參數(shù)

實(shí)際工作中,測(cè)試人員將自動(dòng)化部署在機(jī)器上自動(dòng)的執(zhí)行,測(cè)試人員不會(huì)每次都一直盯著自動(dòng)化執(zhí)行的過(guò)程,而是直接查看自動(dòng)化執(zhí)行的結(jié)果。
無(wú)頭模式:類似于Linux的&模式運(yùn)行命令掛載在后臺(tái)進(jìn)程,不在前臺(tái)顯示。瀏覽器而言的話就是沒(méi)有畫面的運(yùn)行一些自動(dòng)化測(cè)試腳本,這樣可以節(jié)約一定的機(jī)器內(nèi)存資源。

private static void paramControl() {// 百度搜索 ”測(cè)試開(kāi)發(fā)工程師“// 先創(chuàng)建選項(xiàng)對(duì)象然后設(shè)置瀏覽器參數(shù)String url = "https://www.baidu.com/";ChromeOptions chromeOptions = new ChromeOptions();chromeOptions.addArguments("-headless");// 添加瀏覽器參數(shù)設(shè)置ChromeDriver chromeDriver = new ChromeDriver(chromeOptions);chromeDriver.navigate().to(url);chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[5]/div/div/form/span[1]/input")).sendKeys("測(cè)試開(kāi)發(fā)工程師");chromeDriver.findElement(new By.ByXPath("/html/body/div[1]/div[1]/div[5]/div/div/form/span[2]/input")).click();chromeDriver.quit();
}

Junit 5

自動(dòng)化是Selenium腳本來(lái)實(shí)現(xiàn)的,Junit是java的單元測(cè)試工具.只不過(guò)我們?cè)趯?shí)現(xiàn)自動(dòng)化的時(shí)候需要借用Junit庫(kù)里面提供的一些方法
Junit 5支持最低支持jdk8
目前Java領(lǐng)域內(nèi)最為流行的單元測(cè)試框架 ------ JUnit
Junit 5 = Junit Platform + Junit Jupiter + Junit Vintage
Junit Platform: Junit Platform是在JVM上啟動(dòng)測(cè)試框架的基礎(chǔ),不僅支持Junit自制的測(cè)試引擎,其他測(cè)試引擎也都可以接入
Junit Jupiter: Junit Jupiter提供了JUnit5的新的編程模型,是JUnit5新特性的核心。內(nèi)部 包含了一個(gè)測(cè)試引擎,用于在Junit Platform上運(yùn)行
Junit Vintage: 由于JUnit已經(jīng)發(fā)展多年,為了照顧老的項(xiàng)目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的測(cè)試引擎
在這里插入圖片描述

導(dǎo)入依賴

<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter -->
<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.9.2</version><scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite -->
<dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.9.2</version><scope>test</scope>
</dependency>

Junit 4 和 Junit5 注解對(duì)比

Junit 5Junit 4說(shuō)明
@Test@Test被注解的是一個(gè)測(cè)試方法,和Junit 4相同
@BeforeAll@BeforeClass被注解的(靜態(tài))方法將在當(dāng)前類中的所有@Test方法執(zhí)行一次
@BeforeEach@Before被注解的方法將在當(dāng)前類中的么欸個(gè)@Test方法前執(zhí)行
@AffterAll@AfterClass被注解的(靜態(tài))方法將在當(dāng)前類中的所有@Test方法執(zhí)行一次
@AffterEach@After被注解的方法將在當(dāng)前類中的么欸個(gè)@Test方法后執(zhí)行
@DIsable@Ignore被注解的方法不會(huì)執(zhí)行(將被跳過(guò)),但會(huì)報(bào)告為已執(zhí)行

Junit 4 中@Testorg.junit.Test;
Junit 5 中@Testorg.junit.jupiter.api.Test;

@BeforeAll 注解必須用在 static 修飾的代碼塊上,否則會(huì)報(bào)錯(cuò)

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;public class JunitTest {// 當(dāng)前方法要在所有測(cè)試用例之前執(zhí)行一次@BeforeAllstatic void beforeAll() {System.out.println("@BeforeAll");}// 當(dāng)前方法要在每個(gè)測(cè)試用例執(zhí)行之前執(zhí)行一次@BeforeEachvoid beforeEach() {System.out.println("@BeforeEach");}@Testvoid t1() {System.out.println("@Test1");}@Testvoid t2() {System.out.println("@Test2");}@Testvoid t3() {System.out.println("@Test3");}
}

在這里插入圖片描述
After效果和Before效果相反

import org.junit.jupiter.api.*;public class JunitTest {// 當(dāng)前方法要在所有測(cè)試用例之前執(zhí)行一次@BeforeAllstatic void beforeAll() {System.out.println("@BeforeAll");}// 當(dāng)前方法要在每個(gè)測(cè)試用例執(zhí)行之前執(zhí)行一次@BeforeEachvoid beforeEach() {System.out.println("@BeforeEach");}@Testvoid t1() {System.out.println("@Test1");}@Testvoid t2() {System.out.println("@Test2");}@Testvoid t3() {System.out.println("@Test3");}@AfterEachvoid afterEach() {System.out.println("@AfterEach");}@AfterAllstatic void afterAll() {System.out.println("@AfterAll");}
}

在這里插入圖片描述

斷言

斷言方法說(shuō)明
assertEquals(expected, actual)如果 expected 不等于 actual ,則斷言失敗
assertFalse(booleanExpression)如果 booleanExpression 不是 false ,則斷言失敗
assertNull(actual)如果 actual 不是 null ,則斷言失敗
assertNotNull(actual)如果 actual 是 null ,則斷言失敗
assertTrue(booleanExpression)如果 booleanExpression 不是 true ,則斷言失敗
@Test
void testAttributeValue() {String url = "https://www.baidu.com/";ChromeOptions chromeOptions = new ChromeOptions();chromeOptions.addArguments("-headless");ChromeDriver chromeDriver = new ChromeDriver(chromeOptions);chromeDriver.navigate().to(url);chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");// 假如這里獲取到的屬性值不是 百度一下 而是百度兩下System.out.println("value:" + value);Assertions.assertEquals("百度兩下", value);chromeDriver.quit();
}

斷言失敗
在這里插入圖片描述
斷言成功

@Test
void testAttributeValue() {String url = "https://www.baidu.com/";ChromeOptions chromeOptions = new ChromeOptions();chromeOptions.addArguments("-headless");ChromeDriver chromeDriver = new ChromeDriver(chromeOptions);chromeDriver.navigate().to(url);chromeDriver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));String value = chromeDriver.findElement(By.cssSelector("#su")).getAttribute("value");// 假如這里獲取到的屬性值不是 百度一下 而是百度兩下System.out.println("value:" + value);Assertions.assertNotEquals("百度兩下", value);chromeDriver.quit();
}

在這里插入圖片描述

不會(huì)提示錯(cuò)誤地方

測(cè)試順序

import org.junit.jupiter.api.*;public class JunitTest {// 當(dāng)前方法要在所有測(cè)試用例之前執(zhí)行一次@BeforeAllstatic void beforeAll() {System.out.println("@BeforeAll");}// 當(dāng)前方法要在每個(gè)測(cè)試用例執(zhí)行之前執(zhí)行一次@BeforeEachvoid beforeEach() {System.out.println("@BeforeEach");}@Testvoid ae() {System.out.println("@Test1");}@Testvoid bc() {System.out.println("@Test2");}@Testvoid ab() {System.out.println("@Test3");}@AfterEachvoid afterEach() {System.out.println("@AfterEach");}@AfterAllstatic void afterAll() {System.out.println("@AfterAll");}
}@BeforeAll
@BeforeEach
@Test3
@AfterEach
@BeforeEach
@Test1
@AfterEach
@BeforeEach
@Test2
@AfterEach
@AfterAll

發(fā)現(xiàn)執(zhí)行順序按照方法名排序一樣,這里的順序并不是按照程序中代碼的順序執(zhí)行。有時(shí)候我們需要按照順序執(zhí)行代碼,比如測(cè)試系統(tǒng)的時(shí)候必須要用戶先登陸才可以后續(xù)的一些操作的時(shí)候就需要按照順序執(zhí)行測(cè)試代碼
添加一個(gè) @TestMethodOrder 注解,然后添加參數(shù) MethodOrderer.OrderAnnotation.class,最后再給每個(gè)執(zhí)行的代碼編輯順序即可

import org.junit.jupiter.api.*;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class JunitTest {// 當(dāng)前方法要在所有測(cè)試用例之前執(zhí)行一次@BeforeAllstatic void beforeAll() {System.out.println("@BeforeAll");}// 當(dāng)前方法要在每個(gè)測(cè)試用例執(zhí)行之前執(zhí)行一次@BeforeEachvoid beforeEach() {System.out.println("@BeforeEach");}@Test@Order(1)void ae() {System.out.println("@Test1");}@Test@Order(2)void bc() {System.out.println("@Test2");}@Test@Order(3)void ab() {System.out.println("@Test3");}@AfterEachvoid afterEach() {System.out.println("@AfterEach");}@AfterAllstatic void afterAll() {System.out.println("@AfterAll");}
}
@BeforeAll
@BeforeEach
@Test1
@AfterEach
@BeforeEach
@Test2
@AfterEach
@BeforeEach
@Test3
@AfterEach
@AfterAll

參數(shù)化

  1. 盡可能地通過(guò)一個(gè)用例,多組參數(shù)來(lái)模擬用戶的行為
  2. 使用了參數(shù)化注解之后就不能再使用 @Test 注解

單參數(shù)

@ParameterizedTest// 使用參數(shù)化注解之前需要先聲明該方法為參數(shù)化方法
@ValueSource(strings = {"1969612859@qq.com", "1969612858@qq.com"})// 通過(guò)注解提供數(shù)據(jù)源
void SingleParamsTest(String email){System.out.println(email);
}

在這里插入圖片描述
可以看到 @ValueSource(數(shù)據(jù)類型={參數(shù)1, 參數(shù)2, 參數(shù)3...}) 提供的數(shù)據(jù)源類型有很多
在這里插入圖片描述

多參數(shù)

@ParameterizedTest
@CsvSource({"1969612859@qq.com, admin", "1969612858@qq.com, root"})
void muchParamsTest(String email, String password){System.out.printf("email:%s<==>password:%s\n", email, password);
}email:1969612859@qq.com<==>password:admin
email:1969612858@qq.com<==>password:root

當(dāng)參數(shù)很多的時(shí)候,我們可以把參數(shù)放入文件中然后通過(guò)文件讀取獲取參數(shù)

@ParameterizedTest
@CsvFileSource(files = "D:\\Documents\\Program\\Java\\SeleniumTest\\Autotest\\src\\test\\resources\\userData.csv")
void csvFileParamsTest(String email, String password){System.out.printf("email:%s<==>password:%s\n", email, password);
}

在這里插入圖片描述
發(fā)現(xiàn) @CsvFileSource 的源碼可以放入很多參數(shù)來(lái)設(shè)置文件,這里只放了 files 一個(gè)參數(shù)的值,文件默認(rèn)編碼已經(jīng)是 UTF-8 所以就可以不用管編碼問(wèn)題
在這里插入圖片描述

動(dòng)態(tài)參數(shù)

這里導(dǎo)入一個(gè)隨機(jī)工具類 common-util–使用方法

// 動(dòng)態(tài)參數(shù)
static Stream<Arguments> methodParams(){// 構(gòu)造動(dòng)態(tài)參數(shù)String[] arr = new String[10];for (int i = 0; i < arr.length; i++) {arr[i] = RandomUtil.randomNumbers(10)+"@qq.com";}return Stream.of(Arguments.arguments(arr[0], RandomUtil.randomString(8)),Arguments.arguments(arr[1], RandomUtil.randomString(8)),Arguments.arguments(arr[2], RandomUtil.randomString(8)),Arguments.arguments(arr[3], RandomUtil.randomString(8)),Arguments.arguments(arr[4], RandomUtil.randomString(8)),Arguments.arguments(arr[5], RandomUtil.randomString(8)),Arguments.arguments(arr[6], RandomUtil.randomString(8)),Arguments.arguments(arr[7], RandomUtil.randomString(8)),Arguments.arguments(arr[8], RandomUtil.randomString(8)),Arguments.arguments(arr[9], RandomUtil.randomString(8)));
}
@ParameterizedTest
@MethodSource(value = "methodParams")
void dynamicMethodParams(String email, String password){System.out.printf("email:%s<==>password:%s\n", email, password);
}
email:0150592006@qq.com<==>password:5knqh9nd
email:6506175266@qq.com<==>password:jndm1vx6
email:4815105218@qq.com<==>password:9e6yaky2
email:5072613647@qq.com<==>password:56vjv9ff
email:1471676761@qq.com<==>password:0uq2mx9r
email:0637284991@qq.com<==>password:k5xcauzb
email:8646939279@qq.com<==>password:q9zltwfd
email:7903224405@qq.com<==>password:wrgn7fxr
email:2771169159@qq.com<==>password:f3l255bc
email:8080867273@qq.com<==>password:mnpveuxj

在這里插入圖片描述

這里為了方便,就直接使用 Arguments 來(lái)替代

小技巧
如果數(shù)據(jù)源與測(cè)試方法同名,則無(wú)需執(zhí)行數(shù)據(jù)源是來(lái)自哪里的

// 動(dòng)態(tài)參數(shù)
static Stream<Arguments> dynamicMethodParams(){// 構(gòu)造動(dòng)態(tài)參數(shù)String[] arr = new String[10];for (int i = 0; i < arr.length; i++) {arr[i] = RandomUtil.randomNumbers(10)+"@qq.com";}return Stream.of(Arguments.arguments(arr[0], RandomUtil.randomString(8)),Arguments.arguments(arr[1], RandomUtil.randomString(8)),Arguments.arguments(arr[2], RandomUtil.randomString(8)),Arguments.arguments(arr[3], RandomUtil.randomString(8)),Arguments.arguments(arr[4], RandomUtil.randomString(8)),Arguments.arguments(arr[5], RandomUtil.randomString(8)),Arguments.arguments(arr[6], RandomUtil.randomString(8)),Arguments.arguments(arr[7], RandomUtil.randomString(8)),Arguments.arguments(arr[8], RandomUtil.randomString(8)),Arguments.arguments(arr[9], RandomUtil.randomString(8)));
}
@ParameterizedTest
@MethodSource// 自動(dòng)尋找與方法名同名的數(shù)據(jù)源
void dynamicMethodParams(String email, String password){System.out.printf("email:%s<==>password:%s\n", email, password);
}
email:7264428849@qq.com<==>password:wewp75wh
email:4884099760@qq.com<==>password:q57n49kf
email:2779525807@qq.com<==>password:dkyfns0t
email:7260421546@qq.com<==>password:kfxow9gw
email:9750978471@qq.com<==>password:a5dwh5g4
email:7595861999@qq.com<==>password:g9gszroo
email:5860224630@qq.com<==>password:er521mby
email:7009711558@qq.com<==>password:qhftn0rh
email:9374899761@qq.com<==>password:zsjkkyns
email:6637232897@qq.com<==>password:fu8g79om

測(cè)試套件

指定類來(lái)運(yùn)行測(cè)試用例

package TestSuite;import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;// 測(cè)試套件:通過(guò) @Suite 注解
@Suite
@SelectClasses(value = {aaa.class, bbb.class})
public class runSuite {
}

測(cè)試套件測(cè)試 aaa.java, bbb.java, ccc.java 的測(cè)試結(jié)果,類下想要運(yùn)行的用例必須要被 @Test 注解修飾
在這里插入圖片描述
@Suite 注解標(biāo)識(shí)該類是測(cè)試套件類而不是測(cè)試類
@SelectClasses 部分源碼告知我們需要填上 class 類名
在這里插入圖片描述

指定包名來(lái)運(yùn)行包下測(cè)試用例

package TestSuite;import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.SelectPackages;
import org.junit.platform.suite.api.Suite;// 測(cè)試套件:通過(guò) @Suite 注解
@Suite
//@SelectClasses(value = {aaa.class, bbb.class})
@SelectPackages("TestSuite")
public class runSuite {
}

發(fā)現(xiàn)連 ccc.java 的測(cè)試也打印輸出了
在這里插入圖片描述

最好是把要測(cè)試的文件以 xxxTest 結(jié)尾比較好,但是因?yàn)槲募A是 TestSuite的緣故,所以現(xiàn)在即使不是 xxxTest 結(jié)尾的包文件也能被掃描到并執(zhí)行 @Test 注解的方法,否則就會(huì)執(zhí)行報(bào)錯(cuò)。

報(bào)錯(cuò)問(wèn)題如下所示
在這里插入圖片描述
解決方案如下所示
在這里插入圖片描述

http://www.risenshineclean.com/news/33499.html

相關(guān)文章:

  • 論述政府門戶網(wǎng)站建設(shè)的基本意義百度優(yōu)化大師
  • phpcms手機(jī)網(wǎng)站長(zhǎng)沙百度推廣運(yùn)營(yíng)公司
  • 做網(wǎng)站為什么要買網(wǎng)站空間百度的seo排名怎么刷
  • 網(wǎng)站設(shè)計(jì)策劃書 模板營(yíng)銷號(hào)
  • 做直播網(wǎng)站軟件有哪些軟件下載海外域名
  • 哪種源碼做視頻網(wǎng)站好用知乎軟文推廣
  • 一臺(tái)電腦主機(jī)做網(wǎng)站國(guó)際新聞最新消息十條
  • 怎么做類似清風(fēng)dj網(wǎng)站自己做一個(gè)網(wǎng)站
  • 互聯(lián)網(wǎng)信息服務(wù)許可證做優(yōu)化關(guān)鍵詞
  • 開(kāi)遠(yuǎn)市住房和城鄉(xiāng)建設(shè)局網(wǎng)站網(wǎng)絡(luò)營(yíng)銷的特點(diǎn)主要包括什么
  • 小程序官方開(kāi)發(fā)文檔沈陽(yáng)企業(yè)網(wǎng)站seo公司
  • wordpress配置cdn緩存規(guī)則博客可以做seo嗎
  • 怎么用python做網(wǎng)站網(wǎng)絡(luò)運(yùn)營(yíng)工作內(nèi)容
  • 廣東兩學(xué)一做考試網(wǎng)站今天的病毒感染情況
  • 有趣的網(wǎng)站設(shè)計(jì)最新百度關(guān)鍵詞排名
  • 深圳住建網(wǎng)站專業(yè)網(wǎng)絡(luò)推廣機(jī)構(gòu)
  • 電腦個(gè)人網(wǎng)站怎么做外貿(mào)建站
  • 做天貓還是做網(wǎng)站推廣怎么開(kāi)通百度推廣賬號(hào)
  • 重慶設(shè)計(jì)公司網(wǎng)站宣傳營(yíng)銷方式有哪些
  • 深圳企業(yè)網(wǎng)站制作公司怎樣做運(yùn)營(yíng)需要具備什么能力
  • html電子商務(wù)網(wǎng)站模板下載網(wǎng)絡(luò)平臺(tái)怎么推廣
  • 鶴壁網(wǎng)站推廣公司seo資訊網(wǎng)
  • 品牌網(wǎng)站建設(shè) 杭州外貿(mào)seo優(yōu)化
  • 上海石化有做網(wǎng)站設(shè)計(jì)的嗎專業(yè)代寫軟文
  • 適合女生做的網(wǎng)站清遠(yuǎn)seo
  • 優(yōu)化教程網(wǎng)站推廣排名搜索引擎優(yōu)化實(shí)訓(xùn)報(bào)告
  • 韓國(guó)購(gòu)物網(wǎng)站網(wǎng)站流量統(tǒng)計(jì)分析報(bào)告
  • 租賃服務(wù)器的網(wǎng)站網(wǎng)上培訓(xùn)課程平臺(tái)
  • 快速網(wǎng)站建設(shè)價(jià)格百度指數(shù)官網(wǎng)查詢
  • 網(wǎng)站建設(shè)哪家好萬(wàn)維科技推廣軟件賺錢違法嗎