在運行完測試用例後,需要用一個測試報告來作爲自動化運行的一個報告成果,一般是統計用例運行的成功失敗,這裏就給大家引入兩個測試報告模板HTMLTestRunner以及BeautifulReport,這裏基於POM設計模式實現這篇文章中的代碼,來進行改造以及介紹具體的使用。
HTMLTestRunner
BeautifulReport
一、模板的下載
大家可以網上搜索這兩個測試報告模板進行下載,應該都會有;也可以下載我上傳到csdn的資源。或者私聊我都可以。
二、報告模板的使用:
2.1框架結構的變化
首先我把測試報告模板放在了common公共方法包裏
新建了report文件夾和pic文件夾,存放測試報告和截圖
新增了run_all包,和run類作爲運行測試用例的入口。
2.2修改測試報告模板的配置:
HTMLTestRunner.py中修改配置:
489行附近:
這裏我爲了好看,在a標籤里加了一個圖標的圖片,大家可以自行修改這個標籤,或者改成文字鏈接啊什麼都可以。
806行附近
這裏我設置了截圖保存地址的絕對路徑,也就是報告裏的圖片要到這個文件夾去找,大家也可以設置相對路徑或者絕對路徑,都可以。
BeautifulReport中修改配置:
52行附近,要配置report_template文件的路徑,使用相對路徑或者絕對路徑。
2.3報告模板使用方法介紹
HTMLTestRunner的運行方法:
HTMLTestRunner(stream, title, description).run(suite)
- steam:測試報告文件
- title:測試報告標題
- description:測試報告描述
- suite:測試用例集
BeautifulReport的運行方法:
BeautifulReport(suite).report(description, log_path, filename)
- suite:測試用例集
- description:測試報告標題、描述
- log_path:測試報告的存放文件夾位置
- filename:測試報告文件的名稱
2.4 測試報告使用示例
這裏我在run.py這個文件中,作爲運行測試用例集的入口,和unittest批量運行一樣,要先創建測試用例集,不一樣的是運行測試集的方法不同。
HTMLTestRunner運行測試用例集:
導入相關包:
from common.HTMLTestRunner import HTMLTestRunner
import time
import unittest
獲取用例集合
suite = unittest.defaultTestLoader.discover("E:/111test/blog_ui/case", "*login.py")
定義測試報告路徑和文件名
filename = "E:/111test/blog_ui/report/" + time.strftime("%Y-%m-%d %H_%M_%S") + ".html"
創建測試報告文件
file = open(filename, "wb")
使用HTMLTestRunner報告運行用例,結果寫入報告
HTMLTestRunner(stream=file, title=u'接口自動化測試報告', description=u'用例執行情況:').run(suite)
關閉測試報告文件
file.close()
BeautifulReport運行測試用例集:
導入相關包:
from common.BeautifulReport import BeautifulReport
import time
import unittest
獲取用例集合
suite = unittest.defaultTestLoader.discover("E:/111test/blog_ui/case", "*login.py")
使用BeautifulReport報告運行用例,結果寫入報告
BeautifulReport(suite).report(description=u'用例執行情況', log_path="E:/111test/blog_ui/report/", filename=time.strftime("%Y-%m-%d %H_%M_%S"))
三、獲取截圖以及框架方法更新
3.1 driver層
pagedriver層,我加入了一個原生的pagedriver方法,需要注意的是,HTMLTestRunner如果要查看截圖,則要在這裏把圖片地址print出來,然後才能被HTMLTestRunner捕獲。
def screen_shot(self):
pic_path = "E:/111test/blog_ui/report/pic/" + time.strftime("%Y-%m-%d %H_%M_%S") + ".png"
print(pic_path)
return self.driver.save_screenshot(pic_path)
3.2page層
由於driver層新增了截圖方法,所以在page層我們也新建一個截圖操作的方法
def get_screen_shots(self):
self.screen_shot()
3.3case層
在case層中,如要使用BeautifulReport來捕獲截圖,則需要BeautifulReport的裝飾器,並且在整個case運行期間,加入了異常捕獲,並在獲取異常後截圖。
@BeautifulReport.add_test_img("error.png")
def test_wangyi_login(self):
"""登錄網易郵箱"""
login_page = Login(self.driver, self.url, self.title)
try:
login_page.open()
login_page.change_frame()
sleep(3)
login_page.input_name(self.user_name)
login_page.input_password(self.user_password)
sleep(2)
login_page.enter_login()
sleep(5)
login_page.get_screen_shots()
print(login_page.get_login_message())
assert "網易郵箱6.0版" in login_page.get_login_message()
except:
login_page.screen_shot()
assert False
四、實例演示
這裏展示下經過修改的這幾個文件的代碼:
pagedriver.py
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import time
import os
class Action(object):
"""
Action封裝所有頁面都公用的方法
"""
# 初始化driver、url、title等
def __init__(self, driver, page_url=None, page_title=None):
self.page_url = page_url
self.page_title = page_title
self.driver = driver
self.driver.maximize_window()
self.driver.implicitly_wait(30)
def open(self):
"""
定義open方法,調用_open()進行打開鏈接
"""
self._open(self.page_url, self.page_title)
def on_page(self, page_title):
"""
使用current_url獲取當前窗口Url地址,進行與配置地址作比較,返回比較結果(True False)
"""
return page_title in self.driver.title
def _open(self, page_url, page_title):
"""
打開頁面,校驗頁面鏈接是否加載正確
"""
# 使用get打開訪問鏈接地址
if page_url and page_title is not None:
self.driver.get(page_url)
print("打開網址:%s" % page_url)
print("網址預期標題: %s" % page_title)
# 使用assert進行校驗,打開的鏈接地址是否與配置的地址一致。調用on_page()方法
assert self.on_page(page_title), u"打開頁面%s失敗" % page_url
def find_element(self, *locator):
try:
print("定位元素:%s" % (locator,))
return WebDriverWait(self.driver, 20).until(EC.presence_of_element_located(locator))
except Exception as msg:
print(u"%s 頁面中未能找到 %s 元素" % (self, locator))
print("錯誤信息%s" % msg)
def send_keys(self, locator, value, clear_first=True):
"""
重寫定義send_keys方法
"""
element = self.find_element(*locator)
if clear_first:
element.clear()
element.send_keys(value)
else:
element.send_keys(value)
print("輸入值:%s" % value)
def switch_frame(self, frame_loc):
"""
切換frame,
:param frame_loc:id、name、element、index
:return:
"""
self.driver.switch_to.frame(frame_loc)
def screen_shot(self):
pic_path = "E:/111test/blog_ui/report/pic/" + time.strftime("%Y-%m-%d %H_%M_%S") + ".png"
print(pic_path)
return self.driver.save_screenshot(pic_path)
login_page.py
from common.pagedriver import Action
from selenium.webdriver.common.keys import Keys
class Login(Action):
input_name_loc = ("xpath", "//input[@placeholder='郵箱帳號或手機號碼']")
input_password_loc = ("xpath", "//input[@placeholder='輸入密碼']")
enter_login_loc = Keys.ENTER
frame_loc = (0)
def __init__(self, driver, page_url=None, page_title=None):
Action.__init__(self, driver, page_url, page_title)
def open(self):
"""打開頁面"""
self._open(self.page_url, self.page_title)
def change_frame(self):
"""切換frame"""
self.switch_frame(self.frame_loc)
def input_name(self, login_name):
"""輸入登錄名"""
self.send_keys(self.input_name_loc, login_name)
def input_password(self, login_password):
"""輸入密碼"""
self.send_keys(self.input_password_loc, login_password)
def enter_login(self):
"""模擬登陸點擊回車"""
self.send_keys(self.input_password_loc, self.enter_login_loc, False)
def get_login_message(self):
"""獲取登錄後的信息以斷言"""
return self.driver.title
def get_screen_shots(self):
self.screen_shot()
test_163.py
# -*- coding: utf-8 -*-
import unittest
from time import sleep
from page.login_page import Login
from selenium import webdriver
class Demo(unittest.TestCase):
def setUp(self):
self.url = "https://mail.163.com/"
self.title = "網易"
self.user_name = "" # 登錄賬戶
self.user_password = "" # 登錄密碼
self.driver = webdriver.Chrome()
def test_wangyi_login(self):
"""登錄網易郵箱"""
login_page = Login(self.driver, self.url, self.title)
try:
login_page.open()
login_page.change_frame()
sleep(3)
login_page.input_name(self.user_name)
login_page.input_password(self.user_password)
sleep(2)
login_page.enter_login()
sleep(5)
login_page.get_screen_shots()
print(login_page.get_login_message())
assert "網易郵箱6.0版" in login_page.get_login_message()
except:
login_page.screen_shot()
assert False
def tearDown(self):
self.driver.close()
if __name__ == "__main__":
unittest.main()
run.py
from common.HTMLTestRunner import HTMLTestRunner
import time
import unittest
from common.BeautifulReport import BeautifulReport
# 獲取用例集合
suite = unittest.defaultTestLoader.discover("E:/111test/blog_ui/case", "*login.py")
# 定義測試報告路徑和文件名
filename = "E:/111test/blog_ui/report/" + time.strftime("%Y-%m-%d %H_%M_%S") + ".html"
# 創建測試報告文件
file = open(filename, "wb")
# 使用HTMLTestRunner報告運行用例,結果寫入報告
HTMLTestRunner(stream=file, title=u'接口自動化測試報告', description=u'用例執行情況:').run(suite)
# 關閉測試報告文件
file.close()
# 使用BeautifulReport報告運行用例
# BeautifulReport(suite).report(description=u'用例執行情況', log_path="E:/111test/blog_ui/report/", filename=time.strftime("%Y-%m-%d %H_%M_%S"))