博客系統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 地址 | 能顯示且能跳轉 | 不能顯示但能跳轉 | 測試時間緊張,留至下版本更新處理 |
部分擴展功能測試 | 抓緊實現 | 暫未實現 | 測試時間緊張,未能涉及全模塊 |
總結
測試代碼編寫可能出現錯誤的原因:
隱式等待有時會改變代碼執行順序出現報錯,可加入強制等待,確保頁面加載完成,提高自動化的穩定性。