自動(dòng)化測(cè)試
自動(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í)行的過程。(簡(jiǎn)單而言其實(shí)就是降低重復(fù)性的工作(大部分是Python))
自動(dòng)化測(cè)試的具體實(shí)現(xiàn),應(yīng)該是包含下面七個(gè)過程的。
- 分析:總體把握系統(tǒng)邏輯,分析出系統(tǒng)的核心體系架構(gòu)。
- 設(shè)計(jì):設(shè)計(jì)測(cè)試用例,測(cè)試用例要足夠明確和清晰,覆蓋面廣而精
- 實(shí)現(xiàn):實(shí)現(xiàn)腳本,有兩個(gè)要求一是斷言,二是合理的運(yùn)用參數(shù)化。
- 執(zhí)行:執(zhí)行腳本遠(yuǎn)遠(yuǎn)沒有我們想象中那么簡(jiǎn)單。腳本執(zhí)行過程中的異常需要我們仔細(xì)的去分析原因。
- 總結(jié):測(cè)試結(jié)果的分析,和測(cè)試過程的總結(jié)是自動(dòng)化測(cè)試的關(guān)鍵。
- 維護(hù):自動(dòng)化測(cè)試腳本的維護(hù)是一個(gè)難以解決但又必須要解決的問題。
- 分析:在自動(dòng)化測(cè)試過程中深刻的分析自動(dòng)化用例的覆蓋風(fēng)險(xiǎn)和腳本維護(hù)的成本。
自動(dòng)化的分類:?jiǎn)卧獪y(cè)試,接口測(cè)試,UI自動(dòng)化測(cè)試
單元測(cè)試:
最大的投入應(yīng)該在單元測(cè)試上,單元測(cè)試運(yùn)行的頻率也更加高。
單元測(cè)試:
接口測(cè)試就是API測(cè)試,相對(duì)于UI自動(dòng)化API自動(dòng)化更加容易實(shí)現(xiàn),執(zhí)行起來也更穩(wěn)定。
接口自動(dòng)化的有以下特點(diǎn):
- 可在產(chǎn)品前期,接口完成后介入
- 用例維護(hù)量小
- 適合接口變動(dòng)較小,界面變動(dòng)頻繁的項(xiàng)目
常見的接口自動(dòng)化測(cè)試工具有,RobotFramework,JMeter,SoapUI,TestNG+HttpClient,Postman等。
UI自動(dòng)化
雖然測(cè)試金字塔告訴我們盡量多做API層的自動(dòng)化測(cè)試,但是UI層的自動(dòng)化測(cè)試更加貼近用戶的需求和軟件系統(tǒng)的實(shí)際業(yè)務(wù)。并且有時(shí)候我們不得不進(jìn)行UI層的測(cè)試。
UI自動(dòng)化的特點(diǎn):
- 用例維護(hù)量大
- 頁(yè)面相關(guān)性強(qiáng),必須后期項(xiàng)目頁(yè)面開發(fā)完成后介入
- UI測(cè)試適合與界面變動(dòng)較小的項(xiàng)目
UI層的測(cè)試框架比較多,比如Windows客戶端測(cè)試的AutoIT,web測(cè)試的selenium以及TestPlanteggPlant,Robot framework,QTP等
selenium工具
定義
selenium是用來做web自動(dòng)化測(cè)試框架。
特點(diǎn):
- 兼容各種瀏覽器,支持各種平臺(tái),支持各種語言
- 小巧,對(duì)于不同的語言它只是一個(gè)包而已,而QTP 需要下載安裝1個(gè)多G 的程序
- 有豐富的API
- 支持分布式測(cè)試用例的執(zhí)行,可以把測(cè)試用例分布到不同的測(cè)試機(jī)器執(zhí)行,相當(dāng)于分 發(fā)機(jī)的功能。
原理:
自動(dòng)化腳本:通過編寫代碼
webDriver:需要我們?nèi)ハ螺d
瀏覽器:edge瀏覽器,Chrome瀏覽器
selenium+java環(huán)境搭建
- 瀏覽器這里用Chrome瀏覽器:官網(wǎng)下載(注意自己瀏覽器的版本:在瀏覽器關(guān)于里查看)
- 下載與之對(duì)應(yīng)的瀏覽器驅(qū)動(dòng):webDirver:官網(wǎng)下載
- 將壓縮包解壓后驅(qū)動(dòng)放入java安裝的jdk中;
- 打開idea創(chuàng)建項(xiàng)目,導(dǎo)入依賴pom
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
- 創(chuàng)建測(cè)試化代碼
public class Main {
public static void main(String[] args) {
ChromeOptions options=new ChromeOptions();
//允許所有的請(qǐng)求
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
//打開一個(gè)網(wǎng)頁(yè)
webDriver.get("https://www.baidu.com");
}
}
- 運(yùn)行代碼
- 此時(shí)環(huán)境就配好了
Selenium+API
webdriver 提供了一系列的對(duì)象定位方法,常用的有以下幾種:
id,name,class name,link textpartial,link text,tag name,xpath,css selector
這里的重點(diǎn)是css,xpath
public class Main {
public static void main(String[] args) {
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
//找到百度搜索框
// WebElement element= webDriver.findElement(By.cssSelector(".s_ipt"));
WebElement element=webDriver.findElement(By.xpath("http://*[@id=\"kw\"]"));
//輸入一個(gè)軟件測(cè)試
element.sendKeys("軟件測(cè)試");
}
}
定位元素findElement:css
css選擇語法:
id選擇器:#id
類選擇:.class
標(biāo)簽選擇器:標(biāo)簽名
后代選擇器:父級(jí)選擇器,子級(jí)選擇器
xPath :
絕對(duì)路徑:從根目錄出發(fā)尋找
相對(duì)路徑:(常用)
1. 相對(duì)路徑+索引://from/span[2]/input
2. 相對(duì)路徑+屬性://input[@class="s_ipt"]
3. 相對(duì)路徑+通配符://*[@*="s_ipt"]
4. 相對(duì)路徑+文本匹配://a[text()="新聞"]
獲取測(cè)試結(jié)果:
public class Main {
public static void main(String[] args) throws InterruptedException {
int flag=0;
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
//找到百度搜索框
// WebElement element= webDriver.findElement(By.cssSelector(".s_ipt"));
WebElement element=webDriver.findElement(By.xpath("http://*[@id=\"kw\"]"));
//輸入一個(gè)軟件測(cè)試
element.sendKeys("軟件測(cè)試");
//點(diǎn)擊一下百度按鈕
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
//校驗(yàn)
//找到搜索結(jié)果
List<WebElement> elements= webDriver.findElements(By.cssSelector("a em"));
for (int i=0;i<elements.size();i++){
if (!elements.get(i).getText().equals("測(cè)試")){
flag=1;
System.out.println("測(cè)試通過");
break;
}
}
if (flag==0){
System.out.println("測(cè)試不通過");
}
}
}
webdriver 中比較常用的操作對(duì)象的方法有下面幾個(gè):
- click: 點(diǎn)擊對(duì)象
- sendKeys: 在對(duì)象上模擬按鍵輸入
- clear: 清除對(duì)象輸入的文本內(nèi)容
- submit: 提交(必須from標(biāo)簽中,不然會(huì)報(bào)錯(cuò))
- text: 用于獲取元素的文本信息
- getAttribute 獲取控件中的屬性值
private static void test02() {
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
String button_value=webDriver.findElement(By.cssSelector("#su")).getAttribute("value");
if (button_value.equals("百度一下")){
System.out.println("測(cè)試通過");
}else {
System.out.println(button_value);
System.out.println("測(cè)試不通過");
}
}
添加等待
sleep休眠:添加休眠非常簡(jiǎn)單,我們需要引入time 包,就可以在腳本中自由的添加休眠時(shí)間了,這里的休眠指固定休眠
隱式等待:通過添加implicitlyWait() 方法就可以方便的實(shí)現(xiàn)智能等待;implicitlyWait(30)的用法比time.sleep()更智能,后者只能選擇一個(gè)固定的時(shí)間的等待,前者可以在一個(gè)時(shí)間范圍內(nèi)智能的等待
private static void test02() {
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
String button_value=webDriver.findElement(By.cssSelector("#su")).getAttribute("value");
//隱式等待
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
if (button_value.equals("百度一下")){
System.out.println("測(cè)試通過");
}else {
System.out.println(button_value);
System.out.println("測(cè)試不通過");
}
}
隱式地等待并非一個(gè)固定的等待時(shí)間,當(dāng)腳本執(zhí)行到某個(gè)元素定位時(shí),如果元素可以定位,則繼續(xù)執(zhí)行;如果元素定位不到,則它以輪詢的方式不斷的判斷元素是否被定位到。直到超出設(shè)置的時(shí)長(zhǎng)。
顯示等待:
private static void test02() {
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
String button_value=webDriver.findElement(By.cssSelector("#su")).getAttribute("value");
// webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
WebDriverWait wait= new WebDriverWait(webDriver,3000);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#help > a:nth-child(1)")));
}
隱式等待和顯示等待區(qū)別:
顯示等待:可以針對(duì)某一個(gè)地方進(jìn)行等待
隱式等待:對(duì)全局進(jìn)行等待
瀏覽器操作
- 瀏覽器前進(jìn),瀏覽器退后
private static void test03() {
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");
webDriver.findElement(By.cssSelector("#su")).click();
//瀏覽器后退
webDriver.navigate().back();
//瀏覽器前進(jìn)
webDriver.navigate().forward();
//瀏覽器刷新
webDriver.navigate().refresh();
}
- 瀏覽器滾動(dòng)條
#將瀏覽器滾動(dòng)條滑到最頂端
document.documentElement.scrollTop=0
#將瀏覽器滾動(dòng)條滑到最底端
document.documentElement.scrollTop=10000
#將瀏覽器滾動(dòng)條滑到最底端, 示例
((JavascriptExecutor)webDriver).executeScript(“document.documentElement.scrollTop=10000”);
其中,executeScript(script, *args),在當(dāng)前窗口/框架同步執(zhí)行javaScript
private static void test03() {
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");
webDriver.findElement(By.cssSelector("#su")).click();
//瀏覽器后退
webDriver.navigate().back();
//瀏覽器前進(jìn)
webDriver.navigate().forward();
//瀏覽器刷新
webDriver.navigate().refresh();
//滑動(dòng)
((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");
}
- 設(shè)置瀏覽器寬、高
webDriver.manage().window().setSize(new Dimension(1000,1000));
- 瀏覽器最大化
webDriver.manage().window().maximize();
- 瀏覽器全屏
webDriver.manage().window().fullscreen();
鍵盤事件
要使用鍵盤按鍵,必須引入keys 包:
通過send_keys()調(diào)用按鍵:
sendkeys(Keys.TAB) # TAB
sendkeys(Keys.ENTER) # 回車
sendkeys(Keys.SPACE) #空格鍵
sendkeys(Keys.ESCAPE) #回退鍵(Esc)
鍵盤組合鍵用法
sendkeys(Keys.CONTROL,‘a(chǎn)’) #全選(Ctrl+A)
sendkeys(Keys.CONTROL,‘c’) #復(fù)制(Ctrl+C)
sendkeys(Keys.CONTROL,‘x’) #剪貼(Ctrl+X)
sendkeys(Keys.CONTROL,‘v’) #粘貼(Ctrl+V)
webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL,"A");
鼠標(biāo)事件
Actions(driver)
生成用戶的行為。所有的行動(dòng)都存儲(chǔ)在actionchains 對(duì)象。通過perform()存儲(chǔ)的行為。
move_to_element(element)
移動(dòng)鼠標(biāo)到一個(gè)元素中,menu 上面已經(jīng)定義了他所指向的哪一個(gè)元素
perform()
執(zhí)行所有存儲(chǔ)的行為:
Actions類
- contextClick() 右擊
- doubleClick() 雙擊
- dragAndDrop() 拖動(dòng)
- moveToElement() 移動(dòng)
private static void test05() throws InterruptedException {
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote--allow-origin=*");
WebDriver webDriver=new ChromeDriver(options);
webDriver.get("https://www.baidu.com");
WebElement webElement=webDriver.findElement(By.cssSelector("#kw"));
Actions actions=new Actions(webDriver);
sleep(3000);
actions.moveToElement(webElement).contextClick().perform();
}
多層框架/窗口定位
獲取框架
對(duì)于一個(gè)web 應(yīng)用,經(jīng)常會(huì)出現(xiàn)框架(frame) 或窗口(window)的應(yīng)用,這也就給我們的定位帶來了一定的困難。
通過frame的id或者name或者frame自帶的其它屬性來定位框架,這里switchTo.frame()把當(dāng)前定位的主體切換了frame里。
窗口定位:
有可能嵌套的不是框架,而是窗口,還有真對(duì)窗口的方法:switchTo.window用法與switchTo.frame 相同。
下拉框處理
下拉框是我們最常見的一種頁(yè)面元素,對(duì)于一般的元素,我們只需要一次就定位,但下拉框里的內(nèi)容需要進(jìn)行兩次定位,先定位到下拉框?qū)ο吕蜻M(jìn)行操作后,再定位到下拉框內(nèi)里的選項(xiàng)。
private static void test06() {
WebDriver webDriver=new ChromeDriver();
webDriver.get("https://www.baidu.com");
WebElement webElement=webDriver.findElement(By.cssSelector("#ShippingMethod"));
Select select=new Select(webElement);
//通過下標(biāo)選擇
select.selectByIndex(3);
select.selectByValue("12.5");
}
彈窗處理
alert、confirm、prompt 的處理
- text 返回alert/confirm/prompt 中的文字信息
- accept 點(diǎn)擊確認(rèn)按鈕
- dismiss 點(diǎn)擊取消按鈕,如果有的話
- send_keys 輸入值,如果alert 沒有對(duì)話框就不能用了,不然會(huì)報(bào)錯(cuò)
private static void test07() throws InterruptedException {
WebDriver webDriver=new ChromeDriver();
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("button")).click();
sleep(3000);
//alert彈窗取消
webDriver.switchTo().alert().dismiss();
//點(diǎn)擊按鈕
webDriver.findElement(By.cssSelector("button")).click();
//在alert彈窗內(nèi)輸入值
webDriver.switchTo().alert().sendKeys("123456");
//alert彈窗確認(rèn)
webDriver.switchTo().alert().accept();
}
上傳文件操作
上傳過程一般要打開一個(gè)本地窗口,從窗口選擇本地文件添加。所以,一般會(huì)卡在如何操作本地窗口添加上傳文件。
在selenium webdriver 沒我們想的那么復(fù)雜;只要定位上傳按鈕,通過sendKeys 添加本地文件路徑就可以了。絕對(duì)路徑和相對(duì)路徑都可以,關(guān)鍵是上傳的文件存在。
private static void test08() {
WebDriver webDriver=new ChromeDriver();
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("input")).sendKeys("本地文件目錄");
}
關(guān)閉瀏覽器
瀏覽器的quit和close之間的區(qū)別:
- quit關(guān)閉了整個(gè)瀏覽器,close關(guān)閉當(dāng)前的頁(yè)面。
- quit清空了瀏覽器的緩存,close不會(huì)清空緩存。
private static void test09() {
WebDriver webDriver=new ChromeDriver();
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#help > a:nth-child(1)"));
//關(guān)閉
webDriver.quit();
webDriver.close();
}
窗口的切換
getWindowHandle 方法獲取當(dāng)前
private static void test11() throws InterruptedException {
WebDriver webDriver=new ChromeDriver();
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#help > a:nth-child(1)")).click();
sleep(3000);
//通過這個(gè)方法getWindowHandle,獲取當(dāng)前的窗口句柄
//通過這個(gè)方法getWindowHandles,獲取所有的窗口句柄
Set<String> handles= webDriver.getWindowHandles();
String target_handle="";
for ( String handle:handles){
target_handle=handle;
}
webDriver.switchTo().window(target_handle);
sleep(3000);
webDriver.findElement(By.cssSelector("#ww")).sendKeys("新聞聯(lián)播");
webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
}
截圖
導(dǎo)入依賴:進(jìn)入Maven倉(cāng)庫(kù)文章來源:http://www.zghlxwxcb.cn/news/detail-717696.html
<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
private static void test12() throws InterruptedException, IOException {
WebDriver webDriver=new ChromeDriver();
webDriver.get("https://www.baidu.com");
webDriver.findElement(By.cssSelector("#kw")).sendKeys("測(cè)試");
webDriver.findElement(By.cssSelector("#su")).click();
sleep(3000);
File file=((TakesScreenshot)(webDriver)).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(file,new File("D://20231022.png"));
}
需要向上轉(zhuǎn)型,TakesScreenshot,然后調(diào)用getScreenshotAs方法文章來源地址http://www.zghlxwxcb.cn/news/detail-717696.html
到了這里,關(guān)于軟件測(cè)試(五)自動(dòng)化 selenium的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!