目录
该篇文章是我测试学习过程中的总结
1 项目背景
因为我经常在csdn上写博客, 那么我在学习Spring Boot之后呢?想着自己是自己是不是能够做一些什么东西,就想到自己做一个博客系统吧,于是你现在看到的这个博客系统就应运而生了。
2 项目功能
1. 登录功能
2. 博客列表页功能
3. 写博客并发布博客功能
4. 删除博客功能
5. 注销退出功能
3 项目测试
本次测试对博客系统主要使用selenium工具进行UI界面自动化测试,进行功能测试,对于界面测试、易用性测试、兼容性测试等其他测试仅做简单描述。
3.1 测试用例
3.2 登录页面测试
测试场景一:输入正确的用户名和密码点击提交
预期结果:登录成功,跳转到博客首页
实际结果:与预期结果一致。登录成功,跳转到博客首页
测试场景二:输入正确的用户名和错误的密码
预测结果:弹窗提示密码错误
实际结果:与预期结果一致。弹窗提示密码错误
测试场景三:输入错误的用户名和正确的密码
预期结果:弹窗提示用户不存在
实际结果:与预期结果一致。弹窗提示用户不存在
测试场景四:输入错误的用户名和错误的密码
预期结果:弹窗提示用户名不存在
实际结果:与预期结果一致。弹窗提示用户不存在
3.3 博客列表页面测试
测试场景一: 点击菜单栏的“写博客”
预期结果:页面跳转到博客编辑页,用户可以编写博客
实际结果:与预期结果一致。页面正常跳转到编辑页面
测试用例二:输入标题和内容,点击“发布文章”按钮可正常发布博客,在博客首页查看到。
预期结果:成功发布博客,在首页可看到发布的博客。
实际结果:与预期结果一致。可查看到发布的博客。
测试场景三: 点击首页的任意一个博客下方的“查看全文”
预期结果:页面跳转到博客详情页,可查看博客内容
实际结果:与预期结果一致。页面正常跳转到博客详情界面。
测试场景四: 点击菜单栏的“注销”
预期结果:页面跳转到登录界面,用户名和密码被清空,用户可重新登录。
实际结果:与预期结果一致。页面正常跳转到登录界面。
3.4 博客详情页面测试
测试用例一:点击“编辑”按钮
预期结果:进入博客更新页面,可对之前的内容进行编辑,编辑完成后点击更新文章,可在首页看到更新后的文章。
实际结果:与预期结果一致。更新内容后可在首页查看到更新后的博客。
测试用例二:点击“删除”按钮
预期结果:博客被成功删除,在首页找不到此博客。
实际结果:与预期结果一致。且弹窗提示用户确定删除。
测试用例三:在lisi的账号下,我们可以看到是无法编辑和删除zhangsan用户发布的这篇博客的,在zhangsan账号下可正常操作。
3.5 自动化测试
先将一些每个页面所需要的工具放到一个类里。
3.5.1 Utils类
package common;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
public class Utils {
public static WebDriver driver;
public static WebDriver createDriver(){
if(driver == null){
WebDriverManager.chromedriver().setup();
ChromeOptions options = new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
driver = new ChromeDriver(options);
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
driver.manage().window().maximize();
}
return driver;
}
public Utils(String url) {
if(url != ""){
driver = createDriver();
driver.get(url);
}
}
public void getScreenShot(String str) throws IOException {
// ./src/test/image/
// /2024-07-17/
// /test01-17453010.png
// /test02-17453020.png
// /2024-07-18/
// /test01-17453030.png
// /test02-17453034.png
//屏幕截图
SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");
String dirTime = sim1.format(System.currentTimeMillis());
String fileTime = sim2.format(System.currentTimeMillis());
//./src/test/image/2024-07-17/test01-17453020.png
String filename ="./src/test/image/"+ dirTime +"/" + str + "-" + fileTime+".png";
File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
//srcFile放到指定位置
FileUtils.copyFile(srcFile,new File(filename));
}
}
3.5.2 登录测试页面类
package tests;
import common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LoginPage extends Utils {
public static String url = "http://123.60.62.52:9090/blog_login.html";
public LoginPage() {
super(url);
}
/**
* 检查页面是否可以正常打开
*/
public void loginPageRight() {
//通过检查页面元素是否存在来检查页面是否加载成功
//检查提交按钮是否存在
driver.findElement(By.cssSelector("#submit"));
//检查输入框中登录这两个字是否存在
driver.findElement(By.cssSelector("body > div.container-login > div > h3"));
//检查页面中 我的博客系统是否存在
driver.findElement(By.cssSelector("body > div.nav > span"));
}
/**
* 进行登录测试---正常登录
*/
public void loginSuc() {
driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");
driver.findElement(By.cssSelector("#password")).sendKeys("123456");
driver.findElement(By.cssSelector("#submit")).click();
// 如何判断此时登录成功, 此时登陆成功的界面是和上述页面正常加载是不一样的
// 如果此时可以点击查看全文 就说明此时是正常登陆的
try{
Thread.sleep(3000);
}catch (Exception e){
e.printStackTrace();
}
driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")); //你也没点呢
// String title= driver.getTitle();
// assert title.equals("博客列表");
//driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
}
/**
* 进行登录测试---异常登录
* 由于在tests中各项测试是有依赖的
* 在测试异常登录之前 已经登陆过了 而我们的`drive对象并没有释放掉 并没使用这段 driver.quit();
* 进入到博客列表页是获取不到错误弹窗的
* 所以要在上述正常登录测试之后 让其返回到前一步
* 但是返回之后 账号密码都在输入框内
* 此时我们直接输入的内容 只是拼接在输入框的内容
* 所以要先进行清空
*/
public void loginFail() throws InterruptedException {
//方法1
/*driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();*/
//方法2 浏览器刷新
driver.navigate().refresh();
driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");
driver.findElement(By.cssSelector("#password")).sendKeys("123456111");
driver.findElement(By.cssSelector("#submit")).click();
Thread.sleep(3000);
Alert alert = driver.switchTo().alert();
alert.accept();
}
}
3.5.3 博客列表页测试类
package tests;
import common.Utils;
import org.openqa.selenium.By;
public class ListPage extends Utils {
public static String url = "http://123.60.62.52:9090/blog_list.html";
public ListPage() {
super(url);
}
/**
* 登录状态下 博客列表页测试
*/
public void ListPageByLogin() throws InterruptedException {
driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(2) > div.title"));
driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(2) > div.date"));
Thread.sleep(3000);
driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();
Thread.sleep(3000);
}
}
3.5.4 博客详情页测试类
package tests;
import common.Utils;
import org.openqa.selenium.By;
import java.io.IOException;
public class DetailPage extends Utils {
public static String url = "";
public DetailPage() {
super(url);
}
public void DetailPageByLogin() throws InterruptedException, IOException {
// Thread.sleep(2000);
// getScreenShot(getClass().getName());
Thread.sleep(3000);
driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(2)"));
driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(1)")).click();
}
}
3.5.5 博客修改页测试类
package tests;
import common.Utils;
import org.openqa.selenium.By;
public class UpdatePage extends Utils {
public static String url = "";
public UpdatePage() {
super(url);
}
public void UpdatePageByLogin() throws InterruptedException {
Thread.sleep(3000);
driver.findElement(By.cssSelector("#title")).sendKeys("iajrfiojwqe");
driver.findElement(By.cssSelector("#submit")).click();
}
}
3.5.6 未登录情况下测试类
package tests;
import common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import java.io.IOException;
public class PageByNoLogin extends Utils {
public static String listUrl = "http://123.60.62.52:9090/blog_list.html";
public static String editUrl = "http://123.60.62.52:9090/blog_edit.html";
public static String detailUrl = "http://123.60.62.52:9090/blog_detail.html";
public PageByNoLogin() {
super("");
}
/**
* 异常登陆测试
*/
/**
* 列表页未登录测试
*/
public void ListByNoLogin() throws InterruptedException, IOException {
driver.get(listUrl);
Thread.sleep(3000);
Alert alert = driver.switchTo().alert();
alert.accept();
}
/**
* 博客编辑页未登录测试
*/
public void EditByNoLogin() throws InterruptedException {
driver.get(editUrl);
driver.findElement(By.cssSelector("#title"));
driver.findElement(By.cssSelector("#submit")).click();
Thread.sleep(3000);
Alert alert = driver.switchTo().alert();
alert.accept();
//driver.quit();
}
/**
* 博客详情页未登录测试
*/
public void DetailByNoLogin() throws InterruptedException {
driver.get(detailUrl);
Thread.sleep(3000);
Alert alert = driver.switchTo().alert();
alert.accept();
driver.quit();
}
}
3.5.6 启动测试类
import tests.*;
import java.io.IOException;
public class RunTests {
public static void main(String[] args) throws InterruptedException, IOException {
LoginPage loginPage = new LoginPage();
loginPage.loginPageRight();
loginPage.loginSuc();
ListPage listPage = new ListPage();
listPage.ListPageByLogin();
DetailPage detailPage = new DetailPage();
detailPage.DetailPageByLogin();
UpdatePage updatePage = new UpdatePage();
updatePage.UpdatePageByLogin();
EditPage editPage = new EditPage();
editPage.EditPageByLogin();
loginPage.loginFail();
PageByNoLogin pageByNoLogin = new PageByNoLogin();
pageByNoLogin.ListByNoLogin();
pageByNoLogin.EditByNoLogin();
pageByNoLogin.DetailByNoLogin();
}
}
4 项目BUG
(一)bug描述:博客首页的文章和分类无实际作用,当发布新文章后文章的数量并不会增加。
(二)当用户名和密码都错误时,只会提示用户不存在。
5 遇到的问题及解决方法
(一)有弹窗时,添加屏幕截图,要先关闭弹窗后才能截图,否则会抛出异常
(二)当代码出现报错:no such element: Unable to locate element,这种情况可能是由于页面未加载完成,我们可以添加等待:driver.implicitly_wait(5)
(三) 登录时,提示浏览器受到自动化测试软件的控制,可添加下面语句,避免网站检测到浏览器正在被自动化工具(如 Selenium)控制
6 测试总结
此次测试主要对个人博客系统的主要功能进行了测试,并用Selenium编写了测试脚本进行了自动化测试。个人博客系统还需对首页的个人信息栏部分进行优化,如:文章的数量要与用户发布的数量同步起来,在弹窗提示上也需要更详细些,为用户提供有用的弹窗信息,这样才能给用户提供一个良好的体验。