什么是selenium
比较官方的解释
Selenium是一个自动化测试工具,用于在Web应用程序中模拟用户操作。它提供了一组API,可以通过编程方式控制浏览器,并模拟用户的交互行为,例如点击、输入文本和导航等。Selenium支持多种编程语言,包括Java、C#、Python、Ruby、JavaScript等,并可以在多个浏览器和操作系统上运行测试。Selenium的目标是帮助测试人员自动化测试过程,提高测试效率和测试质量。
个人的简单理解
- 浏览器驱动可以操作浏览器,不用selenium也能实现代码控制浏览器的效果,就是需要自己查询浏览器启动提供的功能,
- selenium可以看成是浏览器驱动的工具类,在项目中引入seleniu,就能通过selenium方便的操作浏览器
用途
- 自动化测试
- 爬虫
Java环境搭建
下载浏览器和对应的浏览器驱动器
浏览器和浏览器驱动版本要保持一致(一般前三位一致即可),浏览器和对应的驱动见附件
开启浏览器debug端口
连接到已打开的浏览器,需要浏览器开启debug端口,简单的开启方法如下
-
为chrome.exe创建一个快捷方式
-
chrome.exe创建>>右键>>属性>>目标后面添加--remote-debugging-port=9222(注意chrome.exe与新加内容之间有个空格,端口可以自由定义)
-
此时双击chrome快捷打开浏览器默认会开启debug端口
-
检查浏览器是否开启了debug端口,访问http://localhost:9222/json,返回以下内容说明浏览器成功开启了debug端口,9222是自定义端口
[ { "description": "", "devtoolsFrontendUrl": "/devtools/inspector.html?ws=localhost:9222/devtools/page/B3C592C54EB3552A0F5D76706A6EF844", "id": "B3C592C54EB3552A0F5D76706A6EF844", "title": "emp", "type": "page", "url": "http://localhost:8080/", "webSocketDebuggerUrl": "ws://localhost:9222/devtools/page/B3C592C54EB3552A0F5D76706A6EF844" } ]
引入依赖
org.seleniumhq.selenium selenium-java 3.141.59
Selenium测试代码
public class SeleniumTest { private WebDriver driver; private WebDriverWait wait; @SneakyThrows @Before public void toChrome() { connectExistingChrome(); // 访问指定的 URL driver.navigate().to("http://localhost:8080"); } @Test public void hello() { // 使用显示等待 循环寻找input,如果5秒内找到则返回,如果5秒内未找到则抛出异常 // WebElement nameInput = driver.findElement(By.xpath("/html/body/div[1]/form/div[1]/div/div/input")); WebElement nameInput = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("/html/body/div[1]/form/div[1]/div/div/input"))); // 元素操作(WebElement 相关api) nameInput.sendKeys("张无忌"); /* * 如果页面相对固定,可以用xpath寻找元素,xpath可以通过浏览器直接复制,详细步骤可参考笔记 * 如果页面变动频繁可以通过tagName找到所有的元素,然后再通过指定属性过滤 */ List buttons = driver.findElements(By.tagName("button")); WebElement queryButton = buttons.stream().filter(item -> "查询".equals(item.getText())).findFirst().get(); queryButton.click(); } /** * 显示等待 * TimeoutException: Expected condition failed: waiting for presence of element located by: By.id: absentId (tried for 30 second(s) with 500 milliseconds interval) */ @Test public void webDriverWaitTest(){ System.out.println(System.currentTimeMillis()); wait.until(ExpectedConditions.presenceOfElementLocated(By.id("absentId"))); System.out.println(System.currentTimeMillis()); } /** * 隐式等待 * NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#absentId"} */ @Test public void implicitlyWaitTest(){ System.out.println(System.currentTimeMillis()); driver.findElement(By.id("absentId")); System.out.println(System.currentTimeMillis()); } /** * 连接到已经存在的浏览器 * 这里直接连接已经打开的浏览器,不让浏览器启动器新打开窗口,好处如下 * 1. 退出浏览器驱动时不会退出我们已经打开的浏览器网页窗口 * 2. 自己打开的里面有登录的身份信息,新打开的可能没有身份信息,需要登录 * 连接已打开的浏览器需要浏览器开启debug端口,具体开启方法见文档 */ private void connectExistingChrome() { // 设置 ChromeDriver 的路径 System.setProperty("webdriver.chrome.driver", "C:\\118.0.5993.70\\chromedriver-win64\\chromedriver.exe"); // 配置 ChromeOptions ChromeOptions options = new ChromeOptions(); options.setExperimentalOption("debuggerAddress", "localhost:9222"); // 创建 ChromeDriver 实例 driver = new ChromeDriver(options); // 隐式等待(全局等待):每隔一段时间循环寻找元素,如果3秒内找到则返回元素,找不到则抛异常 driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS); // 显示等待器:如果超时就会抛出异常NoTouchElementException wait = new WebDriverWait(driver, 30); } /** * 打开一个新浏览器窗口 */ public void openNewChrome() { // 设置 ChromeDriver 的路径 System.setProperty("webdriver.chrome.driver", "C:\\118.0.5993.70\\chromedriver-win64\\chromedriver.exe"); // 配置 ChromeOptions ChromeOptions options = new ChromeOptions(); // 指定特定版本的 Chrome 浏览器路径 浏览器版本和浏览器驱动版本要保持一致(一般前三位一致即可) options.setBinary("C:\\118.0.5993.70\\chrome-win64\\chrome.exe"); // 可选:无头模式,不打开浏览器窗口 如果做爬虫不打开浏览器某些网站过不去,可能会遇到Enable JavaScript and cookies to continue // options.addArguments("--headless"); // 解决一些系统的图形化渲染问题 options.addArguments("--disable-gpu"); // 在某些系统上需要添加此参数 options.addArguments("--no-sandbox"); // 解决资源共享内存的问题 options.addArguments("--disable-dev-shm-usage"); // 创建 ChromeDriver 实例 driver = new ChromeDriver(options); // 为浏览器驱动driver创建一个等待器,循环等待,直到条件达成或者超时,如果条件未达成超时就会跑出异常 wait = new WebDriverWait(driver, 30); } @SneakyThrows @After public void closeChrome() { // 退出浏览器驱动程序 driver.quit(); } }
这里直接连接已经打开的浏览器,不让浏览器驱动器新打开窗口,好处如下
- 退出浏览器驱动时不会退出我们已经打开的浏览器网页窗口
- 浏览器驱动器打开的新窗口可能没有身份信息,需要登录
获取Xpath技巧
- 如果页面元素相对比较固定,可以直接用xpath定位,简单直接,xpath可以直接从浏览器赋值
复制出来的xpath直接粘贴到代码里即可
/html/body/div[2]/div[1]/div/div[1]/div/div/div[1]/div/form/div[2]/div/div[1]/div[1]/textarea
如果前端页面频繁更新,页面元素位置经常变动,就不太适合这种方式了
- 如果页面元素经常变动,但是提示语或者某些属性比较固定,可以拿到所有这个类型的元素,再根据固定的属性过滤
List textareaList = driver.findElements(By.tagName("textarea")); for (WebElement textarea : textareaList) { String placeholder = textarea.getAttribute("placeholder"); if (placeholder.contains("内容概要+适用人群+使用场景及目标+其他说明")) { // 拿到了资源描述文本框 } }
常用方法
// 请求一个页面,不支持前进和后退切换 driver.get(url); // 和get类似,支持前进和后退切换 driver.navigate().to(url); // 退到上一个页面 ,前提必须前进了一个页面才能回退 driver.navigate().back(); // 指前进到下一个页面 ,前提是必须后退后才能前进 driver.navigate().forward(); // 刷新当前页面 driver.navigate().refresh(); // 通用搜索,第一个 , By里包含常用的各种搜索 WebElement findElement(By by); // 通用搜索,多个,By里包含常用的各种搜索 List findElements(By by); // 关闭当前窗口,如果它是当前打开的最后一个窗口,则退出浏览器。 driver.close(); // 退出此驱动程序,关闭每个相关窗口。 driver.quit();
WebElement常用方法
元素定位
- 根据id定位
- 根据a标签内容定位
- 根据a标签内容模糊定位
- 根据name属性定位
- 根据标签名字定位
- 根据路径匹配
- 根据类名定位
- 根据css选择器定位
元素操作
- click():点击该元素。
- submit():将表单提交到该元素所在的表单。
- sendKeys(CharSequence… keysToSend):将指定的字符序列发送到该元素。例如向输入框输入文本。
- clear():清除该元素的内容。
- getTagName():获取该元素的标签名称。
- getAttribute(String name):获取该元素指定属性的值。
- getText():获取该元素的文本内容。
- isEnabled():判断该元素是否可用。
- isSelected():判断该元素是否被选中。
- isDisplayed():判断该元素是否可见。
- getLocation():获取该元素在页面中的位置。以Point对象表示,包含x和y坐标。
- getSize():获取该元素的大小,以Dimension对象表示,包含width和height。
- getCssValue(String propertyName):获取该元素指定CSS属性的值。
等待机制
- 显示等待
- 隐式等待
显示等待与隐式等待的区别
-
显示等待是指在代码中明确指定等待条件和等待时间,直到条件成立或等待时间到期,程序才会继续执行下一步操作。显示等待可以根据不同的条件进行等待,例如元素的可见性、可点击性、文本内容、属性值等。显示等待可以通过ExpectedConditions类来实现。
-
隐式等待是指在代码中设置一个全局等待时间,在此时间内如果元素没有立即出现,程序将等待指定的时间,等待元素出现。隐式等待适用于整个测试用例,而不是针对某个特定的元素。隐式等待可以通过WebDriver.Timeouts.implicitlyWait()方法来设置。。
selenium实战
基于selenium的crud
- 启动项目
- crud详见代码com.study.selenium.EmpCRUDTest
- 效果见演示视频
码云地址
https://gitee.com/LessAndfaster/study-selenium.git
在线笔记
https://blog.csdn.net/weixin_41883161/article/details/139270612