前言
pytest的conftest.py文件覺得是一個值得探索的文件,它可以干什么呢
- 可以修改pytest-html內容
- 可以添加hook函數獲取更多特性
- 可以全局化driver
等等。
之前我們介紹過selenium+pytest的組合使用,也介紹了allure的使用,但是對於pytest-html沒有怎么做優化。
今天趁着周末,來講講conftest.py
的更多功能吧。
- 選用的項目依舊是Selenium+Pytest自動化測試框架實戰,在這個項目的基礎上說說怎么優化吧。
pytest版本說明
- python版本——3.7.7
- pytest版本——6.1.2
- pytest-html版本——3.0.0
pytest-html標題更改
我們運行一下項目。查看結果。
發現標題部分是report.html,沒有什么可以使用東西。所以我們先來更改一下這部分。
修改項目根目錄的conftest.py
文件。
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import base64
import pytest
import allure
from py.xml import html
from selenium import webdriver
from config.conf import cm
from common.readconfig import ini
from utils.times import timestamp
from utils.send_mail import send_report
driver = None
@pytest.fixture(scope='session', autouse=True)
def drivers(request):
global driver
if driver is None:
driver = webdriver.Chrome()
driver.maximize_window()
def fn():
driver.quit()
request.addfinalizer(fn)
return driver
@pytest.hookimpl(hookwrapper=True)
def pytest_runtest_makereport(item):
"""
當測試失敗的時候,自動截圖,展示到html報告中
:param item:
"""
pytest_html = item.config.pluginmanager.getplugin('html')
outcome = yield
report = outcome.get_result()
report.description = str(item.function.__doc__)
extra = getattr(report, 'extra', [])
if report.when == 'call' or report.when == "setup":
xfail = hasattr(report, 'wasxfail')
if (report.skipped and xfail) or (report.failed and not xfail):
screen_img = _capture_screenshot()
if screen_img:
html = '<div><img src="data:image/png;base64,%s" alt="screenshot" style="width:1024px;height:768px;" ' \
'onclick="window.open(this.src)" align="right"/></div>' % screen_img
extra.append(pytest_html.extras.html(html))
report.extra = extra
def pytest_html_results_table_header(cells):
cells.insert(1, html.th('用例名稱'))
cells.insert(2, html.th('Test_nodeid'))
cells.pop(2)
def pytest_html_results_table_row(report, cells):
cells.insert(1, html.td(report.description))
cells.insert(2, html.td(report.nodeid))
cells.pop(2)
def pytest_html_results_table_html(report, data):
if report.passed:
del data[:]
data.append(html.div('通過的用例未捕獲日志輸出.', class_='empty log'))
def pytest_html_report_title(report):
report.title = "pytest示例項目測試報告"
def _capture_screenshot():
"""截圖保存為base64"""
now_time, screen_file = cm.screen_path
driver.save_screenshot(screen_file)
allure.attach.file(screen_file,
"失敗截圖{}".format(now_time),
allure.attachment_type.PNG)
with open(screen_file, 'rb') as f:
imagebase64 = base64.b64encode(f.read())
return imagebase64.decode()
通過pytest的hook功能,我們新添加了一個pytest_html_report_title
函數。
然后我們來運行一下。在項目根目錄cmd中輸入pytest
,運行完畢后查看報告文件。
可以看到我們的報告標題已經被更改了,是不是更貼合測試的項目呢。
pytest-html Environment更改
在報告中有一個Environment環境變量選項,如圖所示:
這個對於我們的幫助不是很大,所以我們也更改一下他。
在conftest.py
文件中加入以下代碼。就放在更改標題代碼的下方。
def pytest_configure(config):
config._metadata.clear()
config._metadata['測試項目'] = "測試百度官網搜索"
config._metadata['測試地址'] = ini.url
這次我們添加了pytest_configure
函數。
- 對原有的configure內容進行了清除。
- 然后添加我們自己設定的兩個值。
然后執行一下,查看結果:
可以看到Environment中內容已經更改了,變成對我們有用的內容了。
pytest-html Summary更改
報告中還有一個Summary概要內容
里面的都是對我們有用的,添加一些其他的信息。在contest.py
中添加如下內容。也放在上文函數的下方。
def pytest_html_results_summary(prefix, summary, postfix):
# prefix.clear() # 清空summary中的內容
prefix.extend([html.p("所屬部門: XX公司測試部")])
prefix.extend([html.p("測試執行人: 隨風揮手")])
然后運行一下查看結果:
可以看到添加的部門、執行人的信息已經在報告中出現了。
pytest執行失敗發送郵件
之前我們講過的示例項目中不管執行成功還是執行是失敗都會發送郵件,但是這樣有點不理智,收到郵件有點心慌慌,所以我們應該采取失敗或者錯誤的時候在嘗試發送郵件。
更新一下conftest.py
文件。繼續放在上文函數的下方。
def pytest_terminal_summary(terminalreporter, exitstatus, config):
"""收集測試結果"""
result = {
"total": terminalreporter._numcollected,
'passed': len(terminalreporter.stats.get('passed', [])),
'failed': len(terminalreporter.stats.get('failed', [])),
'error': len(terminalreporter.stats.get('error', [])),
'skipped': len(terminalreporter.stats.get('skipped', [])),
# terminalreporter._sessionstarttime 會話開始時間
'total times': timestamp() - terminalreporter._sessionstarttime
}
print(result)
if result['failed'] or result['error']:
send_report()
添加了一個hook函數pytest_terminal_summary
該函數可以統計測試結果
passed、failed、error、skipped
因為要發送郵件所以只用failed和error作為發送郵件成立的條件。
代碼加好了,我們來更新一下測試用例test_002
,設置一個預期的錯誤:
assert not all(["selenium" in i for i in search.imagine])
然后pyetest
運行一下:
可以看到有一個failed然后緊接着提示測試郵件發送成功。
我們打開郵箱查看一下,成功收到了錯誤郵件:
pytest-html的相關內容就先到這里吧,下期再見。