iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 27
0
Software Development

python 自學系列 第 27

python day27(pytest)

  • 分享至 

  • xImage
  •  

今天來介紹 python 的測試模組 pytest

先安裝 pytest.

pip3 install pytest

檢查 pytest version

> pytest --version
This is pytest version 5.2.1, imported from /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pytest.py

建立一支 test_sum.py

def sum(num1,num2):
 return num1 + num2

def test_sum_int():
 assert sum(1,2) == 3

def test_sum_str():
 assert sum('1','2') == '12'

接著就執行 pytest 指令,會抓開頭是 test_xxx.py 的程式來執行.如果執行測試都有過的話,看下面 output 內容可以看到有一行 test_sum.py .. 有兩個點,一個點代表成功的測試 function.

> pytest
============================== test session starts ===============================
platform darwin -- Python 3.7.4, pytest-5.2.1, py-1.8.0, pluggy-0.13.0
rootdir: /Volumes/Transcend/pylearn
collected 2 items

test_sum.py ..                                                             [100%]

=============================== 2 passed in 0.09s ================================

故意讓第一個測試 function 不過,可以看到第一個點變成 F 了,然後會說那邊程式出錯.

pytest
============================== test session starts ===============================
platform darwin -- Python 3.7.4, pytest-5.2.1, py-1.8.0, pluggy-0.13.0
rootdir: /Volumes/Transcend/pylearn
collected 2 items

test_sum.py F.                                                             [100%]

==================================== FAILURES ====================================
__________________________________ test_sum_int __________________________________

    def test_sum_int():
>    assert sum(1,2) == 1
E    assert 3 == 1
E     +  where 3 = sum(1, 2)

test_sum.py:5: AssertionError
========================== 1 failed, 1 passed in 0.13s ===========================

產生 JUnitXML report

pytest --junit-xml=/Volumes/Transcend/pylearn/sum_test_report.xml

sum_test_report.xml 內容

<testsuites>
    <testsuite errors="0" failures="1" hostname="Danielde-MBP" name="pytest" skipped="0" tests="2" time="0.064" timestamp="2019-10-07T19:08:36.505058">
    <testcase classname="test_sum" file="test_sum.py" line="3" name="test_sum_int" time="0.001">
    <failure message="assert 3 == 1 + where 3 = sum(1, 2)">
    def test_sum_int(): > assert sum(1,2) == 1 E assert 3 == 1 E + where 3 = sum(1, 2) test_sum.py:5: AssertionError
    </failure>
    </testcase>
    <testcase classname="test_sum" file="test_sum.py" line="6" name="test_sum_str" time="0.001"/>
    </testsuite>
</testsuites>

當遇到第一個錯誤就停下來,後面的不繼續執行

> pytest -x
============================== test session starts ===============================
platform darwin -- Python 3.7.4, pytest-5.2.1, py-1.8.0, pluggy-0.13.0
rootdir: /Volumes/Transcend/pylearn
collected 2 items

test_sum.py F

==================================== FAILURES ====================================
__________________________________ test_sum_int __________________________________

    def test_sum_int():
>    assert sum(1,2) == 1
E    assert 3 == 1
E     +  where 3 = sum(1, 2)

test_sum.py:5: AssertionError
=============================== 1 failed in 0.05s ================================

遇到兩個錯誤就停下來後面不繼續執行.

pytest --maxfail=2

-vv 代表印出詳細資訊,--durations=0代表執行時間大於 0 的測試.

pytest -vv --durations=0
============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7
cachedir: .pytest_cache
rootdir: /Volumes/Transcend/pylearn
collected 2 items

test_sum.py::test_sum_int PASSED                                         [ 50%]
test_sum.py::test_sum_str PASSED                                         [100%]

============================ slowest test durations ============================
0.00s setup    test_sum.py::test_sum_int
0.00s teardown test_sum.py::test_sum_int
0.00s call     test_sum.py::test_sum_int
0.00s setup    test_sum.py::test_sum_str
0.00s teardown test_sum.py::test_sum_str
0.00s call     test_sum.py::test_sum_str
============================== 2 passed in 0.02s ===============================

使用@pytest.mark.parametrize建立多個測試參數值,名稱要對應到參數名稱.

def sum(num1,num2):
 return num1 + num2

import pytest

@pytest.mark.parametrize(
 'num1,num2,eq_num',
 [
  (1,2,3),
  (4,5,9),
  (0,0,0)
 ]
)

def test_multi_sum(num1,num2,eq_num):
 assert sum(num1,num2) == eq_num

執行結果

> pytest -vv --durations=0
============================= test session starts ==============================
platform darwin -- Python 3.7.4, pytest-5.2.1, py-1.8.0, pluggy-0.13.0 -- /Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7
cachedir: .pytest_cache
rootdir: /Volumes/Transcend/pylearn
collected 3 items

test_sum.py::test_multi_sum[1-2-3] PASSED                                [ 33%]
test_sum.py::test_multi_sum[4-5-9] PASSED                                [ 66%]
test_sum.py::test_multi_sum[0-0-0] PASSED                                [100%]

============================ slowest test durations ============================
0.00s setup    test_sum.py::test_multi_sum[1-2-3]
0.00s setup    test_sum.py::test_multi_sum[0-0-0]
0.00s setup    test_sum.py::test_multi_sum[4-5-9]
0.00s teardown test_sum.py::test_multi_sum[1-2-3]
0.00s call     test_sum.py::test_multi_sum[1-2-3]
0.00s teardown test_sum.py::test_multi_sum[0-0-0]
0.00s teardown test_sum.py::test_multi_sum[4-5-9]
0.00s call     test_sum.py::test_multi_sum[0-0-0]
0.00s call     test_sum.py::test_multi_sum[4-5-9]
============================== 3 passed in 0.05s ===============================

上一篇
python day26(crawler)
下一篇
python day28(Pandas)
系列文
python 自學30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言