一、编写web测试用例
1.1 主要页面
1.1.1 登录页
1.1.2 列表页
1.1.3 详情页
1.1.4 编辑页
1.2 主要功能
能实现登录、查看列表、查看详情页、编辑内容
自动化测试,检查各个页面独立的功能,以及整体各个页面之间的跳转
二、创建Maven空项目
2.1 在pom.xml里添加需要的依赖
导入selenium库
<dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.0.0</version> </dependency>
导入驱动管理
<dependency> <groupId>io.github.bonigarcia</groupId> <artifactId>webdrivermanager</artifactId> <version>5.8.0</version> <scope>test</scope> </dependency>
导入屏幕截图所需要的包
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency>
2.2 设计文件结构
创建驱动对象 - 所以的测试对象共用一个 driver 对象
编写测试用例 - 如何划分用例? 按照页面分类,每个页面是一个Java文件,页面下所有的用例统一管理
runTest : 执行测试用例
common 包:放共用的资源
- Utils.java 创建驱动对象
tests 包 :放所有页面的用例
- LoginPage.java 登录页面的所有用例
- ListPage.java 列表页面的所有用例
- EditPage.java 编辑页面的所有用例
image 文件夹:放所有测试的屏幕截图
/2024-08-27/
2024153402.png
2024353614.png
/2024-08-27/
2024353402.png
2024353614.png
三、编写自动化脚本
编写自动化脚本时,注意一些方法的调用顺序,可以避免一些不必要的错误
3.1 登录页面测试用例 LoginPage.java
package tests;
import common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.IOException;
import java.time.Duration;
public class LoginPage extends Utils {
/**
* 登录页面的 url
*/
public static String url ="http://124.71.204.113:8080/blog_system/login.html";//登录页面
/**
* 构造函数
* 子类继承父类之后,需要在子类构造方法里 先初始化父类
* @param
*/
public LoginPage() {
super(url);//初始化父类
}
/**
* 检查页面是否加载成功
*/
public void loginPageRight(){
//通过查看页面元素是否存在 来检查页面加载成功与否
//登录输入框
driver.findElement(By.cssSelector("body > div.login-container > div"));
driver.findElement(By.cssSelector("#username"));
System.out.println("登录页面加载测试用例 - 已完成");
// driver.quit();
}
/**
* 测试登录成功
*/
public void loginSuc() throws IOException {
WebDriverWait webDriverWait = new WebDriverWait(driver, Duration.ofSeconds(3));
//显示等待 - 判断是否有这个文本输入框
webDriverWait.until(ExpectedConditions.attributeContains(By.cssSelector("#username"),"type","text"));
driver.findElement(By.cssSelector("#username")).sendKeys("AmerisZ");//输入账号
//显示等待 - 判断是否有这个密码输入框
webDriverWait.until(ExpectedConditions.attributeContains(By.cssSelector("#password"),"type","password"));
driver.findElement(By.cssSelector("#password")).sendKeys("123456");//输入密码
//显示等待 - 判断登录按钮是否能点击
webDriverWait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#submit")));
driver.findElement(By.cssSelector("#submit")).click();//点击登录提交按钮
//列表不为空
//通过 跳转后的页面标题名 来判断是否跳转了 (列表页面的元素 、url都可以用来判断)
String str = driver.getTitle();
// getScreenShot("loginSuc"); //断言之前截图,保存出错时的页面图
assert str.equals("博客列表页");
// String currentUrl = driver.getCurrentUrl();
// assert currentUrl.equals("http://124.71.204.113:8089/list.html");
// webDriverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#body > div.container")));
//回退到登录界面,进行下面的测试
driver.navigate().back();
System.out.println("登录成功测试用例 - 已完成");
}
/**
* 测试登录失败
*/
public void loginFail() throws InterruptedException, IOException {
/**
* 上一个测试案例登录成功后,回到了登录页面,把页面刷新,清空输入框的内容
*/
driver.navigate().refresh();
/**
* 重新输入
*/
WebDriverWait webDriverWait = new WebDriverWait(driver, Duration.ofSeconds(3));
//显示等待 - 判断是否有这个文本输入框
webDriverWait.until(ExpectedConditions.attributeContains(By.cssSelector("#username"),"type","text"));
driver.findElement(By.cssSelector("#username")).sendKeys("AmerisZ");//输入账号
//显示等待 - 判断是否有这个密码输入框
webDriverWait.until(ExpectedConditions.attributeContains(By.cssSelector("#password"),"type","password"));
/**
* 故意写错密码
*/
driver.findElement(By.cssSelector("#password")).sendKeys("11111111");//输入密码
//显示等待 - 判断登录按钮是否能点击
webDriverWait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#submit")));
driver.findElement(By.cssSelector("#submit")).click();//点击登录提交按钮
/**
* 判断提示文字
*/
String text = driver.findElement(By.cssSelector("body")).getText();
// getScreenShot("loginSuc"); //断言之前截图,保存出错时的页面图
assert text.equals("您输入的用户名或密码不正确!!");
System.out.println("登录失败测试用例 - 已完成");
}
}
3.1.1 页面加载用例
3.1.2 登录成功用例
3.1.3 登录失败用例
断言 assert 需要额外配置
3.2 列表页面测试用例 ListPage.java
package tests;
import common.Utils;
import org.bouncycastle.util.Exceptions;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.IOException;
import java.time.Duration;
public class ListPage extends Utils {
public static String url = "http://124.71.204.113:8080/blog_system/blog_list.html";
/**
* 构造函数
*
* @param
*/
public ListPage() {
super(url);
}
/**
* 登录状态下 - 是否查看博客内容
*/
public void listByLogin() throws IOException {
//测试是否有登录页面的元素 “查看全文”的按钮
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > a")));
driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > a")).click();
//跳转到详情页,是否能查看博客内容
String title = driver.getTitle();
assert title.equals("博客详情页");
//退回列表页
System.out.println("登录状态 - 列表页跳转详情页测试用例 - 已完成");
driver.navigate().back();
}
/**
* 登录状态下 - 是否能进入写博客页面
*
*/
public void listToEditPage(){
//测试是否有登录页面的元素 “写博客”的按钮
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("body > div.nav > a:nth-child(5)")));
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
//跳转到写博客页面 - 博客编辑页
String title = driver.getTitle();
assert title.equals("博客编辑页");
//退回列表页
System.out.println("登录状态 - 列表页跳转编辑页测试用例 - 已完成");
driver.navigate().back();
}
/**
* 未登陆状态下 -- 访问列表页
* 注意:前面的登录用例下,登录状态可能已经保存下来辽
* 方法1:点击注销,注销账号退出登录
* 方法2:另外创建一个PageByNoLogin类,专门管理未登录状态下的测试
*/
public void listNoLogin() throws IOException, InterruptedException {
//点击注销按钮,退出登录
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("body > div.nav > a:nth-child(6)")));
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
//退出后,为未登录状态,获取list
driver.get(url);
//未登录状态下,会强制跳转到登录页面,判断是否为登录页面
WebElement until = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#username")));
System.out.println("未登录状态 - 列表测试用例 - 已完成");
driver.quit();
}
}
3.2.1 登录状态下 - 查看博客内容 测试用例
3.2.1 登录状态下 - 进入编辑页 测试用例
3.2.3 未登录状态下 测试用例
3.3 编辑页面测试用例 EditPage.java (比较特殊)
一般情况下,自己本地编写的页面是能正常复制选择器并且交互的。
但由于博客项目里面的编辑功能是导入的第三方插件,在自动化输入内容编辑博客的时候,会出现一些问题,会报错 (ElementNotInteractableException 元素不可交互)
解决办法:使用selenium自带的actions接口
package tests;
import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
public class EditPage extends Utils {
public static String url = "http://124.71.204.113:8080/blog_system/blog_edit.html";
/**
* 构造函数
*
* @param
*/
public EditPage() {
super(url);
}
public void editSuc() throws InterruptedException {
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(2));
//编辑标题内容
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#title-input")));
driver.findElement(By.cssSelector("#title-input")).sendKeys("这是标题 AutoTest01");
/**
* 无法输入博客内容 -- 怎么办?
* 方法1:博客内容本身就有默认内容,不需要手动实现,编辑完标题,发布就行
* 方法2:通过selenium键盘操作来实现
*/
//编辑文章内容
//判断这个编辑的元素 是否存在 是否能点击
// wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div")));
// wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div")));
WebElement element = driver.findElement(By.cssSelector("#editor > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll > div.CodeMirror-sizer > div > div"));
Actions actions = new Actions(driver);
//双击元素,并且使用.perform()在页面查看效果
Thread.sleep(2000);
actions.doubleClick(element).perform();
Thread.sleep(2000);
//按下按键 - delete按键 - 展示
actions.keyDown(Keys.DELETE).perform();
Thread.sleep(2000);
//鼠标移动到这个元素 - 输入内容 - 展示
actions.moveToElement(element).sendKeys("Actions模拟键盘操作,输入博客内容 AutoTest").perform();
Thread.sleep(2000);
System.out.println("编辑成功测试用例 - 已完成");
driver.quit();
}
}