【博客系统UI自动化测试报告】
博客系统UI自动化测试报告
- 一、项目背景
- 二、测试内容
- (一)测试用例
- (二)测试账号
- (三)使用Selenium进行Web自动化测试
- 1.环境搭建
- 2.创建浏览器驱动
- 3.编写博客登陆模块的测试用例代码
- 4.编写博客主页展示模块的测试用例代码
- 5.编写博客创作模块的测试用例代码
- 6.编写博客查看模块的测试用例代码
- 7.编写博客删除模块的测试用例代码
- 8.编写博客退出模块的测试用例代码
- 9.编写测试截图功能
- 10.整合代码,进行系统测试
- (三)自动化测试总结
- 1.自动化测试覆盖模块
- 2.自动化测试用例数量
- 3. 自动化测试代码展示
- 4.自动化测试部分截图
- 5. 自动化测试结果
- 6. 测试评估
- 7. 遗留问题
- 总结
一、项目背景
本次博客系统UI自动化测试所用博客系统是基于SSM框架实现的个人博客系统,由博客登陆页、博客主页页、博客创作页、博客详情页所组成。成功登录博客即可查看自己已发布的博客,也可以进行发布博客操作,通过使用Selenium定位web元素、对获取到的元素进行操作等,对个人博客系统进行测试,测试的核心内容包括博客登录、博客主页展示、博客创作、博客修改、博客查看、博客删除、博客退出等。同时该博客系统还可以实现记录博客发布日期、时间等信息。
二、测试内容
注:测试的内容都是个人完成的,所以就不写需求文档和测试安排了。
(一)测试用例
设计测试用例方法一般从以下几个方面设计:
功能测试、界面测试、性能测试、易用性测试、安全性测试、兼容性测试等六个方面进行设计,但是个人博客系统是一个web网站,主要是针对核心功能、界面测试、安全性测试、兼容性测试进行测试,编写的测试用例如下:
其中安全性测试和界面测试需要人工测试,就不过多涉及了,
本报告主要对功能模块进行自动化测试。
(二)测试账号
账号 | 用户名 | 密码 |
---|---|---|
账号1 | zhangsan | 123456 |
账号2 | lisi | 123456 |
(三)使用Selenium进行Web自动化测试
1.环境搭建
安装与浏览器名称和版本对应的webdrivermanager。
本次测试使用的驱动版本如下:
驱动 | 版本 |
---|---|
Edge浏览器 | 138.0.3351.121 (正式版本) (64 位) |
selenium | 4.0.0 |
webdriver-manager | 4.0.2 |
2.创建浏览器驱动
创建一个驱动类(自定义名为Edge_Driver),通过在Edge_Driver中创建一个统一驱动对象对博客登录、博客主页展示、博客创作、博客修改、博客查看、博客删除、博客退出等功能分别进行测试操作。
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Optionsclass Edge_Driver:driver=""def __init__(self):# EdgeDriver 路径edge_driver_path = r"C:\Program Files (x86)\Microsoft\Edge\WebDriver\edgedriver_win64\msedgedriver.exe"service=Service(edge_driver_path)options = Options()options.add_argument("--remote-allow-origins=*")self.driver=webdriver.Edge(service=service,options=options)self.driver.implicitly_wait(2)
注:根据所要测试的功能可创建不同的测试类
3.编写博客登陆模块的测试用例代码
(1)创建一个博客登陆测试类(自定义名为BlogLand)继承Edge_Driver类,得到驱动driver
(2)根据博客登陆模块测试用例创建不同的方法
land.LandFailTest1()#输入错误的账号和错误的密码land.LandFailTest2()#输入错误的账号和正确的密码land.LandFailTest3()#输入正确的账号和错误的密码land.LandFailTest4()#输入非常规账号和密码land.LandFailTest5()#仅输入账号land.LandFailTest6()#仅输入密码land.LandFailTest7()#不做输入land.LandTest()#输入正确的账号和密码
import time
from selenium.webdriver.common.by import By
from selenium.webdriver.support.expected_conditions import alert_is_present
from common.webdriver import BlogDriver
class BlogLand:url=""driver=""def __init__(self):self.url = "http://8.137.19.140:9090/blog_login.html"self.driver = BlogDriver.driver#登陆成功def LandTest1(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR,"#username").clear()self.driver.find_element(By.CSS_SELECTOR,"#password").clear()self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()BlogDriver.GetImage()text=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3").textassert text=='zhangsan'self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(6)").click()def LandTest2(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("lisi")self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()BlogDriver.GetImage()text = self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3").textassert text == 'lisi'self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(6)").click()#输入错误的账号和错误的密码def LandFailTest1(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR,"#username").clear()self.driver.find_element(By.CSS_SELECTOR,"#password").clear()self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhannsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123457")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='用户不存在'alert.accept()BlogDriver.GetImage()#输入错误的账号和正确的密码def LandFailTest2(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhanasan")self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='用户不存在'alert.accept()BlogDriver.GetImage()#输入正确的账号和错误的密码def LandFailTest3(self):self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("122456")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='密码错误'alert.accept()BlogDriver.GetImage()#输入非常规账号和密码def LandFailTest4(self):self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("$@:zda85545><?~")self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("$@:zda85545><?~")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='用户不存在'alert.accept()BlogDriver.GetImage()#仅输入账号def LandFailTest5(self):self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='账号或密码不能为空'alert.accept()BlogDriver.GetImage()#仅输入密码def LandFailTest6(self):self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")self.driver.implicitly_wait(2)self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='账号或密码不能为空'alert.accept()BlogDriver.GetImage()#不做输入def LandFailTest7(self):self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.implicitly_wait(2)self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='账号或密码不能为空'alert.accept()BlogDriver.GetImage()land = BlogLand()
(3)单独对该模块进行自动化测试
4.编写博客主页展示模块的测试用例代码
(1)创建一个博客主页展示类(自定义名为BlogShow)继承Edge_Driver类,得到驱动driver
(2)根据博客主页展示模块测试用例创建不同的方法
LandShow()#登陆状态下主页展示LandFailShow()#未登录状态主页展示
import time
from selenium.webdriver.common.by import By
from common.webdriver import BlogDriverclass BlogShow:url = ""driver=""def __init__(self):self.url = "http://8.137.19.140:9090/blog_login.html"self.driver=BlogDriver.driverself.driver.get(self.url)#登陆状态下主页展示def LandShow(self):self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()BlogDriver.GetImage()text=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > h3").textassert text=="zhangsan"text=self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > span").textassert text =="我的博客系统"text=self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(6)").textassert text =="注销"text=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)").textassert text =="文章"text=self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)").textassert text =="分类"#未登录状态主页展示def LandFailShow(self):self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(6)").click()BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(4)").click()time.sleep(1)self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(5)").click()time.sleep(1)BlogDriver.GetImage()# text=self.driver.find_element(By.CSS_SELECTOR,"#submit").text# print(text)# assert text =="发布文章"self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='账号或密码不能为空'alert.accept()BlogDriver.GetImage()Show = BlogShow()
(3)单独对该模块进行自动化测试
5.编写博客创作模块的测试用例代码
(1)创建一个博客创作展示类(自定义名为BlogPush)继承Edge_Driver类,得到驱动driver
(2)根据博客创作模块测试用例创建不同的方法
BPush()#博客创作Modify()#博客修改
from common.webdriver import BlogDriver
import timefrom selenium.webdriver.common.by import Byclass BlogPush:driver=""url=""def __init__(self):self.driver=BlogDriver.driverself.url="http://8.137.19.140:9090/blog_login.html"# 博客创作def BPush(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(5)").click()time.sleep(1)BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)alert=self.driver.switch_to.alertalert.accept()self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("博客系统UI自动化测试")BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(6)").click()# 博客修改def Modify(self):self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > a").click()time.sleep(1)BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > div.operating > button:nth-child(1)").click()BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR, "#title").send_keys("123")BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"body > div.nav > a:nth-child(6)").click()push=BlogPush()
(3)单独对该模块进行自动化测试
6.编写博客查看模块的测试用例代码
(1)创建一个博客查看展示类(自定义名为BlogFind)继承Edge_Driver类,得到驱动driver
(2)根据博客查看模块测试用例创建不同的方法
#博客查看
LandFind():
from common.webdriver import BlogDriver
import timefrom selenium.webdriver.common.by import Byclass BlogFind:url=""driver=""def __init__(self):self.url = "http://8.137.19.140:9090/blog_login.html"self.driver=BlogDriver.driver#博客查看def LandFind(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > a").click()text=self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.title").textBlogDriver.GetImage()assert text=='博客系统UI自动化测试123'text=self.driver.find_element(By.CSS_SELECTOR, "#h2-u5728u8FD9u91CCu5199u4E0Bu4E00u7BC7u535Au5BA2").textassert text=='在这里写下一篇博客'self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click()find=BlogFind()
(3)单独对该模块进行自动化测试
7.编写博客删除模块的测试用例代码
(1)创建一个博客删除类(自定义名为BlogPop)继承Edge_Driver类,得到驱动driver
(2)根据博客删除博客删除模块测试用例创建不同的方法
BPop()#博客删除
import timefrom selenium.webdriver.common.by import Byfrom common.webdriver import BlogDriverclass BlogPop:driver=""url=""def __init__(self):self.driver=BlogDriver.driverself.url="http://8.137.19.140:9090/blog_login.html"def BPop(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > a").click()time.sleep(1)BlogDriver.GetImage()self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > div.operating > button:nth-child(2)").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='确定删除?'alert.dismiss()self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > div.operating > button:nth-child(2)").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='确定删除?'alert.accept()BlogDriver.GetImage()pop=BlogPop()
(3)单独对该模块进行自动化测试
8.编写博客退出模块的测试用例代码
(1)创建一个博客退出类(自定义名为BlogExit)继承Edge_Driver类,得到驱动driver
(2)根据博客退出模块测试用例创建不同的方法
注:博客正常退出在前几个模块不断被使用,故这里只编写了不正常退出。
BExit()#博客不正常退出
import timefrom selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
from selenium.webdriver.edge.service import Servicefrom common.webdriver import BlogDriverclass BlogExit:driver=""url=""def __init__(self):self.url="http://8.137.19.140:9090/blog_login.html"self.driver=BlogDriver.driverdef BExit(self):self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()self.driver.quit()edge_driver_path = r"C:\Program Files (x86)\Microsoft\Edge\WebDriver\edgedriver_win64\msedgedriver.exe"service=Service(edge_driver_path)options = Options()options.add_argument("--remote-allow-origins=*")self.driver=webdriver.Edge(service=service,options=options)self.driver.get(self.url)self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(1)alert = self.driver.switch_to.alerttext=alert.textassert text=='账号或密码不能为空'alert.accept()self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR,"#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR,"#submit").click()time.sleep(1)self.driver.find_element(By.CSS_SELECTOR, "body > div.nav > a:nth-child(6)").click()time.sleep(1)self.driver.quit()exit=BlogExit()
(3)单独对该模块进行自动化测试
9.编写测试截图功能
测试截图可在自动化测试过程中进行截图操作并保存,这有利于自动化测试结果的观察。
因为该截图功能可能会被反复调用,故可以将其和创建驱动对象写到一起。
import datetime
import os
import sys
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Optionsclass Edge_Driver:driver=""def __init__(self):# EdgeDriver 路径edge_driver_path = r"C:\Program Files (x86)\Microsoft\Edge\WebDriver\edgedriver_win64\msedgedriver.exe"service=Service(edge_driver_path)options = Options()options.add_argument("--remote-allow-origins=*")self.driver=webdriver.Edge(service=service,options=options)self.driver.implicitly_wait(2)def GetImage(self):dirname = datetime.datetime.now().strftime('%Y-%m-%d')if not os.path.exists("../images/" + dirname):os.mkdir("../images/" + dirname)filename = sys._getframe().f_back.f_code.co_name + "-" + datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S") + ".png"self.driver.save_screenshot("../images/" + dirname + "/" + filename)BlogDriver=Edge_Driver()
10.整合代码,进行系统测试
将前面写的代码都放入main函数中运行。
from auto_Chrome_bolgtest import EdgeBlogLand
from auto_Chrome_bolgtest import EdgeBlogShow
from auto_Chrome_bolgtest import EdgeBlogFind
from auto_Chrome_bolgtest import EdgeBlogPush
from auto_Chrome_bolgtest import EdgeBlogPop
from auto_Chrome_bolgtest import EdgeBlogExitif __name__=="__main__":#博客登陆EdgeBlogLand.land.LandFailTest1()#输入错误的账号和错误的密码EdgeBlogLand.land.LandFailTest2()#输入错误的账号和正确的密码EdgeBlogLand.land.LandFailTest3()#输入正确的账号和错误的密码EdgeBlogLand.land.LandFailTest4()#输入非常规账号和密码EdgeBlogLand.land.LandFailTest5()#仅输入账号EdgeBlogLand.land.LandFailTest6()#仅输入密码EdgeBlogLand.land.LandFailTest7()#不做输入EdgeBlogLand.land.LandTest1()#输入正确的账号和密码EdgeBlogLand.land.LandTest2() # 输入正确的账号和密码#博客主页展示EdgeBlogShow.Show.LandShow()EdgeBlogShow.Show.LandFailShow()#博客创作EdgeBlogPush.push.BPush()EdgeBlogPush.push.Modify()#博客查看EdgeBlogFind.find.LandFind()#博客删除EdgeBlogPop.pop.BPop()#博客退出EdgeBlogExit.exit.BExit()
(三)自动化测试总结
1.自动化测试覆盖模块
博客登录、博客主页展示、博客创作、博客修改、博客查看、博客删除、博客退出
2.自动化测试用例数量
自动化测试用例数量:33个
3. 自动化测试代码展示
博客UI自动化测试代码链接:
https://gitee.com/pluck-his-hair/primary-project/tree/master/auto_test
4.自动化测试部分截图
5. 自动化测试结果
项目功能用例99.999999%通过
6. 测试评估
核心功能测试通过,项目达到上线基本要求
7. 遗留问题
问题 | 预期结果 | 实际结果 | 遗留原因 |
---|---|---|---|
博客主页展示页面中文章数量 | 跟随博客数量的变动而进行改变 | 始终为2 | 测试时间紧张,留至下版本更新处理 |
博客主页GitHub 地址 | 能显示且能跳转 | 不能显示但能跳转 | 测试时间紧张,留至下版本更新处理 |
部分扩展功能测试 | 抓紧实现 | 暂未实现 | 测试时间紧张,未能涉及全模块 |
总结
测试代码编写可能出现错误的原因:
隐式等待有时会改变代码执行顺序出现报错,可加入强制等待,确保页面加载完成,提高自动化的稳定性。