自动化实战 - 测试个人博客系统
前言
本篇使用Selenium3+Junit5对个人博客进行自动化测试,如有错误,请在评论区指正,让我们一起交流,共同进步!
文章目录
- 前言
- 一.web自动化测试用例
- 二.测试准备
- 1.注册界面自动化测试
- 测试过程中遇到的Bug:
- 2.登录界面自动化测试
- 登录测试的过程中的Bug:
- 3.个人博客管理页自动化测试
- 测试个人博客管理页的Bug
- 4.博客编辑页自动化测试
- 博客编辑页出现的Bug
- 5.总博客列表页自动化测试
- 6.测试套件 - RunSuiteTest
- 三、小结
- 参考代码
- 总结
本文开始
一.web自动化测试用例
描述:针对个人博客项目,主要测试五个页面:注册页,登录页,个人博客管理页,编辑页,总博客列表页,对其主要功能,注册,登录,编辑,查看,删除,注销等常用功能进行自动化测试;
根据博客系统,设计部分手工测试用例:
二.测试准备
1.创建Maven项目
2.添加相应的依赖
- 根据编写的测试用例,对每个页面进行测试,测试每个页面的主要功能
- 添加公共类
<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>
公共管理类
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();}
}
对主要测试重点功能,进行自动化测试
1.注册界面自动化测试
- 注册界面测试 - RegTest
1.获取驱动,打开注册界面
2.校验界面是否完整 - 测试是否有注册提交按钮
3.校验注册正常操作
4.校验注册失败操作
5.指定注册测试的顺序,保证注册测试的正常
测试过程中遇到的Bug:
- 获取弹窗内容必须在弹窗还没有关闭的状态执行,如果弹窗关闭,在去获取弹窗text内容,会包No such alert错误;
- 在注册过程中,如果数据库中注册信息重复了,但没有弹窗提示,在获取alert()弹窗是也会报No such alert错误;
注册测试代码:
package webAutoTest.TestClass;import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;
import webAutoTest.common.AutoTestUtils;import java.util.concurrent.TimeUnit;
import static java.lang.Thread.sleep;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class RegTest extends AutoTestUtils {/*** 测试注册页面的完整性* 测试注册页面使用XPath获取元素位置 - 需要使用By.xpath()获取,如果使用Css选择器回找不到选择器而报错*/@Order(1)@Testvoid regPageTest() {//1.打开注册页webDriver.get("http://localhost:8080/reg.html");webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//2.校验注册框是否存在String reg_title = webDriver.findElement(By.xpath("/html/body/div[2]/div/h3")).getText();Assertions.assertEquals("注册", reg_title);//3.注册提交按钮是否存在webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);WebElement webElement = webDriver.findElement(By.xpath("//*[@id=\"submit\"]"));Assertions.assertNotNull(webElement);}/*** 测试注册正常操作* 数据库中已有注册账号 - 不会有弹窗提示,操作报错*/@Order(2)@ParameterizedTest@CsvSource({"李四,abc,abc"})void regSuccessTest(String username, String password1, String password2) throws InterruptedException {
// webDriver.get("http://localhost:8080/reg.html");webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);//1.清空之前注册操作webDriver.findElement(By.xpath("//*[@id=\"username\"]")).clear();webDriver.findElement(By.xpath("//*[@id=\"password\"]")).clear();webDriver.findElement(By.xpath("//*[@id=\"password2\"]")).clear();webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);//2.输入注册账号,密码,确认密码webDriver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys(username);webDriver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys(password1);webDriver.findElement(By.xpath("//*[@id=\"password2\"]")).sendKeys(password2);//3.点击提交按钮,提交webDriver.manage().timeouts().implicitlyWait(5,TimeUnit.SECONDS);webDriver.findElement(By.xpath("//*[@id=\"submit\"]")).click();//4.显示注册成功弹窗,确认弹窗sleep(1000); //为了测试看清测试过程,也为了让页面不用渲染太快,导致找不到弹窗报错Alert alert = webDriver.switchTo().alert();webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);alert.accept();//5.校验是否注册后跳转到登录页面:sleep(500);String currentUrl = webDriver.getCurrentUrl();Assertions.assertEquals("http://localhost:8080/login.html",currentUrl);//5.再回退到注册页,方便后面的测试webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.navigate().back();}/*** 测试登录失败* @param username* @param password1* @param password2* 获取弹窗内容必须在弹窗还没有关闭的状态执行,如果弹窗关闭,在去获取弹窗text内容,会包No such alert错误;*/@Order(3)@ParameterizedTest@CsvSource({"老六,123,1234"})void regFailTest(String username, String password1, String password2) throws InterruptedException {//1.打开注册页面webDriver.get("http://localhost:8080/reg.html");//2.清空注册框webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.findElement(By.xpath("//*[@id=\"username\"]")).clear();webDriver.findElement(By.xpath("//*[@id=\"password\"]")).clear();webDriver.findElement(By.xpath("//*[@id=\"password2\"]")).clear();//3.输入密码,判断输入密码两次是否一样webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.findElement(By.xpath("//*[@id=\"username\"]")).sendKeys(username);webDriver.findElement(By.xpath("//*[@id=\"password\"]")).sendKeys(password1);webDriver.findElement(By.xpath("//*[@id=\"password2\"]")).sendKeys(password2);webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.findElement(By.xpath("//*[@id=\"submit\"]")).click();//4.出现弹窗提示,点击确认Alert alert = webDriver.switchTo().alert();webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);Assertions.assertEquals("两次密码不一致!",alert.getText());String info = alert.getText();System.out.println(info);alert.accept();}
}
测试结果界面:
2.登录界面自动化测试
- 登录界面自动化测试 - LoginTest
1.获取驱动,打开登录界面
2.校验界面是否正常 - 测试是否有登录提交按钮
3.校验正常登录 - 多参数测试,多个测试用例
4.校验异常登录 - 错误的密码登录
5.对于多组测试,需要情况上次输入的内容
6.使用注解保证测试的顺序
登录测试的过程中的Bug:
- 设置强制等待,不设置页面会因为渲染过快,alert弹窗还没有弹出,就断言判断页面的url,从而造成错误;
- 对于多组参数的数据,下一组测试前需要清空上一组测试的数据
- 测试登录成功后显示个人列表页面,对比成功后页面的url,对于多组测试数据需要回退,不然会断言错误;
package webAutoTest.TestClass;import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import webAutoTest.common.AutoTestUtils;import org.openqa.selenium.support.ui.WebDriverWait;import static java.lang.Thread.sleep;
import static java.time.Duration.ofSeconds;
import java.time.Duration;
import java.util.concurrent.TimeUnit;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class LoginTest extends AutoTestUtils {/*** 测试登录页面是否正常显示*/@Order(1)@Testvoid loginPageTest() {webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//1.打开登录页面,看页面是否正常webDriver.get("http://localhost:8080/login.html");//2.登录标题是否存在webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);String login_title = webDriver.findElement(By.cssSelector("body > div.login-container > div > h3")).getText();Assertions.assertEquals("登录",login_title);//3.登录提交按钮是否存在webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);WebElement webElement = webDriver.findElement(By.cssSelector("#submit"));Assertions.assertNotNull(webElement);}/*** 登录成功* @param username* @param password* @throws InterruptedException*/@Order(2)@ParameterizedTest@CsvSource({"张三,123","王五,123"})void loginSuccessTest(String username,String password) throws InterruptedException {webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//1.清理之前的账号,密码 - 多账户登录webDriver.findElement(By.cssSelector("#username")).clear();webDriver.findElement(By.cssSelector("#password")).clear();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//2.找到输入框,输入账号,密码webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);//3.点击提交按钮webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#submit")).click();//4.验证个人列表url,看是否登录成功sleep(200);String currentUrl = webDriver.getCurrentUrl();Assertions.assertEquals("http://localhost:8080/myblog_list.html",currentUrl);//5.为测试多次登录,需要回退到登录页webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.navigate().back();}/*** 登录失败* @param username* @param password* @param list_url* @throws InterruptedException*/@Order(3)@Disabled@ParameterizedTest@CsvFileSource(resources = "LoginFail.csv")void LoginFail(String username, String password, String list_url) throws InterruptedException {//1.打开博客登录页webDriver.get("http://localhost:8080/login.html");webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//2.输入账号:张三, 密码:1234webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//3.点击提交webDriver.findElement(By.cssSelector("#submit")).click();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//4.出现弹窗提示用户或密码错误,点击弹窗确认Alert alert = webDriver.switchTo().alert();System.out.println(alert.getText());webDriver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);//设置等待时间过短,会报错,页面渲染过快,弹窗捕捉不到,导致错误alert.accept();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//5.确认当前是登录页webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);String currentUrl = webDriver.getCurrentUrl();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);Assertions.assertNotEquals(list_url,currentUrl);}}
测试结果:
3.个人博客管理页自动化测试
- 个人文章列表页自动化测试 - BlogListTest
1.处于登录状态
2.校验个人博客管理页是否正常
3.校验查看博客按钮,编辑博客按钮,删除博客按钮
4.测试未登录状态,直接跳转登录页
测试个人博客管理页的Bug
- 必须在登录状态才能看到,个人博客列表
package webAutoTest.TestClass;import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import webAutoTest.common.AutoTestUtils;import java.util.Queue;
import java.util.concurrent.TimeUnit;
import static java.lang.Thread.sleep;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogListTest extends AutoTestUtils {/*** 测试个人博客管理页面是否完整*/@Order(1)@ParameterizedTest@CsvSource({"张三,123"})void blogListPageTest(String username, String password) throws InterruptedException {//1.登录webDriver.get("http://localhost:8080/login.html");webDriver.findElement(By.cssSelector("#username")).clear();webDriver.findElement(By.cssSelector("#password")).clear();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//找到输入框,输入账号,密码webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);//点击提交按钮webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#submit")).click();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);sleep(500);//2.测试个人博客管理页面标题String title = webDriver.getTitle();System.out.println(title);Assertions.assertEquals("个人博客列表管理页",title);//3.查看全文按钮,修改按钮,删除按钮是否正常webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);WebElement check_button = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(4)"));WebElement update_button = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(5)"));WebElement delete_button = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(6)"));Assertions.assertNotNull(check_button);Assertions.assertNotNull(update_button);Assertions.assertNotNull(delete_button);}/*** 测试个人博客管理页的* 查看按钮,编辑按钮,删除按钮*/@Order(2)@Testvoid blogListTest() {webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);//1.校验查看全文,点击按钮,进入文章详情页webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(4)")).click();//2.校验是否到文章详细页urlString content_url = webDriver.getCurrentUrl();String expect_url = "http://localhost:8080/blog_content.html";if(content_url.contains(expect_url)) {System.out.println("查看按钮测试通过!");}else {System.out.println("查看按钮测试不通过!");}webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.navigate().back();//2.校验修改文章按钮,点击按钮,进入编辑页webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(5)")).click();//3.校验是否是编辑页的urlString edit_url = webDriver.getCurrentUrl();String expect_url2 = "http://localhost:8080/blog_edit.html";if(edit_url.contains(expect_url2)) {System.out.println("编辑按钮测试通过!");}else {System.out.println("编辑按钮不通过!");}webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.navigate().back();//4.校验删除按钮,点击按钮,删除文章webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a:nth-child(6)")).click();//5.弹窗显示删除成功,点击确认webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);Alert alert = webDriver.switchTo().alert();System.out.println(alert.getText());alert.accept();//6.校验此时第一篇标题webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);String title_text = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > div.title")).getText();Assertions.assertNotEquals("java",title_text);}/*** 测试未登录状态,博客管理页*/@Disabled // 设置无效,不随整体执行,作为单个测试样例@Testvoid unLoginBlogList() {webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);//1.直接进入个人博客管理页webDriver.get("http://localhost:8080/myblog_list.html");//2.弹窗显示,登录之后再查看Alert alert = webDriver.switchTo().alert();System.out.println(alert.getText());alert.accept();//3.校验是否回到登录页webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);String login_url = webDriver.getCurrentUrl();Assertions.assertEquals("http://localhost:8080/login.html",login_url);}}
测试结果:
4.博客编辑页自动化测试
- 博客编辑页自动化测试 - BlogEditTest
1.校验编辑页面的完整性 - 发布按钮是否存在
2.校验发布成功后,是否能跳转到个人列表管理页
博客编辑页出现的Bug
- 获取文章标题,使用getText()获取文本,可能获取不到,获取到空字符串,造成断言失败,可以使用getTitle();
package webAutoTest.TestClass;import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import webAutoTest.common.AutoTestUtils;import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class BlogEditTest extends AutoTestUtils {/*** 测试编辑页的完整性*/@Order(1)@ParameterizedTest@CsvSource("张三,123")void blogEditPageTest(String username, String password) throws InterruptedException {//1.登录webDriver.get("http://localhost:8080/login.html");webDriver.findElement(By.cssSelector("#username")).clear();webDriver.findElement(By.cssSelector("#password")).clear();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//找到输入框,输入账号,密码webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);//点击提交按钮webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#submit")).click();sleep(500);//2.点击写博客webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();//3.当前是否到博客编辑页webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);String edit_url = webDriver.getCurrentUrl();Assertions.assertEquals("http://localhost:8080/blog_add.html",edit_url);//4.校验发布文章按钮是否存在WebElement webElement = webDriver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button"));Assertions.assertNotNull(webElement);}/*** 测试文章发布,发布后是否成功跳转* @throws InterruptedException*/@Order(2)@Testvoid blogEditTest() throws InterruptedException {webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);//1.输入标题webDriver.findElement(By.cssSelector("#title")).sendKeys("测试实战2");//2.输入正文 - 第三方插件,不能使用sendkeywebDriver.findElement(By.cssSelector("#editorDiv > div.CodeMirror.cm-s-default.CodeMirror-wrap > div.CodeMirror-scroll")).click();//3.点击发布按钮webDriver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();//4.发布成功,出现弹窗,显示是否继续发布,点击取消sleep(500);Alert alert = webDriver.switchTo().alert();webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);System.out.println(alert.getText());alert.dismiss();//5.校验跳转页面,到个人博客列表管理页webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);String currentUrl = webDriver.getCurrentUrl();Assertions.assertEquals("http://localhost:8080/myblog_list.html",currentUrl);//6.校验发布的文章的标题String text = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > div.title")).getText();Assertions.assertEquals("测试实战2",text);}
}
测试结果:
5.总博客列表页自动化测试
- 总博客列表页自动化测试 - TotalBlogListTest
1.校验总博客列表页完整 - 首页,上一页,下一页,末页按钮存在
2.校验在第一页点击首页,处理弹窗
3.校验在最后一页,点击末页,处理弹窗
4.未登录,查看总博客列表页功能正常
package webAutoTest.TestClass;import org.junit.jupiter.api.*;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import webAutoTest.common.AutoTestUtils;import java.util.concurrent.TimeUnit;import static java.lang.Thread.sleep;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class TotalBlogListTest extends AutoTestUtils {/*** 测试总博客列表页是否正常* 校验首页,上一页,下一页,末页*/@Order(1)@ParameterizedTest@CsvSource({"张三,123"})void totalPageTest(String username,String password) throws InterruptedException {//1.登录webDriver.get("http://localhost:8080/login.html");webDriver.findElement(By.cssSelector("#username")).clear();webDriver.findElement(By.cssSelector("#password")).clear();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);//找到输入框,输入账号,密码webDriver.findElement(By.cssSelector("#username")).sendKeys(username);webDriver.findElement(By.cssSelector("#password")).sendKeys(password);//点击提交按钮webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#submit")).click();webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);sleep(200);//2.点击主页webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)")).click();webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);//2.校验总列表页是否正常,校验首页,上一页,下一页,末页WebElement first_button = webDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(1)"));WebElement prev_page_button = webDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(2)"));WebElement next_page_button = webDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(3)"));WebElement last_button = webDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(4)"));Assertions.assertNotNull(first_button);Assertions.assertNotNull(prev_page_button);Assertions.assertNotNull(next_page_button);Assertions.assertNotNull(last_button);}@Order(2)@Testvoid totalBlogListTest() throws InterruptedException {//1.点击首页webDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(1)")).click();//2.出现弹窗,显示已在首页,点击确认sleep(200);Alert alert = webDriver.switchTo().alert();System.out.println(alert.getText());alert.accept();//3.点击下一页,校验urlwebDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(3)")).click();String currentUrl = webDriver.getCurrentUrl();char intdex = currentUrl.charAt(currentUrl.length() - 1);Assertions.assertEquals("2",intdex+"");//4.点击两次末页,校验webDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(4)")).click();webDriver.findElement(By.cssSelector("body > div.container > div > div.blog-pagnation-wrapper > button:nth-child(4)")).click();sleep(200);Alert alert1 = webDriver.switchTo().alert();System.out.println(alert1.getText());alert1.accept();//5.点击查看全文,可以跳转到文章详情页webDriver.manage().timeouts().implicitlyWait(3,TimeUnit.SECONDS);webDriver.findElement(By.cssSelector("#artListDiv > div > a")).click();String content_url = webDriver.getCurrentUrl();if(content_url.contains("http://localhost:8080/blog_content.html")) {System.out.println("查看文章按钮通过!");}else {System.out.println("查看文章按钮失败!");}}/*** 未登录,查看总博客列表页* @throws InterruptedException*/@Disabled@Order(3)@Testvoid unLoginTotalBlogListTest() {//1.获取总博客列表页webDriver.get("http://localhost:8080/blog_list.html");//2.文章列表中第一篇文章显示正常String content_title = webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > div.title")).getText();Assertions.assertEquals("测试实战2",content_title);//利用断言验证//3.点击文章,可以查看文章详情webDriver.findElement(By.cssSelector("#artListDiv > div:nth-child(1) > a")).click();String content_url = webDriver.getCurrentUrl();//4.校验文章详情页urlif(content_url.contains("http://localhost:8080/blog_content.html")) {System.out.println("查看文章按钮通过!");}else {System.out.println("查看文章按钮失败!");}}
}
测试结果:
未登录查看总博客列表页
6.测试套件 - RunSuiteTest
- 测试套件 - RunSuiteTest
- 通过套件,以测试类运行,也可写多个测试类,会按照顺序执行
package webAutoTest.TestClass;import org.junit.platform.suite.api.SelectClasses;
import org.junit.platform.suite.api.Suite;@Suite
@SelectClasses({LoginTest.class})
public class RunSuiteTest {
}
测试结果:
三、小结
注意:
- 需要注意测试的执行顺序,不关注可能报错
- 对于多参数测试,需要清空上次输入数据,页面回退
- 使用@SelectClasses的参数指定执行类的顺序
- 测试用例并不是越多越好,覆盖较多功能较好
- 测试功能会有遗漏的情况,对于测试用例执行顺序会有错误情况;
测试优势:
1.使用Junit5单元测试框架中的注释:提高测试的稳定性,提高自动化执行效率;(指定执行测试顺序,指定参数)
2.根据个人博客设计的手工测试用例,对每个测试用例的常用功能实现自动化测试
3.使用工具类每次测试都需要驱动,写一个公共类,实现代码复用
4.使用测试套件,降低测试人员的工作量
5.使用等待:提高自动化运行效率,提高自动化的稳定性,减小误报的可能性
参考代码
点击查看,自动化测试源代码
总结
✨✨✨各位读友,本篇分享到内容如果对你有帮助给个👍赞鼓励一下吧!!
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!!
相关文章:

自动化实战 - 测试个人博客系统
前言 本篇使用Selenium3Junit5对个人博客进行自动化测试,如有错误,请在评论区指正,让我们一起交流,共同进步! 文章目录 前言一.web自动化测试用例二.测试准备1.注册界面自动化测试测试过程中遇到的Bug: 2.登录界面自动…...

TCP/IP详解
TCP/IP详解 一、网络基础1.TCP/IP网络分层2.IP地址和端口号3.封装与分用4.客户-服务端模型 二、链路层1.以太网IEEE802封装2.环回接口 Loopback Interface3.最大传输单元MTU和路径MTU 三、网络层 - IP1.IP首部的关键信息2.IP路由选择3.子网寻址和子网掩码4.ICMP和IGMP 四、传输…...

2023年的低代码:数字化、人工智能、趋势及未来展望
前言 正如许多专家预测的那样,低代码平台在2023年将展现更加强劲的势头。越来越多的企业正在纷纷转向低代码开发,他们希望能够快速开发内部应用程序,并在经济衰退可能出现的情况下保持灵活性。在这个大背景下,低代码平台为企业软件…...

【gogogo专栏】golang并发编程
golang并发编程 并发编程的工具goroutine介绍协程管理器sync.WaitGroup channel介绍readChannel和writeChannelclose的用法select的用法 通讯示例总结 并发编程的工具 在golang中,并发编程是比较简单的,不像java中那么麻烦,golang天然的支持协…...

深入理解JVM虚拟机第二十二篇:详解JVM当中与操作数栈相关的字节码指令
大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。 孙哥链接:孙哥个人主页 作者简介:一个颜值99分,只比孙哥差一点的程序员 本专栏简介:话不多说,让我们一起干翻J…...
Vue报错解决Error in v-on handler: “Error: 无效的节点选择器:#div1“
因为我们在创建元素之前用了#div1"所有它会报错,解决方案简单粗暴咱们直接用 setTimeout(createEdit, 1)解决问题了 原理:vue的虚拟dom创建完成以后再调用真是dom就没啥问题 function createEdit() {const editor new E(#div1)editor.config.hei…...

R | R包安装报错-github连接速度慢或无法访问 | metaboanalystR | Retip | rJava安装
R | R包安装报错-github连接速度慢或无法访问 | metaboanalystR | Retip | rJava安装 一、metaboanalystR 安装1.1 Bioconductor报错,无网络连接1.2 github520-修改hosts文件 二、retip安装2.1 rJava包加载报错及安装2.2 安装Retip包 三、从Bioconductor安装Rdisop报…...

博阳精讯、凡得科技访问上海斯歌:共探BPM流程服务新高地
10月27日下午,来自博阳精讯、凡得科技的流程领域专家、领导一行参观访问了上海斯歌总部。三方举行了深度交流会谈,分享了彼此对流程领域的前沿洞察和技术实践,共同探索了BPM流程服务科技力与价值力的新高地。 本次研讨会上,博阳精…...

响应式艺术作品展示前端html网站模板源码
响应式艺术作品展示网站模板是一款适合各种艺术作品在线展示的响应式网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。 转载自 https://www.qnziyw.cn/wysc/qdmb/23778.html...

大语言模型(LLM)综述(六):大型语言模型的基准和评估
A Survey of Large Language Models 前言7 CAPACITY AND EVALUATION7.1 基本能力7.1.1 语言生成7.1.2 知识利用7.1.3 复杂推理 7.2 高级能力7.2.1 人类对齐7.2.2 与外部环境的交互7.2.3 工具操作 7.3 基准和评估方法7.3.1 综合评价基准7.3.2 评估方法 7.4 实证评估7.4.1 实验设…...

【Python自学笔记】Flask调教方法Internel Server Error
收到老师的小组作业任务说是写一个自动报告程序,用PythonSQLiteHTML实现,好吧。 前面没什么问题,打开VSCode,连数据库读数据处理可视化模板拼凑,最后调用Flask框架出网页报告的时候总报错连接不了。 但换了jinjia2的渲…...

【AICFD案例教程】汽车外气动-AI加速
AICFD是由天洑软件自主研发的通用智能热流体仿真软件,用于高效解决能源动力、船舶海洋、电子设备和车辆运载等领域复杂的流动和传热问题。软件涵盖了从建模、仿真到结果处理完整仿真分析流程,帮助工业企业建立设计、仿真和优化相结合的一体化流程&#x…...

P1547 [USACO05MAR] Out of Hay S 题解
文章目录 题目描述输入格式输出格式样例样例输入样例输出 完整代码 题目描述 Bessie 计划调查 N N N( 2 ≤ N ≤ 2 000 2 \leq N \leq 2\,000 2≤N≤2000)个农场的干草情况,它从 1 1 1 号农场出发。农场之间总共有 M M M( 1 ≤…...

2023.11.10联测总结
T 1 T1 T1求的是有多少个区间的异或和是 k k k的因子, n , k ≤ 1 0 5 n,k \leq 10^5 n,k≤105。 这道题用前缀和维护一下,暴力枚举所有区间就有 80 80 80分。 有一瞬间想过枚举因数,但是脑抽以为要 O ( n ) \mathcal O(n) O(n)枚举&#x…...
C++:list?自己模拟实现!
目录 1.list的模拟实现 1.1 成员变量和节点 1.2 迭代器实现 1.2.1 非const的迭代器 1.2.2 const的迭代器 1.2.3 一个模板实现 const 与 非const 迭代器 1.3 增删改查的实现 1.4 拷贝构造函数,析构函数与赋值运算符重载 1.5 泛型编程实现打印 2. list 反…...

layui table合并相同的列
table.render({elem: #samples,url: /index/Develorderss/samplelists?od_idod_id //数据接口,page: { //支持传入 laypage 组件的所有参数(某些参数除外,如:jump/elem) - 详见文档layout: [prev, page, next, count,skip,limit]…...

【Spring】SpringBoot配置文件
SpringBoot配置文件 配置文件作用SpringBoot配置文件配置文件快速入手配置文件的格式properties配置文件说明基本语法读取配置文件properties缺点分析 yml配置文件说明yml基本语法yml使用进阶yml配置读取配置对象配置集合配置Mapyml优缺点 配置文件作用 计算机上有数以千计的配…...
python批量下载txt文件中链接的数据
python下载txt文件中链接的数据,以gimms ndvi3g下载为例 官方下载网址:https://www.ncei.noaa.gov/data/land-normalized-difference-vegetation-index/access/ 选择下载2020年数据为例: 网址:Index of /data/land-normalized-difference-vegetation-index/access/2020…...

stm32 Bootloader设计(YModem协议)
stm32 Bootloader设计(YModem协议) Chapter1 stm32 Bootloader设计(YModem协议)YModem协议:STM32 Bootloader软件设计STM32 Bootloader使用方法准备工作stm32 Bootloader修改:stm32目标板程序.bin偏移地址修改: Chapt…...

竞赛 题目: 基于深度学习的疲劳驾驶检测 深度学习
文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 🔥 优…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...

AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...

tauri项目,如何在rust端读取电脑环境变量
如果想在前端通过调用来获取环境变量的值,可以通过标准的依赖: std::env::var(name).ok() 想在前端通过调用来获取,可以写一个command函数: #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
高防服务器价格高原因分析
高防服务器的价格较高,主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因: 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器,因此…...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...