【轉】自動化測試框架pytest中文文檔:pytest入門基礎


幫助你更好的書寫程序

  • 成熟全功能的Python測試工具
    • 支持POSIX / Windows, Python的2.5-3.3 , PyPy和Jython - 2.5.1
    • 1000測試用例自測零bug。
    • pytest升級時有很好的向后兼容性
    • 豐富的在線和PDF文檔
    • 大量的第三方插件和內置幫助
    • 在許多小型和大型項目和組織使用
    • 許多測試實例
  • 靈活
    • 易學,有多種用法
    • assert語句斷言
    • 追蹤和失敗斷言報告
    • 打印調試和測試執行期間可以捕獲標准輸出
  • 適合簡單的單元測試到復雜的功能測試
    • 模塊化和參數化的平台
    • 參數化的測試函數
    • 支持屬性
    • Skip和xfail處理失敗的用例
    • xdist插件分發測試給多個CPU
    • 不斷地重新運行失敗的測試
    • 靈活的Python測試發現
  • 集成
    • 多范式:可以執行nose, unittest 和doctest風格的測試用例,甚至Django和trial。
    • 支持良好的集成實踐
    • 支持擴展的xUnit風格setup
    • 支持非python測試
    • 支持生成測試覆蓋率報告
    • 支持PEP8兼容的編碼風格
  • 擴展插件和定制系統:
    • 所有的收集,報告,運行方面都委派給hook函數
    • 定制可以是每個目錄,每個項目或每個PyPI上發布的插件
    • 很容易添加命令行選項或定制現有的行為

安裝和入門

  • 安裝
1 pip install -U pytest # or
2 easy_install -U pytest

檢查版本:

1 # py.test --version
2 This is pytest version 2.5.2, imported from /usr/lib/python2.7/site-packages/pytest.pyc
  • 第一個實例:

代碼:

1 # content of test_sample.py
2 def func(x):
3     return x + 1
4 def test_answer():
5     assert func(3) == 5

執行結果:

 1 # py.test
 2 =========================================================================================================== test session starts ===========================================================================================================
 3 platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
 4 collected 1 items 
 5 
 6 test_sample.py F
 7 
 8 ================================================================================================================ FAILURES =================================================================================================================
 9 _______________________________________________________________________________________________________________ test_answer _______________________________________________________________________________________________________________
10 
11     def test_answer():
12 >       assert func(3) == 5
13 E       assert 4 == 5
14 E        +  where 4 = func(3)
15 
16 test_sample.py:8: AssertionError
17 ======================================================================================================== 1 failed in 0.34 seconds =========================================================================================================

pytest通過標准測試發現規則發現test_answer函數,通常是查找 test_前綴。我們得到了一個故障報告,因為我們調用func(3)沒有返回5。pytest的高級內省斷言會智能報告assert的中間值,不需要記住那些JUnit傳統方法。

  • 異常斷言

代碼:

1 import pytest
2 def f():
3     raise SystemExit(1)
4 def test_mytest():
5     with pytest.raises(SystemExit):
6         f()

執行結果:

1 $ py.test -q test_sysexit.py
2 .
3 1 passed in 0.01 seconds

-q表示靜默模式:

1 -q, --quiet           decrease verbosity.
  • 在類中分組用例

代碼

1 # content of test_class.py
2 class TestClass:
3     def test_one(self):
4         x = "this"
5         assert 'h' in x
6         
7     def test_two(self):
8         x = "hello"
9         assert hasattr(x, 'check')

執行結果:

 1 # py.test test_class.py 
 2 =========================================================================================================== test session starts ===========================================================================================================
 3 platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
 4 collected 2 items 
 5 
 6 test_class.py .F
 7 
 8 ================================================================================================================ FAILURES =================================================================================================================
 9 ___________________________________________________________________________________________________________ TestClass.test_two ____________________________________________________________________________________________________________
