项目概要:基于ssm项目的博客系统测试
项目相关技术栈:SpringBoot
, SpringMVC
,MyBatis
, MySQL
, Redis
, HTML
, CSS
, JavaScript
测试报告的目的:测试自己的博客项目是否符合预期结果.
范围和日期:2023年10月
测试执行的总体情况:主要针对常见功能进行测试例如:博客登录页面,博客列表页面,博客详情页,博客编辑页…
项目背景:巩固所学自动化测试相关知识.
测试目标:基于Servlet实现的博客系统.
测试策略进行说明:按照用户一般登录的逻辑编写测试用例并进行测试.
阐述测试的目的和重点:查缺补漏.
硬件:XiaoXinAir 14ALC 2021
软件:Google Chrome
开发工具:IDEA
测试工具:自动化测试工具Selenium
操作系统:Windows 10家庭中文版
浏览器版本:Google Chrome 117.0.5938.134(正式版本)(64 位)
博客登录页:
博客注册页:
个人博客列表页:
博客主页:
博客详情页:
博客编辑页:
由于随着项目版本的迭代,功能的逐渐增多,各种功能回归测试的需要,单纯的手工测试已经难以满足我们对于测试效率的要求,于是我们引入了自动化测试。它能够将人工从重复机械的测试过程中解放,使得人力资源能够投入到更加关键的测试中。
(包含截图测试):AutotestUtils
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class AutotestUtils {
static WebDriver webDriver;
@BeforeAll
static void SetUp() {
webDriver = new ChromeDriver();
}
@AfterAll
static void TearDown() {
webDriver.quit();
}
//获取当前时间将截图按照时间保存
public List<String> getTime(){
//文件夹以天保存
//截图以毫秒时间戳保存
SimpleDateFormat sim1=new SimpleDateFormat("yyyyMMdd-HHmmssSS");
SimpleDateFormat sim2 = new SimpleDateFormat("yyyyMMdd");
String filename=sim1.format(System.currentTimeMillis());
String dirname=sim2.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();
String filename="E:\\TestClass\\blog_ssm_test\\src\\main\\java\\com\\blogautotest"+list.get(0)+"\\"+str+"_"+list.get(1)+".png";
File srcfile=((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
//把屏幕截图生成的文件放到指定的路径
FileUtils.copyFile(srcfile,new File(filename));
}
}
LoginCases
:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.openqa.selenium.By;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
public class BlogCases extends AutotestUtils{
static String name;
/**
*
* 输入正确的账号,密码登录成功
*/
@Order(1)
@ParameterizedTest
@CsvFileSource(resources = "LoginSuccess.csv")
void LoginSuccess(String username, String password, String blog_list_url) throws IOException {
System.out.println(username + password + blog_list_url);
// 打开博客登录页面
webDriver.get("http://localhost:8080/login.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入账号zhangsan
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 输入密码12345
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);
// 跳转到列表页
// 获取到当前页面url
String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();
getScreenShot(methodName);
String cur_url = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 如果url=http://localhost:8080/myblog_list.html,测试通过,否则测试不通过
Assertions.assertEquals(blog_list_url, cur_url);
}
// 账号正确,密码错误
@Order(2)
@ParameterizedTest
@CsvSource({"admin,123","zhangsan,666"})
void LoginAbnormal(String username,String password) throws InterruptedException {
webDriver.get("http://localhost:8080/login.html");
webDriver.findElement(By.cssSelector("#username")).clear();
webDriver.findElement(By.cssSelector("#password")).clear();
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.findElement(By.cssSelector("#submit")).click();
//处理弹窗
Thread.sleep(300);
//获取弹窗内容
String text=webDriver.switchTo().alert().getText();
String except="登陆成功!";
webDriver.switchTo().alert().accept();
Assertions.assertNotEquals(except,text);
}
}
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.openqa.selenium.By;
import java.util.concurrent.TimeUnit;
import static java.lang.Thread.sleep;
public class RegCases extends AutotestUtils{
@Order(1)
@ParameterizedTest
@CsvSource({"zhangsan,12345,12345,http://localhost:8080/login.html"})
void regSuccess(String username,String password,String againpassword,String login_url) throws InterruptedException {
//打开主页
webDriver.get("http://localhost:8080/login.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//找到注册按钮并点击
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//输入注册的用户名,密码
webDriver.findElement(By.cssSelector("#username")).sendKeys(username);
webDriver.findElement(By.cssSelector("#password")).sendKeys(password);
webDriver.findElement(By.cssSelector("#password2")).sendKeys(againpassword);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
//点击提交
webDriver.findElement(By.cssSelector("#submit")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
}
}
/**
* 博客详情页校验
* url
* 博客标题
* 页面title是“博客详情页”
*/
@Order(4)
@ParameterizedTest
@MethodSource("Generator")
void BlogDetail(String expected_url, String expected_title, String expected_blog_title) {
// 打开博客列表页
webDriver.get("http://localhost:8080/myblog_list.html");
// 找到第一篇博客对应的产看全文按钮
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
webDriver.findElement(By.cssSelector("#artlist > div:nth-child(1) > a:nth-child(4)")).click();
// 获取当前页面url
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
String cur_url = webDriver.getCurrentUrl();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 获取当前页面title
String cur_title = webDriver.getTitle();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 获取博客标题
String cur_blog_title = webDriver.findElement(By.cssSelector("#title")).getText();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
Assertions.assertEquals(expected_title ,cur_title);
Assertions.assertEquals(expected_blog_title, cur_blog_title);
if(cur_url.contains(expected_url)) {
System.out.println("测试通过");
} else {
System.out.println(cur_url);
System.out.println("测试不通过");
}
}
//博客编辑页
@Order(5)
@Test
void EditBlog() throws InterruptedException {
// 打开博客列表页
webDriver.get("http://localhost:8080/myblog_list.html");
// 找到写博客按钮,点击
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 通过Js进行输入
((JavascriptExecutor)webDriver).executeScript("document.getElementById(\"title\").value=\"自动化测试\"");
sleep(3000);
// 点击发布
webDriver.findElement(By.cssSelector("body > div.blog-edit-container > div.title > button")).click();
sleep(3000);
String cur_text = webDriver.switchTo().alert().getText();
String expect_text = "恭喜:添加成功!是否继续添加文章?";
Assertions.assertEquals(expect_text,cur_text);
}
/**
* 校验已发布博客标题
* 校验已发布博客时间
* 博客列表页
*/
@Order(6)
@Test
void BlogInfoChecked() {
webDriver.switchTo().alert().dismiss();
webDriver.get("http://localhost:8080/blog_list.html");
// 获取第一篇博客标题
String first_blog_title = webDriver.findElement(By.cssSelector("#artlist > div:nth-child(1) > div.title")).getText();
// 获取第一篇博客发布时间
String first_blog_time = webDriver.findElement(By.xpath("//*[@id=\"artlist\"]/div[1]/div[2]")).getText();
// 校验博客标题是不是自动化测试
Assertions.assertEquals("自动化测试", first_blog_title);
// 如果时间是2023-5-23年发布的,测试通过
if(first_blog_title.contains("2023-10")) {
System.out.println("测试通过");
} else {
System.out.println("当前时间是:" + first_blog_time);
System.out.println("测试不通过");
}
}
删除功能:
/**
* 个人列表页
* 删除第一篇博客
*/
@Order(7)
@Test
void DeleteBlog() throws InterruptedException {
// 打开个人博客列表页面
webDriver.get("http://localhost:8080/myblog_list.html");
// 点击删除按钮
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
webDriver.findElement(By.cssSelector("#artlist > div:nth-child(1) > a:nth-child(6)")).click();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
webDriver.switchTo().alert().accept();
}
//注销
@Order(8)
@Test
void Logout() {
webDriver.switchTo().alert().accept();
// 打开个人博客列表页面
//点击注销
webDriver.get("http://localhost:8080/myblog_list.html");
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
webDriver.switchTo().alert().accept();
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
// 校验url 注销后进入博客列表页
String cur_url = webDriver.getCurrentUrl();
Assertions.assertEquals("http://localhost:8080/blog_list.html", cur_url);
webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);
}
测试通过.其中博客详情页被忽略是因为和博客删除页有(业务逻辑)冲突.并不影响测试结果.单独测试详情页是通过的.
除上述描述之外,一份完整的测试报告还包含以下方面等:
此处我们不做过多阐述.到公司后熟悉即可.同时,在编写测试报告时,需要注意以下几点: