自动化测试
目录
一,相关概念
1,自动化测试是否可以取代人工测试?
2, 自动化测试金字塔
二, 创建自动化程序环境
三,案例展示
四,selenium的常用函数
1,查找元素的方法
2,打印属性:
3, 切换窗口:
4, 窗口设置大小:
5, 截图:
6, NoSuchElementException出现的原因
7, 等待
(1)强制等待:
(2)隐式等待:
(3)显示等待:
8, 弹窗的操作
9, 上传文件
10 ,浏览器参数设置
一,相关概念
1,自动化测试是否可以取代人工测试?
自动化测试占测试的的很小一部分,自动化测试也是由测试人员来实现的,自动化测试可以使手工测试的代码量减少,能够保证产品尽快上线,时间充足,测试也会更加充分一些.如果存在历史功能的优化,自动化脚本可能会出现报错,测试人员需要维护并解决自动化脚本里的问题,自动化脚本出现报错,有时候不一定是代码写的有问题,可能是开发人员编写的新功能影响了历史功能,自动化脚本发现了bug
自动化测试通常用于回归测试, 即新的功能没有问题,测试历史的功能是否存在问题. 自动化测试不会大幅度降低工作量
自动化测试是一个统称,包含以下部分
UI/界面自动化测试:①web界面自动化测试(H5页面)②客户端界面自动化测试
接口自动化测试
2, 自动化测试金字塔
实际在企业中是"冰淇淋蛋筒反模式"
实际在工作中,手工测试才能发现更多的问题,也是投入精力最大的,其次,UI自动化可以发现的问题相较于接口自动化来说要多一些,很多后端的问题,往往会体现在界面上,所以界面自动化不仅可以发现界面问题也可以发现后端问题,
二, 创建自动化程序环境
程序想要打开web浏览器就需要安装驱动,驱动必须要跟浏览器匹配,下载方式有两种,一种是手动下载,但是需要注意的是,如果浏览器进行了更新,下载的旧的驱动就使用不了,还需要下载新的驱动,更很不方便.第二种方式,由驱动管理工具自动下载与浏览器版本匹配的驱动
【Java+idea+驱动+selenium(与驱动发生交互)】
1,浏览器已经更新了,但是驱动程序还没有发布最新版本,那么最近的历史版本的驱动就可以接着使用
2,浏览器还未更新,但是下载的最新版本的驱动,最新版本的驱动可以兼容历史版本的浏览器
驱动管理程序:
<dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version><scope>test</scope></dependency>
selenium:
<dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.0.0</version></dependency>
下载的途径:
三,案例展示
public void test1() throws InterruptedException {//下载驱动WebDriverManager.edgedriver().setup();EdgeOptions options=new EdgeOptions();//允许访问所有连接options.addArguments("--remote-allow-origins=*");//1,驱动打开浏览器-打来浏览器WebDriver driver=new EdgeDriver(options);Thread.sleep(3000);//2.请求百度网址: https://www.baidu.com/driver.get("https://www.baidu.com/");Thread.sleep(3000);//3,找到百度输入框并输入driver.findElement(By.cssSelector("#kw")).sendKeys("profound");Thread.sleep(3000);//4,找到百度按钮并输入,并点击driver.findElement(By.cssSelector("#su")).click();Thread.sleep(3000);//5,关闭浏览器driver.quit();}
四,selenium的常用函数
1,查找元素的方法
findElement/findElements
1),cssSelect:通过标签来进行定位,例如上述代码中,定位"百度一下"
如果找不到id或者class,也可以选择到想要,找到对应的前端代码,右键->copy->selector
2),xpath
"//*"表示获取html页面内所有的节点
"//[指定节点]"表示获取节点
"/"获取一个节点中的直接子节点
通过索引方式获得对应的内容,注意:xpath的标签获取的方式是从1开始的
实现节点属性匹配[@属性=属性值]
动态元素,识别并复制下来,并手动进行修改
登录状态下和未登录的状态下页面展示有可能是不一样的,所以手工测试和自动化测试时必须保证环境是一样的,自动化测试环境默认为是未登录的状态的
例如:将热搜的文本全部打印下来:
如果直接进行复制,则只复制了第一个li里面的的标题,所以此时需要手动进行修改一下,将[1]去除,这时就都定位到了
即:
public void test3(){WebDriverManager.edgedriver().setup();EdgeOptions options=new EdgeOptions();options.addArguments("--remote-allow-origins=*");WebDriver driver=new EdgeDriver(options);driver.get("https://www.baidu.com/");List<WebElement> hotSearch = driver.findElements(By.xpath("//*[@id=\"hotsearch-content-wrapper\"]/li/a/span[2]"));for (WebElement w:hotSearch) {System.out.println(w.getText());}driver.quit();}
2,打印属性:
public void test4(){WebDriverManager.edgedriver().setup();EdgeOptions options=new EdgeOptions();options.addArguments("--remote-allow-origins=*");WebDriver driver=new EdgeDriver(options);driver.get("https://www.baidu.com/");System.out.println(driver.findElement(By.cssSelector("#su")).getAttribute("value"));//百度一下driver.quit();}
页面上的绝大部分元素都是可以执行点击操作的,但是一些隐藏的,不可见的,不存在的是不可进行点击的
3, 切换窗口:
当在当前窗口打开新的页面,那么我们在新的窗口上进行的操作前,要切换当前句柄为最新的的页面
获得当前句柄:driver.getWindowHandle();
获得句柄列表:driver.getWindowHandles()
public void test5() throws IOException {WebDriverManager.edgedriver().setup();EdgeOptions options=new EdgeOptions();options.addArguments("--remote-allow-origins=*");WebDriver driver=new EdgeDriver(options);driver.get("https://www.baidu.com/");driver.findElement(By.xpath("//*[@id=\"s-top-left\"]/a[6]")).click();//点击图片//更换最新句柄String curHandle = driver.getWindowHandle();Set<String> windowHandles = driver.getWindowHandles();for (String handle:windowHandles) {if(!handle.equals(curHandle)){driver.switchTo().window(handle);}}//打印新页面上的"热门搜索:"String focus=driver.findElement(By.xpath("//*[@id=\"app\"]/div/div[1]/div/div[3]/div[3]/span")).getText();System.out.println(focus);driver.quit();}
4, 窗口设置大小:
//窗⼝最⼤化driver.manage().window().maximize();//窗⼝最⼩化driver.manage().window().minimize();//全屏窗⼝driver.manage().window().fullscreen();//⼿动设置窗⼝⼤⼩driver.manage().window().setSize(new Dimension(1024, 768));
5, 截图:
需要进行额外的导包
<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>
public void getScreenshot(WebDriver driver) throws IOException {SimpleDateFormat sim1=new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2=new SimpleDateFormat("HHmmssSS");String dirTime=sim1.format(System.currentTimeMillis());String fileTime=sim2.format(System.currentTimeMillis());/*储存位置及格式:testimage当天日期test_时间戳.png*/String fileName="./src/test/image/"+dirTime+"/test_"+fileTime+".png";File imageFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);FileUtils.copyFile(imageFile,new File(fileName));}
截图时,直接调用这个函数就可以了
6, NoSuchElementException出现的原因
①元素复制错误
②xpath,selector代码和页面对应错误
③自动化打开的页面和手动打开的页面不一致
④动态元素
⑤代码执行速度比网页加载速度要快
7, 等待
public WebDriver openExplore(){WebDriverManager.edgedriver().setup();EdgeOptions options=new EdgeOptions();options.addArguments("--remote-allow-origins=*");WebDriver driver=new EdgeDriver(options);driver.get("https://www.baidu.com/");return driver;}public void closeExplore(WebDriver driver){driver.quit();}public void test(){WebDriver driver = openExplore();driver.findElement(By.cssSelector("#kw")).sendKeys("profound");//在输入框中输入'profound'driver.findElement(By.cssSelector("#su")).click();//点击查询String text = driver.findElement(By.xpath("//*[@id=\"1\"]/div/div[1]/div/div/div[2]/div/div")).getText();System.out.println(text);//打印'意义深远的'closeExplore(driver);}
出现报错!!原因:代码执行速度比网页加载速度要快,所以要进行等待操作,等待网页执行完毕,在继续往下执行代码
(1)强制等待:
sleep();
优点:使用简单,调试有效
缺点:影响运行速率,浪费大量时间
(2)隐式等待:
隐式等待的作用域是作用在所有元素上,也就意味着等待所有元素加载成功,只要driver对象没有释放掉,隐式等待就会一直生效,隐式等待之作用在查找元素上
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));
(3)显示等待:
显⽰等待也是⼀种智能等待,在指定超时时间范围内只要满⾜操作的条件就会继续执⾏后续代,可作用在指定的元素上,如果在规定的时间内没有满足until条件就会报错
WebDriver driver = openExplore();driver.findElement(By.cssSelector("#kw")).sendKeys("profound");//在输入框中输入'profound'driver.findElement(By.cssSelector("#su")).click();//点击查询//显示等待new WebDriverWait(driver,Duration.ofSeconds(3)).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//*[@id=\"1\"]/div/div[1]/div/div/div[2]/div/div")));closeExplore(driver);
常用ExpectedConditions预定义⽅法:
① elementToBeClickable(By locator):⽤于检查元素的期望是可⻅的并已启⽤,以便可以单击它
②textToBe (Bylocator , String str)检查元素
③presenceOfElementLocated(Bylocator):检查⻚⾯的DOM上是否存在元素
④urlToBe(java.lang.String url)‒检查当前⻚⾯的URL是⼀个特定的URL。
优点:显示等待是智能等待,可以自定义等待的条件,操作灵活
缺点:写法复杂
不建议隐式等待和显示等待一起使用,有可能会导致不可预测的等待时间
浏览器的导航
前进,后退,刷新,得到url
public void test() throws InterruptedException {WebDriverManager.edgedriver().setup();EdgeOptions options=new EdgeOptions();options.addArguments("--remote-allow-origins=*");WebDriver driver=new EdgeDriver(options);//打开网址driver.navigate().to("https://www.baidu.com/");//回退,返回到标签页driver.navigate().back();//前进,前进到百度首页driver.navigate().forward();//刷新driver.navigate().refresh();closeExplore(driver);}
8, 弹窗的操作
确认&取消&输入文本&返回文本
如果页面上有弹窗,一定要先处理弹窗,(关闭弹窗)如果跳过弹窗处理其他,则会报异常 : UnhandleAlertException
public void test3() throws InterruptedException {WebDriver driver = openExplore();driver.get("file:///C:/Users/HUAWEI/AppData/Local/Temp/16478f5f-b548-4c30-9ce9-577d6b632482_selenium-html.rar.selenium-html.rar/selenium-html/Prompt.html");driver.findElement(By.xpath("/html/body/input")).click();Thread.sleep(2000);//切换到弹窗Alert alert = driver.switchTo().alert();alert.sendKeys("dolphin");Thread.sleep(2000);//点击确认alert.accept();Thread.sleep(2000);//刷新页面driver.navigate().refresh();//再次点击弹窗driver.findElement(By.xpath("/html/body/input")).click();Thread.sleep(2000);//输出弹窗文本System.out.println(alert.getText());//点击取消alert.dismiss();Thread.sleep(2000);closeExplore(driver);}
场景:点击弹窗之后页面加载了一会才出现弹窗,就有可能由于代码执行过快,已经走到处理弹窗的代码,但是弹窗的还没有出现,就有可能导致代码执行失败.此时就会报出NoAlertPresentException
处理方法:
一,强制等待.二显示等待:alertIsPresent
public void test(){WebDriver driver = openExplore();driver.get("http://127.0.0.1:8080/blog_login.html");//输入用户名driver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys("zhansan");//输入密码driver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys("123");//点击"登录"driver.findElement(By.xpath("//*[@id=\"submit\"]")).click();//显示等待WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));wait.until(ExpectedConditions.alertIsPresent());//处理弹窗Alert alert = driver.switchTo().alert();alert.dismiss();closeExplore(driver);}
9, 上传文件
预期达到的效果
public void test() throws InterruptedException {WebDriver driver = openExplore();driver.get("file:///C:/Users/HUAWEI/AppData/Local/Temp/ac99e136-d1e2-40ec-b683-824af410dd51_selenium-html.rar.selenium-html.rar/selenium-html/upload.html");driver.findElement(By.xpath("/html/body/div/div/input")).sendKeys("D:\\Data\\编程学习\\测试\\软件测试课件.rar");Thread.sleep(3000);closeExplore(driver);}
10 ,浏览器参数设置
浏览器在后台进行相关操作,我们称之为"无头模式"
设置浏览器的加载策略,如果页面资源较多,访问的页面的时候会出现,页面的主要元素都已经加载完了,但是还存在其他没有加载完,导致driver.get一直在等
EdgeOptions options=new EdgeOptions();//允许访问所有连接options.addArguments("--remote-allow-origins=*");//无头模式options.addArguments("-headless");//设置页面加载策略options.setPageLoadStrategy(PageLoadStrategy.NONE);//完全不会阻塞webDriveroptions.setPageLoadStrategy(PageLoadStrategy.EAGER);//DOM访问已经准备就绪,但是其他资源还在加载中..options.setPageLoadStrategy(PageLoadStrategy.NORMAL);//默认值,等待所有资源都下载完成