- 取得連結
- 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 中
test_advance.py
- # 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")
輸入 help 可看到已加入
- 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"))
pytest -h
custom options: --mybool boolean option --name=NAME name: abc or ABC
- cache
- 快取運用
test_advance.py
輸入指令,可看到 cache 存放的值
- 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())
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
留言
張貼留言