前言
本篇文章是对之前做过的博客系统进行测试用例的编写,并使用Selenium4自动测试工具和Junit5单元测试框架结合对博客系统的测试用例进行代码编写。
一、博客系统的测试用例编写
该博客系统共包含四个页面,登录、列表、详情、编辑页面,具体细节与实现可参考前面博客系统的文章。
二、自动化测试
创建驱动是测试的公共部分,则可以放在一个类里,再创建登录页面、登录列表页面、登录详情页面、登录编辑页面测试类,最后创建一个套件可以选择要测试的类。
AutotestUtils类中包括创建去对对象和保存执行测试过程中截图的方法。
//1.创建驱动对象
public static ChromeDriver createDriver() {
if (driver == null) {
driver = new ChromeDriver();
//创建隐式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}
return driver;
}
//通过格式化时间戳来动态的获取截图名
public List<String> getTime() {
//文件格式 20230307-225600
SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyyMMdd-HHmmssSS");
SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat("yyyyMMdd");
String fileName = simpleDateFormat1.format(System.currentTimeMillis());
String dirName = simpleDateFormat2.format(System.currentTimeMillis());
List<String > list = new ArrayList<>();
list.add(dirName);
list.add(fileName);
return list;
}
/**
* 获取屏幕截图,把所有的用例执行的结果保存下来
*/
public void getScreenShot(String str) throws IOException {
List<String> list = getTime();
//dir+fileName
String fileName = "./src/test/java/com/blogWebAutoTest/"+list.get(0)+"/"+str+"_"+list.get(1)+".png";
File srcFile = driver.getScreenshotAs(OutputType.FILE);
//把屏幕截图生成的文件放到指定的路径
FileUtils.copyFile(srcFile,new File(fileName));
}
1.博客登录页面测试
根据测试用例进行编写。
主要用到技术测试套件@Suite,组织获取URL,登录成功/失败,关闭资源的顺序。
注意:设置多组数据进行登录时(用到@CsvSource),需要先清空登录框中的数据。
BlogLoginTest
//调用AutotestUtils中的createDriver
private static ChromeDriver driver = createDriver();
//测试登录页面的一些共同步骤
//1.获取浏览器对象
//2.访问登录页面的URL
@BeforeAll
public static void baseControl() {
driver.get("http://121.4.74.140:8080/blogSystem2/blog_login.html");
}
/**
* 检查登录页面打开是否正确
* 检查点:主页 写博客 元素是否存在
*/
@Test
@Order(1)
public void loginPageLoadRight() {
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
}
/**
*检查正常登录是否成功
*/
//@ParameterizedTest
@CsvSource({
"张三,123","王一,123"})
@Order(3)
public void loginSuccess(String name,String password) {
//清空登录框,以防多组登录
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
//进行登录
driver.findElement(By.cssSelector("#username")).sendKeys(name);
driver.findElement(By.cssSelector("#password")).sendKeys(password);
driver.findElement(By.cssSelector("#login-button")).click();
//如果跳转到博客列表页,才算登录成功
driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(1) > div.date"));
driver.navigate().back();
}
/**
* 登录失败检测
*/
@ParameterizedTest
@CsvSource({
"张三,1234"})
@Order(2)
public void loginFail(String name,String password) {
//清空登录框,以防多组登录
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
//进行登录
driver.findElement(By.cssSelector("#username")).sendKeys(name);
driver.findElement(By.cssSelector("#password")).sendKeys(password);
driver.findElement(By.cssSelector("#login-button")).click();
//登录失败情况
String expect = "用户未注册或用户名密码错误!登录失败!";
String actual = driver.findElement(By.cssSelector("body")).getText();
Assertions.assertEquals(expect,actual);
}
2.博客列表页面测试
登录成功后进入博客列表页面,通过查看列表页面是否存在某些元素来检查博客列表页面是否正常显示。
BlogListTest:
/**
* 登录列表页面可以正常显示
*/
@Test
public void listPageLoadRight() throws IOException {
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));
getScreenShot(getClass().getName());
}
3.博客编辑页面测试
在博客编写页面:
首先,需要博客编写页面是否正常显示,和博客列表页面一样通过检查某些特定元素是否存在判定博客编写页面是否正常显示;
其次,检查博客编辑提交是否正常,通过发布一篇博客,编写博客的时候由于博客编辑用的是第三方插件,所以不能直接用sendKeys,通过点击某些元素进行编辑;
最后,发布博客后,通过最新博客的标题与编辑博客时候的标题进行比较,相等则博客发布成功。
BlogEditTest
/**
* 检查编辑页面可以正常打开
*/
@Test
@Order(1)
public void editPageLoadRight() throws IOException {
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)"));
driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));
getScreenShot(getClass().getName());
}
/**
* 检查编写博客页面可以正常编写提交
*/
@Test
@Order(2)
public void editAndSubmitBlog() throws IOException {
String expect = "测试博客可以编写并提交";
driver.findElement(By.cssSelector("#blog-title")).sendKeys(expect);
//因为博客系统使用的是第三方软件,所以不能直接使用sendKeys
driver.findElement(By.cssSelector("#editor > div.editormd-toolbar > div > ul > li:nth-child(17) > a > i")).click();
driver.findElement(By.cssSelector("#submit")).click();
getScreenShot(getClass().getName());
//获取最后一条博客的标题文本,检查是否和预期一样
String actual = driver.findElement(By.cssSelector("body > div.container > div.container-right > div:nth-child(5) > div.title")).getText();
Assertions.assertEquals(expect,actual);
}
4.博客详情页面测试
详情页测试和列表页测试时类似的,只是检测时选中的元素可能不同。。
@Test
public void detailPageLoadRight() throws IOException {
driver.findElement(By.cssSelector("body > div.container > div.container-right > div > h3"));
driver.findElement(By.cssSelector("body > div.container > div.container-right > div > div.date"));
getScreenShot(getClass().getName());
}
@AfterAll
public static void driverQuit() {
driver.quit();
}
以防将驱动释放忘记,直接将驱动释放写成一个测试类
QuitDriverTest
public class QuitDriverTest extends AutotestUtils {
private static ChromeDriver driver = createDriver();
@Test
public void quitDriver() {
driver.quit();
}
}
总结
该博客系统的测试代码的亮点:
(1)使用Junit5提供的注解:避免生成过多的对象,造成资源和时间的浪费,提高了自动化的执行效率。
(2)只创建了一次驱动对象,避免每个用例重复创建驱动对象造成时间和资源的浪费。
(3)使用参数化:保持用例的简洁,提高代码的可读性。
(4)使用测试套件:降低了测试人员的工作量,通过套件一次执行所有的测试用例。
(5)使用了等待:提高了自动化运行效率,提高了自动化的稳定性。
(6)屏幕截图:方便问题的追溯以及问题的解决。