10 
11 self = <test_class.TestClass instance at 0x265aef0>
12 
13     def test_two(self):
14         x = "hello"
15 >       assert hasattr(x, 'check')
16 E       assert hasattr('hello', 'check')
17 
18 test_class.py:12: AssertionError
19 =================================================================================================== 1 failed, 1 passed in 0.01 seconds ====================================================================================================
  • 功能測試示例:生成唯一的臨時目錄

功能測試經常需要創建一些文件,並將其傳遞給應用程序對象。pytest提供 Builtin fixtures/function 參數允許請求任意資源,例如唯一的臨時目錄:

1 def test_needsfiles(tmpdir):
2     print tmpdir
3     assert 0

執行結果:

 1 ]# py.test -q test_tmpdir.py
 2 FF
 3 ================================================================================================================ FAILURES =================================================================================================================
 4 _____________________________________________________________________________________________________________ test_needsfiles _____________________________________________________________________________________________________________
 5 
 6 tmpdir = local('/tmp/pytest-0/test_needsfiles0')
 7 
 8     def test_needsfiles(tmpdir):
 9         print tmpdir
10 >       assert 0
11 E       assert 0
12 
13 test_tmpdir.py:7: AssertionError
14 ------------------------------------------------------------------------------------------------------------- Captured stdout -------------------------------------------------------------------------------------------------------------
15 /tmp/pytest-0/test_needsfiles0
16 1 failed in 0.07 seconds

斷言的前面的print內容也會打印出來,測試時可以多加print語句,保證異常時輸出一些有用的信息。

下面方式可以查看內置的

 1 # py.test --fixtures
 2 
 3 =========================================================================================================== test session starts ===========================================================================================================
 4 platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
 5 collected 5 items 
 6 capsys
 7     enables capturing of writes to sys.stdout/sys.stderr and makes
 8     captured output available via ``capsys.readouterr()`` method calls
 9     which return a ``(out, err)`` tuple.
10     
11 capfd
12     enables capturing of writes to file descriptors 1 and 2 and makes
13     captured output available via ``capsys.readouterr()`` method calls
14     which return a ``(out, err)`` tuple.
15     
16 monkeypatch
17     The returned ``monkeypatch`` funcarg provides these
18     helper methods to modify objects, dictionaries or os.environ::
19     
20     monkeypatch.setattr(obj, name, value, raising=True)
21     monkeypatch.delattr(obj, name, raising=True)
22     monkeypatch.setitem(mapping, name, value)
23     monkeypatch.delitem(obj, name, raising=True)
24     monkeypatch.setenv(name, value, prepend=False)
25     monkeypatch.delenv(name, value, raising=True)
26     monkeypatch.syspath_prepend(path)
27     monkeypatch.chdir(path)
28     
29     All modifications will be undone after the requesting
30     test function has finished. The ``raising``
31     parameter determines if a KeyError or AttributeError
32     will be raised if the set/deletion operation has no target.
33     
34 pytestconfig
35     the pytest config object with access to command line opts.
36 recwarn
37     Return a WarningsRecorder instance that provides these methods:
38     
39     * ``pop(category=None)``: return last warning matching the category.
40     * ``clear()``: clear list of warnings
41     
42     See http://docs.python.org/library/warnings.html for information
43     on warning categories.
44     
45 tmpdir
46     return a temporary directory path object
47     which is unique to each test function invocation,
48     created as a sub directory of the base temporary
49     directory.  The returned object is a `py.path.local`_
50     path object.
51     
52 
53 ============================================================================================================  in 0.02 seconds =============================================================================================================

使用和調用

  • python -m pytest調用:
    • python -m pytest [...] 效果和py.test [...] 一樣
  • 獲取版本,選項名,環境變量
    • py.test --version 看版本
    • py.test --fixtures 查看內置參數
    • py.test -h | --help 命令行和配置文件幫助
  • 失敗后停止
    • 首次失敗后停止執行:py.test -x
    • py.test --maxfail=2 兩次失敗之后停止執行
  • 執行選擇用例
    • py.test test_mod.py,執行模塊中的用例
    • py.test somepath,執行路徑中用例
    • py.test -k stringexpr,執行字符串表達式中的用例,比如"MyClass? and not method",選擇TestMyClass.test_something,排除了TestMyClass.test_method_simple。
    • py.test --pyargs pkg,導入pkg,使用其文件系統位置來查找和執行用例。執行pypkg目錄下的所有用例。
  • 調試輸出:
    • py.test --showlocals 在traceback中顯示本地變量
    • py.test -l 在traceback中顯示本地變量(快捷方式)
    • py.test --tb=long 默認的traceback信息格式化形式
    • py.test --tb=native 標准庫格式化形式
    • py.test --tb=short 更短的格式
    • py.test --tb=line 每個錯誤一行
  • 失敗時調用PDB (Python Debugger):

