- 取得連結
- X
- 以電子郵件傳送
- 其他應用程式
程式語言:Python
範例 Source code
功能:Python test 設定與 Builtin Fixtures
習慣放 __init__ 在每個測試資料夾,以免出現同名的檔案
即使 function 名字不同,個別測試時 ok,但當集體測試時便會出錯
unittest.mock
pytest-cov’s documentation
- Package:
- pytest
範例 Source code
功能:Python test 設定與 Builtin Fixtures
習慣放 __init__ 在每個測試資料夾,以免出現同名的檔案
即使 function 名字不同,個別測試時 ok,但當集體測試時便會出錯
built-in fixtures
- 暫存
- tmpdir: Function Scope
- tmpdir_factory: Session Scope
test_advance.py
def test_tmpdir(tmpdir): tmdir_same_part(tmpdir) def test_tmpdir_factory(tmpdir_factory): dir_ = tmpdir_factory.mktemp("mydir") # 印出暫存位置 base_temp = tmpdir_factory.getbasetemp() print("base:", base_temp) tmdir_same_part(dir_) def tmdir_same_part(dir_): file1 = dir_.join("fileName1.txt") sub_dir = dir_.mkdir("dirName") file2 = sub_dir.join("fileName2.txt") file1.write("一二三") file2.write("四五六") assert file1.read() == "一二三" assert file2.read() == "四五六"
- cli command
- pytestconfig
conftest.py,自定義的 cli command 必須放在這,或是 plugin 中
# pytest_addoption 是特定名字 def pytest_addoption(parser): parser.addoption("--mybool", action="store_true", help="boolean option") parser.addoption("--name", action="store", default="abc", help="name: abc or ABC")test_advance.py
import pytest # pytestconfig fixtures def test_pytestconfig_option(pytestconfig): print('"name" :', pytestconfig.getoption("name"), pytestconfig.option.name) print('"mybool" :', pytestconfig.getoption("mybool"), pytestconfig.option.mybool) # pytestconfig fixtures def test_pytestconfig(pytestconfig): print("args :", pytestconfig.args) print("inifile :", pytestconfig.inifile) print("invocation_dir :", pytestconfig.invocation_dir) print("rootdir :", pytestconfig.rootdir) print("-k EXPRESSION :", pytestconfig.getoption("keyword")) print("-v, --verbose :", pytestconfig.getoption("verbose")) print("-q, --quiet :", pytestconfig.getoption("--quiet")) print("-l, --showlocals:", pytestconfig.getoption("showlocals")) print("--tb=style :", pytestconfig.getoption("tbstyle")) # request fixtures def test_pytestconfig_legacy(request): print('\n"name" :', request.config.getoption("name")) print('"myopt" :', request.config.getoption("mybool")) print('"keyword" :', request.config.getoption("keyword"))輸入 help 可看到已加入
pytest -h
custom options: --mybool boolean option --name=NAME name: abc or ABC
- cache
- 快取運用
test_advance.py
import pytest import datetime import random import time from collections import namedtuple Duration = namedtuple("Duration", ["current", "last"]) @pytest.fixture(scope="session") def duration_cache(request): # 存放的資料夾與檔名 key = "folder/fileName" d = Duration({}, request.config.cache.get(key, {})) yield d request.config.cache.set(key, d.current) @pytest.fixture() def check_duration(request, duration_cache): d = duration_cache nodeid = request.node.nodeid start_time = datetime.datetime.now() yield duration = (datetime.datetime.now() - start_time).total_seconds() d.current[nodeid] = duration if d.last.get(nodeid, None) is not None: errorstring = "測試時間是上次的兩倍" assert duration <= (d.last[nodeid] * 2), errorstring @pytest.mark.parametrize("i", range(5)) def test_cache(i, check_duration): time.sleep(random.random())輸入指令,可看到 cache 存放的值
pytest test_advance.py --cache-clear pytest test_advance.py --cache-show
folder\fileName contains: {'test_advance.py::test_cache[0]': 0.122007, 'test_advance.py::test_cache[1]': 0.996057, 'test_advance.py::test_cache[2]': 0.941054, 'test_advance.py::test_cache[3]': 0.222012, 'test_advance.py::test_cache[4]': 0.799045}
- capsys
- 獲取 stdout & stdout
- 暫時輸出 stdout
test_advance.py
import sys import pytest def capsys_Hi(name): print("Hi, {}".format(name)) print("有錯誤", file=sys.stderr) def test_capsys_Hi(capsys): capsys_Hi("一") out, err = capsys.readouterr() assert out == "Hi, 一\n" assert "錯誤" in err capsys_Hi("二") capsys_Hi("三") out, err = capsys.readouterr() assert out == "Hi, 二\nHi, 三\n" assert err == "" def test_capsys_disabled(capsys): with capsys.disabled(): print("\n總是顯示") print("有 -s 才顯示")
- monkeypatch
- setattr(target, name, value=
, raising=True): Set an attribute. delattr(target, name= , raising=True): Delete an attribute. setitem(dic, name, value): Set a dictionary entry. delitem(dic, name, raising=True): Delete a dictionary entry. setenv(name, value, prepend=None): Set an environmental variable. delenv(name, raising=True): Delete an environmental variable. syspath_prepend(path): Prepend path to sys.path chdir(path): Change the current working directory - 可搭配 unittest.mock
test_advance.py
import math def test_monkeypatch(monkeypatch): d = {"a": 1} assert d.get("a") == 1 monkeypatch.setitem(d, "a", 100) assert d.get("a") == 100 with monkeypatch.context() as m: m.setattr(math, "cos", (lambda x: x)) assert math.cos("a") == "a" assert math.cos(math.pi) == -1
Configuration
除了 setup.cfg 開頭略有不同,格式是一致的
pytest.ini
pytest.ini
[pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ; 分號註解setup.cfg
[tool:pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ; 分號註解tox.ini
[pytest] addopts = -rsxX -l --tb=short --strict xfail_strict = true ; 分號註解help 中有定義可設定的值
pytest -h [pytest] ini-options in the first pytest.ini|tox.ini|setup.cfg file found: markers (linelist) markers for test functions empty_parameter_set_mark (string) default marker for empty parametersets norecursedirs (args) directory patterns to avoid for recursion testpaths (args) directories to search for tests when no files or dire console_output_style (string) console output: classic or with additional progr usefixtures (args) list of default fixtures to be used with this project python_files (args) glob-style file patterns for Python test module disco python_classes (args) prefixes or glob names for Python test class discover python_functions (args) prefixes or glob names for Python test function and m xfail_strict (bool) default for the strict parameter of xfail markers whe junit_suite_name (string) Test suite name for JUnit report junit_logging (string) Write captured log messages to JUnit report: one of n doctest_optionflags (args) option flags for doctests doctest_encoding (string) encoding used for doctest files cache_dir (string) cache directory path. filterwarnings (linelist) Each line specifies a pattern for warnings.filterwar log_print (bool) default value for --no-print-logs log_level (string) default value for --log-level log_format (string) default value for --log-format log_date_format (string) default value for --log-date-format log_cli (bool) enable log display during test run (also known as "li log_cli_level (string) default value for --log-cli-level log_cli_format (string) default value for --log-cli-format log_cli_date_format (string) default value for --log-cli-date-format log_file (string) default value for --log-file log_file_level (string) default value for --log-file-level log_file_format (string) default value for --log-file-format log_file_date_format (string) default value for --log-file-date-format addopts (args) extra command line options minversion (string) minimally required pytest version mock_traceback_monkeypatch (string) Monkeypatch the mock library to improve re mock_use_standalone_module (string) Use standalone "mock" (from PyPI) instead以下是常用的設定
- addopts
- 預設命令動作
addopts = -rsxX -l --tb=short --strict
- markers
- 註冊 markers 與 --strict 搭配使用,以免打錯字
markers = hot: hot run get: get function test
- 可用以下指令查詢
pytest --markers
- minversion
- 指定最小 pytest version
minversion = 3.0
- norecursedirs
- 不用尋找的檔案與資料夾,* 表示任意長度的值,空格隔開
; default: .* build dist CVS _darcs {arch} *.egg norecursedirs = .* venv src *.egg dist build
- testpaths
- 指定尋找的位置
testpaths = tests
- python_classes
python_files
python_functions - 更改尋找 test 的規則,* 表示任意長度的值,空格隔開
python_classes = *Test Test* *Suite python_files = test_* *_test check_* python_functions = test_* check_*
- xfail_strict
- 指定 xfail 的 function 測試 pass 時,視為 Error
xfail_strict = true
With Other Tools
pdb
pytest -v --lf -x --pdb
- p/print expr
- Prints the value of exp.
- pp expr
- Pretty prints the value of expr.
- l/list
- Lists the point of failure and five lines of code above and below.
- l/list begin,end: Lists specific line numbers.
- a/args
- Prints the arguments of the current function with their values. (This is helpful when in a test helper function.)
- u/up
- Moves up one level in the stack trace.
- d/down
- Moves down one level in the stack trace. q/quit: Quits the debugging session.
pytest-cov
pytest --cov=src # 可輸出 html 格式的報表 pytest --cov=src --cov-report=html
參考
Python Testing with pytestunittest.mock
pytest-cov’s documentation
留言
張貼留言