前言
本篇使用Selenium3+Junit5对个人技术交流论坛进行简单的自动化测试,如有错误,请在评论区指正,让我们一起交流,共同进步!
文章目录
- 前言
- 1. 项目基础描述
- 2. 编写手工测试用例
- 3. 测试用例转自动化测试用例
- 3.1 前置准备操作
- 3.1.1 配置环境:
- 3.1.2 配置使用的公共类
- 3.1.3 项目目录 + 截图
- 3.2 编写自动化测试脚本
- 3.2.1 注册自动化测试
- 成功注册
- 注册失败情况
- 3.2.2 登录自动化测试
- 成功登录情况
- 失败登录
- 3.2.3 列表页自动化测试
- 登录状态下查看列表
- 未登录状态下查看帖子页
- 3.2.4 帖子编辑自动化测试
- 登录状态下进行帖子编辑
- 未登录状态
- 3.2.5 个人中心自动化测试
- 登录状态下获取个人信息
- 未登录状态获取个人中心
- 3.2.6 退出功能自动化测试
- 登录状态下退出
- 4.小结
- 考虑提升:
- 后期注意
- 测试优势:
- 总结
本文开始
1. 项目基础描述
项目介绍:
技术交流论坛基于 Spring Boot,MyBatis, MySQL等技术实现的一个前后端分离的一个项目;
主要功能页有:登录页、注册页、技术交流论坛列表展示页,帖子编辑发布和个人中心页。
测试主要页面:登录页面,注册页面,列表展示页面以及帖子编辑发布页,个人信息展示,退出操作功能。【都是基于常用的主要页面进行的】
2. 编写手工测试用例
3. 测试用例转自动化测试用例
3.1 前置准备操作
3.1.1 配置环境:
创建Maven项目,配置pom.xml文件
<dependencies><!--添加selenium依赖--><!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java --><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>3.141.59</version></dependency><!--保存屏幕截图的包--><!-- https://mvnrepository.com/artifact/commons-io/commons-io --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.11.0</version></dependency><!--Junit5--><!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api --><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.1</version></dependency><!-- https://mvnrepository.com/artifact/org.junit.platform/junit-platform-suite --><dependency><groupId>org.junit.platform</groupId><artifactId>junit-platform-suite</artifactId><version>1.9.1</version></dependency></dependencies>
3.1.2 配置使用的公共类
原因:
1.每个测试用例都需要驱动,使用前置方法设置,后置方法释放驱动资源
2.配置一些公共方法,方便测试使用;如:截图方法,进入登录状态方法等
public class AutoTestUtils {//每次测试都需要驱动,写一个公共类,实现代码复用public static WebDriver webDriver;@BeforeAllpublic static void SetUp() {if(webDriver == null) {System.setProperty("webdriver.chrome.driver","C:\\Program Files\\Google\\Chrome\\Application\\chromedriver.exe");webDriver = new ChromeDriver();}}@AfterAllstatic void TearDown() {webDriver.quit();}/*** 截图方法*/public static void saveScreenshot(WebDriver driver, String fileName) throws IOException {File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);// 确保截图目录存在File screenshotDir = new File(SCREENSHOT_DIR);if (!screenshotDir.exists()) {screenshotDir.mkdirs();}// 拼接完整的文件路径File destFile = new File(screenshotDir, fileName);// 复制文件FileUtils.copyFile(srcFile, destFile);System.out.println("Screenshot saved as " + destFile.getAbsolutePath());}/*** 获取当前截图时间-字符串* @return*/public static String getCurrentShotTime() {SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd-HHmmss");String timeName = sdf.format(System.currentTimeMillis());return timeName;}/*** 封装登录方法,方便以后调用;以后测试需要在登录状态下使用*/public static void login() throws InterruptedException {//1.打开登录页面webDriver.get("http://8.130.77.131:58080/sign-in.html");//2.清楚之前的账号密码webDriver.findElement(By.cssSelector("#username")).clear();webDriver.findElement(By.cssSelector("#password")).clear();//3.找到输入框,输入正确的账号和密码webDriver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");webDriver.findElement(By.cssSelector("#password")).sendKeys("123");//4.点击登录按钮webDriver.findElement(By.cssSelector("#submit")).click();sleep(3000);}}
3.1.3 项目目录 + 截图
3.2 编写自动化测试脚本
3.2.1 注册自动化测试
- 注册界面测试 - RegTest
1.获取驱动,打开注册界面
2.找到输入框,输入账号,昵称,密码,确认密码
3.点击确认协议
4.校验是否注册成功
5.注册失败,截图查看失败原因
成功注册
/*** 成功注册的情况*/@Order(1)@ParameterizedTest@CsvSource(value = {"lisi,lisi,123,123"})public void regSuccessTest(String username, String nickname,String password, String passwordRepeat) throws InterruptedException {//显示等待webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//1.打开注册页面webDriver.get("http://8.130.77.131:58080/sign-up.html");//2.找到输入框,输入注册的账号和密码webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.findElement(By.cssSelector("#nickname")).sendKeys(nickname);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);webDriver.findElement(By.cssSelector("#passwordRepeat")).sendKeys(passwordRepeat);//4.点击同意协议webDriver.findElement(By.cssSelector("#policy")).click();//5.点击注册按钮webDriver.findElement(By.cssSelector("#submit")).click();//5.验证是否跳转到登录页sleep(2000);String currentUrl = webDriver.getCurrentUrl();Assertions.assertTrue(currentUrl.contains("sign-in.html"));//查看是否包含关键词webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);}
注册失败情况
【注】编写的测试用例太多,取几个演示
@Order(2)@ParameterizedTest@CsvSource(value = {"wangwu,wangwu,123,1234"})public void regFailTest(String username, String nickname,String password, String passwordRepeat) throws InterruptedException, IOException {//显示等待webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//1.打开注册页面webDriver.get("http://8.130.77.131:58080/sign-up.html");//2.找到输入框,输入注册的账号和密码webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.findElement(By.cssSelector("#nickname")).sendKeys(nickname);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);webDriver.findElement(By.cssSelector("#passwordRepeat")).sendKeys(passwordRepeat);//3.错误截图,生成当前截图时间String timeName = getCurrentShotTime();String fileName = "regFail" + timeName + ".png";sleep(2000);saveScreenshot(webDriver,fileName);//4.点击同意协议webDriver.findElement(By.cssSelector("#policy")).click();//5.点击注册按钮webDriver.findElement(By.cssSelector("#submit")).click();String timeName2 = getCurrentShotTime();String fileName2 = "regClickFail" + timeName2 + ".png";sleep(2000);saveScreenshot(webDriver,fileName2);}/*** 昵称为空 + 密码错误*/@Order(3)@ParameterizedTest@CsvSource(value = {"laoliu,laoliu,123,123"})public void regNickNameNullTest(String username, String nickname,String password, String passwordRepeat) throws InterruptedException, IOException {//显示等待webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//1.打开注册页面webDriver.get("http://8.130.77.131:58080/sign-up.html");//2.找到输入框,输入注册的账号和密码webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);webDriver.findElement(By.cssSelector("#passwordRepeat")).sendKeys(passwordRepeat);//3.点击同意协议webDriver.findElement(By.cssSelector("#policy")).click();//4.点击注册按钮webDriver.findElement(By.cssSelector("#submit")).click();//5.失败截图String timeName = getCurrentShotTime();String fileName = "regNickNameNull" + timeName + ".png";sleep(2000);saveScreenshot(webDriver,fileName);}
测试结果:
失败截图查看原因
3.2.2 登录自动化测试
- 登录界面自动化测试 - LoginTest
1.获取驱动,打开登录界面
2.校验正常登录 - 多参数测试,多个测试用例
3.校验异常登录 - 错误的密码登录
4.对于多组测试,需要清空上次输入的内容
5.使用注解保证测试的顺序
成功登录情况
/*** 正常登录情况* 参数化登录:使用注解@CsvSource*/@Order(1)@ParameterizedTest@CsvSource({"zhangsan,123", "张三,123"})public void logSuccessTest(String name, String password) throws InterruptedException {//显示等待webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//1.打开登录页面webDriver.get("http://8.130.77.131:58080/sign-in.html");//2.清楚之前的账号密码webDriver.findElement(By.cssSelector("#username")).clear();webDriver.findElement(By.cssSelector("#password")).clear();//3.找到输入框,输入正确的账号和密码webDriver.findElement(By.cssSelector("#username")).sendKeys(name);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);//4.点击登录按钮webDriver.findElement(By.cssSelector("#submit")).click();//5.验证是否跳转到列表页
// webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);sleep(2000);String currentUrl = webDriver.getCurrentUrl();Assertions.assertEquals("http://8.130.77.131:58080/index.html", currentUrl);//6.多次登录,每次登录后退回登录页面webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.navigate().back();}
失败登录
/*** 异常登录情况* 输入错误的账号+密码*/@Disabled // 不运行注释@Order(2)@ParameterizedTest@CsvSource(value = "zhangsan,1234")public void failLogin(String name, String password) throws InterruptedException, IOException {//1.打开登录页面webDriver.get("http://8.130.77.131:58080/sign-in.html");webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//2.输入账号:zhangsan,密码:1234webDriver.findElement(By.cssSelector("#username")).sendKeys(name);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);Thread.sleep(2000);//3.点击提交webDriver.findElement(By.cssSelector("#submit")).click();//4.获取提示信息文本:用户或密码错误String text = webDriver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div")).getText();System.out.println("提示信息:" + text);//5.生成当前截图时间String timeName = getCurrentShotTime();String fileName = "loginFail" + timeName + ".png";//6.调用截图方法sleep(3000);saveScreenshot(webDriver,fileName);}
运行结果
错误情况截图
3.2.3 列表页自动化测试
- 遇到的bug:
- 操作:登录状态查看帖子列表
- 出现异常: no such element
- 原因:首页帖子页面还未渲染完毕,就捕获文本元素
- 解决:使用隐式等待
如:webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
登录状态下查看列表
/*** 登录状态查看帖子列表* 出现异常: no such element* 原因:首页帖子页面还未渲染完毕,就捕获文本元素* 解决:使用显示等待*/@Test@Order(1)public void showSuccess() throws InterruptedException {//1.登录操作login();//2.显示首页帖子列表,查看第一天帖子信息webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);String actual_text = webDriver.findElement(By.cssSelector("#artical-items-body > div:nth-child(1) > div > div.col > div.text-truncate > a > strong")).getText();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//3.断言校验Assertions.assertEquals("Java是如何练成的?", actual_text);}
未登录状态下查看帖子页
/*** 未登录页不能够查看帖子页* 能够显示*/@Test@Order(2)public void showFail() throws InterruptedException, IOException {//1.不进行登录,直接查看帖子页面webDriver.get("http://8.130.77.131:58080/index.html");//2.显示列表页,使用截图查看String timeName = getCurrentShotTime();String fileName = "showFail" + timeName + ".png";//3.调用截图方法sleep(3000);saveScreenshot(webDriver,fileName);}
运行结果
未登录错误情况截图
3.2.4 帖子编辑自动化测试
- 遇到bug:
- 操作:登录状态下进行帖子编辑
- 出现异常:ElementClickInterceptedException: element click intercepted: Element is not clickable at point (939, 1108)
- 原因:页面是异步加载,点击按钮未加载,就进行了的点击,导致元素点击中断,找不到点击位置
登录状态下进行帖子编辑
/*** 登录状态下进行帖子编辑* 出现异常:ElementClickInterceptedException: element click intercepted: Element is not clickable at point (939, 1108)* 原因:页面是异步加载,点击按钮未加载,就进行了的点击,导致元素点击中断,找不到点击位置*/@Testpublic void editSuccess() throws InterruptedException, IOException {//1.进入登录状态login();//2.点击编辑帖子webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.xpath("//*[@id=\"forum-content\"]/div[1]/div/div/div[2]/div/a[1]")).click();//3.输入帖子标题webDriver.findElement(By.xpath("//*[@id='article_post_title']")).sendKeys("EditTest");;sleep(3000);//4.查看发布帖子按钮String text = webDriver.findElement(By.xpath("//*[@id='article_post_submit']")).getText();Assertions.assertEquals("发 布", text);sleep(3000);webDriver.findElement(By.xpath("/html/body/div[1]/div/div[1]/div[2]/div/div/div[2]/div/a")).click();String text1 = webDriver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div")).getText();System.out.println("提示:" + text1);//5.截图查看String time = getCurrentShotTime();String fileName = "editSuccess" + time + ".png";sleep(2000);saveScreenshot(webDriver, fileName);}
未登录状态
/*** 未登录状态,直接提示报错信息*/@Testpublic void editFail() throws InterruptedException, IOException {//1.直接进入编辑页面webDriver.get("http://8.130.77.131:58080/index.html");//2.截图获取信息String time = getCurrentShotTime();String fileName = "editFail" + time + ".png";sleep(2000);saveScreenshot(webDriver, fileName);}
运行结果:
没有输入帖子内容,错误提示截图
3.2.5 个人中心自动化测试
登录状态下获取个人信息
/*** 登录状态下,获取个人信息*/@Testpublic void successShowPersonInfo() throws InterruptedException {//1.进入登录状态login();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//2.点击个人中心webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();//点击个人头像webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#index_user_settings")).click();//下拉列表中,点击个人中心sleep(2000);//3.获取用户昵称String actual_text = webDriver.findElement(By.cssSelector("#setting_input_nickname")).getAttribute("value");webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);Assertions.assertEquals("zhangsan", actual_text);}
未登录状态获取个人中心
@Testpublic void failShowPersonInfo() throws InterruptedException, IOException {//1.进入列表页webDriver.get("http://8.130.77.131:58080/index.html");//2.点击个人中心webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();//点击个人头像webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#index_user_settings")).click();//下拉列表中,点击个人中心//3.截图查看提示String timeName = getCurrentShotTime();String fileName = "failShowPersonInfo" + timeName + ".png";//3.调用截图方法sleep(3000);saveScreenshot(webDriver,fileName);}
运行结果
未登录状态,错误提示截图
3.2.6 退出功能自动化测试
登录状态下退出
/*** 登录状态点击退出*/@Testpublic void backSucTest() throws InterruptedException {//1.进入登录状态login();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//2.点击个人中心webDriver.findElement(By.cssSelector("#index_nav_avatar")).click();//点击个人头像//3.点击退出webDriver.findElement(By.xpath("//*[@id=\"index_user_logout\"]")).click();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//4.回到登录页面校验 “用户登录” 文本String login_text = webDriver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2")).getText();Assertions.assertEquals("用户登录", login_text);}
运行结果:
4.小结
考虑提升:
- 可以考虑使用PO模式,现在的代码将获取元素,操作元素,测试元素操作混在了一起,对于后期维护比较困难,使用PO模式改进,可以复用元素代码,让多个人写测试用例的耦合降低,也利用后期的维护工作;
后期注意
- 需要注意测试的执行顺序,不关注可能报错
- 对于多参数测试,需要清空上次输入数据,页面回退
- 测试用例并不是越多越好,覆盖较多功能较好
- 测试功能会有遗漏的情况,对于测试用例执行顺序会有错误情况
测试优势:
1.使用Junit5单元测试框架中的注释:提高测试的稳定性,提高自动化执行效率;(指定执行测试顺序,指定参数)
2.根据技术交流论坛设计的手工测试用例,对每个测试用例的常用功能实现自动化测试
3.使用工具类每次测试都需要驱动,写一个公共类,实现代码复用
4.使用等待:提高自动化运行效率,提高自动化的稳定性,减小误报的可能性
总结
✨✨✨各位读友,本篇分享到内容如果对你有帮助给个👍赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!