pytest學習及總結(一)
技術標籤:python
pytest
1.捕獲異常
pytest.raises(異常型別)
2.標記測試函式
1.顯式指定函式名
pytest 指令碼路徑/***.py::函式名
2.使用模糊匹配
pytest -k 模糊匹配名 路徑/test_*.py
3.pytest.mark
在函式前加上@pytest.mark.finished
測試時使用pytest -m finished 路徑/***.py
3.跳過測試
如果測試中有一些函式需要被略過,則需要在需要被跳過的函式前加 1. @pytest.mark.skip(reason='out-of-date api')reason裡面寫 2. @pytest.mark.skipif(條件(相當於if裡面的條件),reason='out-of-date api')
import pytest
import sys
@pytest.mark.skip(reason='out-of-date api')
def test_connect():
pass
@pytest.mark.skipif(sys.version < '3.6.5', reason='not support util 0.2.0')
def test_api():
print('aaa')
def test_function(record_property):
record_property('example_key', 1)
assert True
4.預見錯誤
測試時可以預見錯誤,如果預見錯誤,但測試通過則為xpass,預見錯誤,實際檢測出來也是錯誤的話,則為xfail
@pytest.mark.xfail(預見的錯誤,reason='')
用x進行標記
import pytest
import sys
@pytest.mark.xfail(sys.version < '3.5.0', reason='not syrpport until v3.7.0')
def test_api():
a = 1
b = 2
assert a != b
5.引數化
用於校驗一個或多個測試用例,例如使用者名稱與密碼校驗 pytest.mark.parametrize(argnames,argvalues) 其中argnames可以是一個或者多個引數
import pytest
@pytest.mark.parametrize('passwd', ['123456', 'abcdefdfs', 'as52345fasdf4'])
def test_passwd_length(passwd):
assert len(passwd) >= 8
@pytest.mark.parametrize('user, passwd',
[('jack', 'abcdefgh'),
('tom', 'a123456a')])
def test_passwd_md5(user, passwd):
db = {
'jack': 'e8dc4081b13434b45189a720b77b6818',
'tom': '1702a132e769a623c1adb78353fc9503'
}
import hashlib
assert hashlib.md5(passwd.encode()).hexdigest() == db[user]
@pytest.mark.parametrize('user,passwd',
[pytest.param('jack', 'abcdefgh', id='User<Jack>'),
pytest.param('tom', 'a123456a', id='User<Tom>')])
def test_passwd_md5_id(user, passwd):
db = {
'jack': 'e8dc4081b13434b45189a720b77b6818',
'tom': '1702a132e769a623c1adb78353fc9503'
}
import hashlib
assert hashlib.md5(passwd.encode()).hexdigest() == db[user]
6.韌體
韌體是一些函式,pytest
會在執行測試之前或者之後執行它們,可以利用韌體做任何事情。還可以將韌體全部寫在 conftest.py
中,便於集中管理韌體。複雜專案中還可以在不同的目錄級別中定義韌體,作用域是其所在的目錄以及子目錄。
import pytest
@pytest.fixture()
def postcode():
return '011'
def test_postcode(postcode):
assert postcode == '010'
6.1.預處理和後處理
在測試前或者測試結束後需要進行一些操作,當這些操作需要大量重複時,便可以使用韌體中的預處理和後處理。
預處理:測試前執行。如:連線資料庫
後處理:測試後進行。如:關閉資料庫連線
pytest使用yield
關鍵詞將韌體分為兩部分,yield
之前是預處理測試前進行,yield
之後是後處理,測試後進行。
@pytest.fixture()
def db():
print('Connection successful')
yield
print('Connection closed')
def search_user(user_id):
d = {
'001': 'xiaoming'
}
return d[user_id]
def test_search(db):
assert search_user('001') == 'xiaoming'
可以使用pytest -s ***.py 或 pytest --setup-show ***.py
顯示詳細的測試資訊。
6.2作用域
pytest使用作用域指定韌體的作用範圍,在定義韌體時,可以使用scope引數宣告作用域
function 每個測試函式都會執行韌體
class 每個測試類執行一次,包括類裡面的所有函式
module 每個模組執行一次,包括模組裡面的類和函式
session 一次測試只執行一次,所有找到的函式和方法都可以使用
@pytest.fixture(scope='function')
@pytest.fixture(scope='class')
@pytest.fixture(scope='module')
@pytest.fixture(scope='session')
類作用域需要使用@pytest.mark.usefixtures('class_scope')
import pytest
@pytest.fixture(scope='function')
def func_scope():
pass
@pytest.fixture(scope='module')
def mod_scope():
pass
@pytest.fixture(scope='session')
def sess_scope():
pass
@pytest.fixture(scope='class')
def class_scope():
pass
def test_multi_scope(sess_scope, mod_scope, func_scope):
pass
@pytest.mark.usefixtures('class_scope')
class TestClassScope:
def test_1(self):
pass
def test_2(self):
pass
6.3自動執行
如果需要讓韌體自動執行,可以在使用時定義autouse
引數
如下例子統計函式執行時間,結合scope
使用,可以定義作用範圍
import pytest
import time
DATE_FORMAT = '%Y-%m-%d %H:%M:%S'
@pytest.fixture(scope='session', autouse=True)
def timer_session_scope():
start = time.time()
print('\nstart: {}'.format(time.strftime(DATE_FORMAT, time.localtime(start))))
yield
finished = time.time()
print('\nfinished: {}'.format(time.strftime(DATE_FORMAT, time.localtime(finished))))
print('Total time cost: {:.3f}'.format(finished - start))
@pytest.fixture(autouse=True)
def time_function_scope():
start = time.time()
yield
print(' Time cost: {:.3f}'.format(time.time() - start))
def test_1():
time.sleep(1)
def test_2():
time.sleep(1)
結果:
test_autouse.py::test_1
start: 2020-11-24 13:39:59 # 會話開始計時
PASSED Time cost: 1.014 # 函式1耗時時間
test_autouse.py::test_2 #
PASSED Time cost: 1.002 # 函式2耗時時間
finished: 2020-11-24 13:40:01 # 會話結束
Total time cost: 2.025 # 整個會話耗時
6.4重新命名
如果需要對韌體名稱進行重新命名,則在定義時加上name
引數
import pytest
@pytest.fixture(name='age')
def calculate_average_age():
return 28
def test_age(age):
assert age == 28
6.5引數化
測試函式中函式可以引數化,在韌體中韌體引數也可以引數化,例如資料庫的連線測試,可以將其測試引數合併在一起,合併為一個韌體,測試更加方便。韌體在使用時必須要用params
引數進行引數化。
其中需要用到request
內建韌體,並使用request.param
屬性獲取引數。
import pytest
@pytest.fixture(params=[
('redis', '6379'),
('elasticsearch', '9200')
])
def param(request):
return request.param
@pytest.fixture(autouse=True)
def db(param):
print('\n Succeed to connect %s %s' % param)
print('\n Succeed to close %s %s' % param)
def test_api():
assert 1 == 1
6.6內建韌體
6.6.1tmpdir
和tmpdir_factory
tmpdir.mkdir()
可以建立臨時目錄,tmpdir.join()
可以建立檔案
def test_tmpdir(tmpdir):
a_dir = tmpdir.mkdir('mytmpdir')
a_file = a_dir.join('tmpfile.txt')
a_file.write('hello,pytest')
assert a_file.read() == 'hello,pytest'
tmpdir_factory
可以在作用域使用,包括session module class function
@pytest.fixture(scope='module')
def my_tmpdir_factory(tmpdir_factory):
a_dir = tmpdir_factory.mktemp('mytmpdir')
a_file = a_dir.join('tmpfile.txt')
a_file.write('hello,pytest')
return a_file
6.6.2pytestconfig
pytestconfig
可以讀取命令列引數配置以及檔案,其中在配置檔案conftest.py
中使用鉤子函式pytest_addoption
# conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption('--host',
action='store',
help='host of db')
parser.addoption('--port',
action='store',
default='8888',
help='port of db')
@pytest.fixture
def config(request):
return request.config
# test_config
def test_option1(pytestconfig):
print('host1: %s' % pytestconfig.getoption('host'))
print('port1: %s' % pytestconfig.getoption('port'))
# 其中pytestconfig是request.config的快捷方式,可以使用韌體
def test_option2(config):
print('host2: %s' % config.getoption('host'))
print('port2: %s' % config.getoption('port'))
# 測試時可以在測試程式碼中指定引數:
pytest -sv --host=localhost test_config::test_option1
6.6.3capsys
主要用於捕獲sysout
和syserr
import sys
def ping(output):
print('ping....', file=output)
def test_stdout(capsys):
ping(sys.stdout)
out, err = capsys.readouterr()
assert out == 'ping....\n'
assert err == ''
def test_stderr(capsys):
ping(sys.stderr)
out, err = capsys.readouterr()
assert out == ''
assert err == 'ping....\n'
6.6.4recwarn
recwarn
可以捕獲程式中warnings
產生的警告,pytest
中用pytest.warns
import warnings, pytest
def warn():
warnings.warn('Deprecated function', DeprecationWarning)
def test_warn(recwarn):
warn()
assert len(recwarn) == 1
w = recwarn.pop()
assert w.category == DeprecationWarning
def test_warn2():
with pytest.warns(None) as warnings:
warn()
assert len(warnings) == 1
w = warnings.pop()
assert w.category == DeprecationWarning
7.
7.1 pytest
指令
pytest -x # 在第一次測試失敗之後停止測試
pytest --maxfail = 2 # 第二次測試失敗之後停止測試
pytest -r
# r後面可以跟很多引數,顯示不同的資訊
f -failed
E -error
s -skipped
x -xfailed
X -xpassed
p -passed
P -passed with output
a -all execpt pP
7.2pdb
除錯
進入pdb除錯介面指令:python -m pdb test_pdb.py
h 顯示幫助指令
h l 顯示列表顯示的詳細資訊
b 給目標位置設定斷點
b 12 給第12行設定斷點
b test_fun.add 給add函式設定斷點
b 顯所有斷點
cl 刪除斷點
cl 2 刪除第二個斷點
cl 刪除所有斷點
歡迎使用Markdown編輯器
你好! 這是你第一次使用 Markdown編輯器 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。
新的改變
我們對Markdown編輯器進行了一些功能拓展與語法支援,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫部落格:
- 全新的介面設計 ,將會帶來全新的寫作體驗;
- 在創作中心設定你喜愛的程式碼高亮樣式,Markdown 將程式碼片顯示選擇的高亮樣式 進行展示;
- 增加了 圖片拖拽 功能,你可以將本地的圖片直接拖拽到編輯區域直接展示;
- 全新的 KaTeX數學公式 語法;
- 增加了支援甘特圖的mermaid語法1 功能;
- 增加了 多螢幕編輯 Markdown文章功能;
- 增加了 焦點寫作模式、預覽模式、簡潔寫作模式、左右區域同步滾輪設定 等功能,功能按鈕位於編輯區域與預覽區域中間;
- 增加了 檢查列表 功能。
功能快捷鍵
撤銷:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜體:Ctrl/Command + I
標題:Ctrl/Command + Shift + H
無序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
檢查列表:Ctrl/Command + Shift + C
插入程式碼:Ctrl/Command + Shift + K
插入連結:Ctrl/Command + Shift + L
插入圖片:Ctrl/Command + Shift + G
查詢:Ctrl/Command + F
替換:Ctrl/Command + G
合理的建立標題,有助於目錄的生成
直接輸入1次#,並按下space後,將生成1級標題。
輸入2次#,並按下space後,將生成2級標題。
以此類推,我們支援6級標題。有助於使用TOC
語法後生成一個完美的目錄。
如何改變文字的樣式
強調文字 強調文字
加粗文字 加粗文字
標記文字
刪除文字
引用文字
H2O is是液體。
210 運算結果是 1024.
插入連結與圖片
連結: link.
圖片:
帶尺寸的圖片:
居中的圖片:
居中並且帶尺寸的圖片:
當然,我們為了讓使用者更加便捷,我們增加了圖片拖拽功能。
如何插入一段漂亮的程式碼片
去部落格設定頁面,選擇一款你喜歡的程式碼片高亮樣式,下面展示同樣高亮的 程式碼片
.
// An highlighted block
var foo = 'bar';
生成一個適合你的列表
- 專案
- 專案
- 專案
- 專案
- 專案1
- 專案2
- 專案3
- 計劃任務
- 完成任務
建立一個表格
一個簡單的表格是這麼建立的:
專案 | Value |
---|---|
電腦 | $1600 |
手機 | $12 |
導管 | $1 |
設定內容居中、居左、居右
使用:---------:
居中
使用:----------
居左
使用----------:
居右
第一列 | 第二列 | 第三列 |
---|---|---|
第一列文字居中 | 第二列文字居右 | 第三列文字居左 |
SmartyPants
SmartyPants將ASCII標點字元轉換為“智慧”印刷標點HTML實體。例如:
TYPE | ASCII | HTML |
---|---|---|
Single backticks | 'Isn't this fun?' | ‘Isn’t this fun?’ |
Quotes | "Isn't this fun?" | “Isn’t this fun?” |
Dashes | -- is en-dash, --- is em-dash | – is en-dash, — is em-dash |
建立一個自定義列表
-
Markdown
- Text-to- HTML conversion tool Authors
- John
- Luke
如何建立一個註腳
一個具有註腳的文字。2
註釋也是必不可少的
Markdown將文字轉換為 HTML。
KaTeX數學公式
您可以使用渲染LaTeX數學表示式 KaTeX:
Gamma公式展示 Γ ( n ) = ( n − 1 ) ! ∀ n ∈ N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N Γ(n)=(n−1)!∀n∈N 是通過尤拉積分
Γ ( z ) = ∫ 0 ∞ t z − 1 e − t d t . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,. Γ(z)=∫0∞tz−1e−tdt.
你可以找到更多關於的資訊 LaTeX 數學表示式here.
新的甘特圖功能,豐富你的文章
- 關於 甘特圖 語法,參考 這兒,
UML 圖表
可以使用UML圖表進行渲染。 Mermaid. 例如下面產生的一個序列圖:
這將產生一個流程圖。:
- 關於 Mermaid 語法,參考 這兒,
FLowchart流程圖
我們依舊會支援flowchart的流程圖:
- 關於 Flowchart流程圖 語法,參考 這兒.
匯出與匯入
匯出
如果你想嘗試使用此編輯器, 你可以在此篇文章任意編輯。當你完成了一篇文章的寫作, 在上方工具欄找到 文章匯出 ,生成一個.md檔案或者.html檔案進行本地儲存。
匯入
如果你想載入一篇你寫過的.md檔案,在上方工具欄可以選擇匯入功能進行對應副檔名的檔案匯入,
繼續你的創作。
註腳的解釋 ↩︎