Python帶有一個內置的Python調試器稱為PDB。pytest可以在命令行選項指定調用:

py.test --pdb 

這將每次失敗時調用Python調試器。

py.test -x --pdb # 失敗時調用pdb,然后退出測試。 py.test --pdb - maxfail=33次失敗調用pdb
  • 設置斷點:
1 import pytest
2 def test_function():
3     ...
4     pytest.set_trace() # invoke PDB debugger and tracing

以前的版本中只有通過py.test-s禁用命令行捕捉才可以進入pdb調試。

  • Profiling測試執行時間:得到最執行慢的10個測試:
py.test --durations=10 
  • 創建JUnitXML格式的文件

創建Hudson或其他持續集成服務器的結果文件:

py.test --junitxml=path 
  • 創建resultlog格式的文件

要創建純文本的機器可讀的結果文件,用於PyPy-testweb展示等。

py.test --resultlog=path 
  • 發送測試報告給在線pastebin服務

bpaste可以為你的文本生成url連接,下面為創建每個測試失敗創建一個url:

py.test --pastebin=failed py.test --pastebin=all py.test --pastebin=failed -x 

目前只支持:py.test --pastebin=failed

  • 禁用插件
    py.test -p no:doctest 
  • 在python代碼中調用pytest
    1 pytest.main([’-x’, ’mytestdir’])
    2 pytest.main("-x mytestdir")
    3 # 指定插件
    4 # content of myinvoke.py
    5 import pytest
    6 class MyPlugin:
    7     def pytest_sessionfinish(self):
    8         print("***test run reporting finishing")
    9 pytest.main("-qq", plugins=[MyPlugin()])

執行結果:

1 $ python myinvoke.py
2 ***
3 test run reporting finishing

好的集成實踐

  • 使用虛擬環境
 1 #virtualenv .
 2 New python executable in ./bin/python
 3 Installing setuptools, pip...done.
 4 root@AutoTest:[/data/code/python/pytest]#source bin/activate
 5 (pytest)root@AutoTest:[/data/code/python/pytest]#pip install pytest
 6 Downloading/unpacking pytest
 7   Downloading pytest-2.5.2.tar.gz (608kB): 608kB downloaded
 8   Running setup.py (path:/data/code/python/pytest/build/pytest/setup.py) egg_info for package pytest
 9     
10 Downloading/unpacking py>=1.4.20 (from pytest)
11   Downloading py-1.4.22.tar.gz (189kB): 189kB downloaded
12   Running setup.py (path:/data/code/python/pytest/build/py/setup.py) egg_info for package py
13     
14 Installing collected packages: pytest, py
15   Running setup.py install for pytest
16     
17     Installing py.test-2.7 script to /data/code/python/pytest/bin
18     Installing py.test script to /data/code/python/pytest/bin
19   Running setup.py install for py
20     
21 Successfully installed pytest py
22 Cleaning up...
  • 測試布局和導入規則

測試布局的方法有2種。一為放置在應用代碼之外,適用於有很多功能測試等情況。

setup.py # your distutils/setuptools Python package metadata
mypkg/
__init__.py
appmodule.py
tests/
test_app.py
...

 

二為嵌入測試目錄到應用,當(單元)測試和應用之間的有直接關系,並想一起發布時有用:

setup.py # your distutils/setuptools Python package metadata
mypkg/
__init__.py
appmodule.py
...
test/
test_app.py
...

---未完待續

原文地址


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM