自动化测试selenium(Java版)_selenium-java
1.准备工作
1.1.下载浏览器
自动化测试首先我们要准备一个浏览器,我们这里使用谷歌(chrome)浏览器.
1.2.安装驱动管理
每一个浏览器都是靠浏览器驱动程序来启动,但是浏览器的版本更新非常快,可能我们今天测试的是一个版本,第二天发布了一个新的版本,那么我们就要重构代码,很不方便.于是selenium帮我们生成了驱动管理依赖,只要引入依赖.就不要我们手动的去处理浏览器版本的问题,只需要我们在pom.xml文件中引入依赖,每次使用都会帮助我们下载新的驱动
io.github.bonigarcia webdrivermanager 5.8.0 test
此外我们还要引入selenium依赖
org.seleniumhq.selenium selenium-java 4.0.0
1.3创建项目
创建一个maven项目
引入相关依赖
到此准备工作就完成了
2. 编写自动化脚本
2.1 创建文件
对于代码的测试我们一般都是在test目录下创建,也可以在main方法中创建,但是一般规范都是让我们在test中创建,FirstTest用来编写我们的自动化脚本,run是执行我们的脚本
2.2 编写代码
2.2.1 使用代码下载对应的浏览器驱动
//自动下载与当前系统和浏览器版本匹配的驱动程序 WebDriverManager.chromedriver().setup();
2.2.2 浏览器访问限制处理
//访问限制处理 ChromeOptions options=new ChromeOptions(); options.addArguments(\"--remote-allow-origins=*\");
2.2.3 生成一个浏览器对象完成初始访问
//生成一个浏览器对象 WebDriver driver=new ChromeDriver(options); driver.get(\"https://www.baidu.com/\"); driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"鞠婧祎\"); driver.findElement(By.cssSelector(\"#su\")).click(); driver.quit();
整体代码:
public void test(){ //自动下载与当前系统和浏览器版本匹配的驱动程序 WebDriverManager.chromedriver().setup(); //访问限制处理 ChromeOptions options=new ChromeOptions(); options.addArguments(\"--remote-allow-origins=*\"); //生成一个浏览器对象 WebDriver driver=new ChromeDriver(options); driver.get(\"https://www.baidu.com/\"); driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"鞠婧祎\"); driver.findElement(By.cssSelector(\"#su\")).click(); driver.quit(); }
当我们完成一次操作之后要关闭driver对象.[driver.quit();]
这样我们就完成了一次简单的简单的测试用例
3.自动化常用方法
我们先把下载驱动,创建一个浏览器对象,解除浏览器限制封装成一个方法,这样就减少了代码的冗余
public void createDriver() throws InterruptedException { //自动下载与当前系统和浏览器版本匹配的驱动程序 WebDriverManager.chromedriver().setup(); //访问限制处理 ChromeOptions options=new ChromeOptions(); options.addArguments(\"--remote-allow-origins=*\"); //生成一个浏览器对象 WebDriver driver=new ChromeDriver(options); driver.get(\"https://www.baidu.com/\"); }
3.1 元素的定位
一般定位一个元素我们一般使用cssSelector和Xpath.
获取web元素按照上述操作定位元素位置之后,右键可以复制 Selector和Xpath
3.1.1 cssSelector
public void test01(){ createDriver(); //找到搜索框之后,输入搜索关键字鞠婧祎 driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"鞠婧祎\"); //点击按钮,也就是\"百度一下\".click(点击操作) driver.findElement(By.cssSelector(\"#su\")).click(); driver.quit(); }
findeElement:用于定位某个元素
By.cssSelector 使用 CSS 选择器语法来定位 HTML 元素.
\"#kw\" 表示通过 id 属性为 kw 的元素进行定位.(百度的搜索框元素id为kw)
sendKeys:用于向指定的页面元素发送按键(输入文本或模拟键盘操作)
click:用于模拟用户点击页面上的某个元素
driver.quit():关闭由 WebDriver 打开的所有浏览器窗口,并终止与浏览器的会话连接。
3.1.2 Xpath
XML路径语⾔,不仅可以在XML⽂件中查找信息,还可以在HTML中选取节点xpath使⽤路径表达式来选择xml⽂档中的节点xpath语法中: 获取HTML⻚⾯所有的节点 //* 获取HTML⻚⾯指定的节点 //[指定节点] //ul :获取HTML⻚⾯所有的ul节点 //input:获取HTML⻚⾯所有的input节点 获取⼀个节点中的直接⼦节点 / //span/input 获取⼀个节点的⽗节点 .. //input/.. 获取input节点的⽗节点 实现节点属性的匹配 [@...] //*[@id=\'kw\'] 匹配HTML⻚⾯中id属性为kw的节点 使⽤指定索引的⽅式获取对应的节点内容 注意:xpath的索引是从1开始的。 百度⾸⻚通过://div/ul/li[3] 定位到第三个百度热搜标签
//使用Xpath定位 public void test02() { createDriver(); driver.findElement(By.xpath(\"//*[@id=\\\"kw\\\"]\")).sendKeys(\"鞠婧祎\"); driver.findElement(By.xpath(\"//*[@id=\\\"su\\\"]\")).click(); driver.quit(); }
3.2 操作测试对象
3.2.1 click
//找到百度⼀下按钮并点击driver.findElement(By.cssSelector(\"#su\")).click();
3.2.2 sendKeys(\"\")
driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"输⼊⽂字\");
3.2.3清除⽂本内容(clear)
将一开始输入的鞠婧祎删除后紧接着搜索章若楠
如果不使用clear(),我们搜索的词条就是\"鞠婧祎章若楠\"
public void test03() throws InterruptedException { createDriver(); driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"鞠婧祎\"); driver.findElement(By.cssSelector(\"#su\")).click(); driver.findElement(By.cssSelector(\"#kw\")).clear(); driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"章若楠\"); Thread.sleep(3000); driver.findElement(By.cssSelector(\"#su\")).click(); Thread.sleep(3000); driver.quit(); }
3.2.4 获取文本信息(getText())
public void test04() { createDriver(); String text = driver.findElement(By.cssSelector(\"#hotsearch-content-wrapper > li:nth-child(1) > a\")).getText(); System.out.println(text); driver.quit(); }
3.2.5 获取当前页面标题(getTitle())或URL(getCurrentUrl)
//获取标题或url public void test05() { createDriver(); String title = driver.getTitle(); String currentUrl = driver.getCurrentUrl(); System.out.println(title); System.out.println(currentUrl); driver.quit(); }
3.2.6窗口
句柄:每个浏览器窗口或标签页都有一个唯一的标识符(字符串形式),称为窗口句柄
3.2.6.1 获取百度首页句柄以及新闻页面句柄
public void test06() { createDriver(); //进入新闻页面 driver.findElement(By.cssSelector(\"#s-top-left > a:nth-child(1)\")).click(); //获取百度首页句柄 String curHandle = driver.getWindowHandle(); System.out.println(curHandle); System.out.println(\"========================\"); //获取所有句柄 Set windowHandles = driver.getWindowHandles(); for (String handle:windowHandles){ System.out.println(handle); } driver.quit(); }
3.2.6.2 切换句柄
当前driver对象指向的是百度首页的句柄,我们要使用新闻页的元素,就要切换窗口,让driver指向新闻页
3.2.6.3 设置窗口大小
//窗⼝最⼤化driver.manage().window().maximize();//窗⼝最⼩化driver.manage().window().minimize();//全屏窗⼝driver.manage().window().fullscreen();//⼿动设置窗⼝⼤⼩driver.manage().window().setSize(new Dimension(1024, 768));
3.3 屏幕截图
有时为了观察我们测试结果,需要保存图片,于是selenium帮我们生成了截图
void getScreenShot(String str) throws IOException { // ./src/test/image/ // /2024-07-17/ // /test01-174530.png // /test02-174530.png // /2024-07-18/ // /test01-174530.png // /test02-174530.png SimpleDateFormat sim1 = new SimpleDateFormat(\"yyyy-MM-dd\"); SimpleDateFormat sim2 = new SimpleDateFormat(\"HHmmssSS\"); String dirTime = sim1.format(System.currentTimeMillis()); String fileTime = sim2.format(System.currentTimeMillis()); //./src/test/image/2024-07-17/test01-174530.png String filename =\"./src/test/image/\"+ dirTime +\"/\" + str + \"-\" + fileTime+\".png\"; System.out.println(\"filename:\"+filename); File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE); FileUtils.copyFile(srcFile,new File(filename)); }
SimpleDateFormat sim1:该行代码创建了一个日期格式化对象 sim1,用于将时间戳格式化为“年-月-日”的字符串形式
3.4 关闭窗口
//表示关闭当前标签页driver.close();//断开连接,关闭driver对象driver.quit();
3.5 等待
3.5.1 强制等待
Thread.sleep();
优点:代码简单
缺点:影响运行效率,浪费大量时间
3.5.2 隐式等待
隐式等待是⼀种智能等待,他可以规定在查找元素时,在指定时间内不断查找元素。如果找到则代码继续执⾏,直到超时没找到元素才会报错。
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
隐式等待作⽤域是整个脚本的所有元素。即只要driver对象没有被释放掉(driver.quit()),隐式等待就⼀直⽣效(全局生效).但是隐式等待也有缺点,他只能查找元素是否存在,而不管元素对不对.而且只能查找元素就像下方代码:
//等待机制的隐式等待 //隐式等待只是查找元素,并不关注元素结果对不对,只要是有结果,就继续执行 public void test13() throws InterruptedException { createDriver(); driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"邓紫棋\"); driver.findElement(By.cssSelector(\"#su\")).click(); Thread.sleep(3000); driver.findElement(By.cssSelector(\"#\\\\31 > div > div > div > div > div > div.header-wrapper_3m6nI > div.cos-row.row-text_1L24W.row_4WY55 > div > div > div.cos-flex.cos-items-center > div.title-wrapper_XLSiK > a > div > p > span > span\")); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3)); //隐式等待,查找后发现有\"#kw\",所以不管.clear是否执行完成,就继续查找下一个元素是否存在 driver.findElement(By.cssSelector(\"#kw\")).clear(); //隐式等待,查找后发现有\"#kw\",所以不管.sendKeys是否执行完成,就继续查找下一个元素是否存在 driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"迪丽热巴\"); //隐式等待,查找后发现有\"#su\",所以不管.click是否执行完成,就继续查找下一个元素是否存在 driver.findElement(By.cssSelector(\"#su\")).click(); Thread.sleep(3000); //如果我们不强制等待上述的三个指令执行完成的话,那么迪丽热巴这个词条可能还没完成输入(sendKeys(\"迪丽热巴\");),点击查询按钮(.click();),隐式等待就已经查询完毕了 //此时迪丽热巴词条还没有进行搜索,就结束,所以还是会返回邓紫棋 //Thread.sleep(3000);就是为了等待 driver.findElement(By.cssSelector(\"#kw\")).sendKeys(\"迪丽热巴\"); // driver.findElement(By.cssSelector(\"#su\")).click();执行完毕,更新#\\31 > div > div > div > div > div > div.header值为迪丽热巴 WebElement ele=driver.findElement(By.cssSelector(\"#\\\\31 > div > div > div > div > div > div.header-wrapper_3m6nI > div.cos-row.row-text_1L24W.row_4WY55 > div > div > div.cos-flex.cos-items-center > div.title-wrapper_XLSiK > a > div > p > span > span\")); System.out.println(ele.getText()); driver.quit();
3.5.3 显式等待
显⽰等待也是⼀种智能等待,在指定超时时间范围内只要满⾜操作的条件就会继续执⾏后续代码显式等待可以
elementToBeClickable:等待直到指定的元素在页面上可见并且可以被点击
WebDriverWait wait=new WebDriverWait(driver,Duration.ofSeconds(3)); wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(\"#id\")));
等待某个元素的文本内容为 \"预期文本\"(就是看括号内文本在不在前端页面中)
wait.until(ExpectedConditions.textToBe());
presenceOfElementLocated(By locator) 是 ExpectedConditions 类中的一个方法,用于显式等待某个元素出现在页面的 DOM 中。这个方法并不保证元素是可见的或可交互的,只是确保元素已经存在于页面的 DOM 结构中
wait.until(ExpectedConditions.presenceOfElementLocated())
检查当前⻚⾯的 URL 是⼀个特定的 URL
urlToBe(java.lang.String url)
3.6浏览器导航
//后退driver.navigate().back();//前进driver.navigate().forward();//刷新driver.navigate().refresh();
打开网站:
// 更⻓的⽅法driver.navigate().to(\"https://selenium.dev\");// 简洁的⽅法driver.get(\"https://selenium.dev\");
3.7 弹窗
弹窗不属于web页面元素,所以就没办法定位元素,这里就要使用Alert类
Alert alert = driver.switchTo.alert();//确认alert.accept()//取消alert.dismiss()
3.8 文件上传
点击⽂件上传的场景下会弹窗系统窗⼝,进⾏⽂件的选择。 selenium⽆法识别⾮web的控件,上传⽂件窗⼝为系统⾃带,⽆法识别窗⼝元素 但是可以使⽤sendkeys来上传指定路径的⽂件,达到的效果是⼀样的
WebElement ele = driver.findElement(By.cssSelector(\"body > div > div > input[type=file]\"));//输入文件本地存储的路径即可ele.sendKeys(\"D:\\\\selenium2html\\\\selenium2html\\\\upload.html\");
3.9 浏览器参数设置
1)\"无头模式\",指的是执行自动化的时候不会打开网页
options.addArguments(\"-headless\");
2)设置浏览器加载策略 options.setPageLoadStrategy(PageLoadStrategy.NONE);