日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

pytest单侧模块_入门汇总

發布時間:2023/12/2 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pytest单侧模块_入门汇总 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Pytest簡單介紹

(pytest是python的一個測試框架,主要是用來進行一些小的測試)

  • 安裝:pip install -U pytest
  • 查看是否安裝成功:pytest --version
  • 運行:在當前文件所在目錄下執行pytest,會尋找當前目錄以及子目錄下以test開頭的py文件或者以test結尾的py文件,找到文件后,在文件中找到以test開頭函數并執行。(或者執行pytest 文件名--這樣可以指定某個文件進行pytest的測試? 或者? python -m pytest xxx.py)

在執行pytest xxx.py時,若增加參數:pytest -v -s xxx.py? ?(-v:顯示運行的函數;-s:顯示內部的打印信息)

  • 編寫pytest測試樣例的規則:
  • 測試文件以test_開頭
  • 測試類以Test開頭,并且不能帶有init方法
  • 測試函數以test_開頭
  • 斷言使用基本的assert即可
  • 斷言--正常:
assert value == 0
  • 斷言--異常(pytest.raise方法):
1 #斷言1除以0,將產生一個ZeroDivisionError類型的異常。 2 import pytest 3 def test_zero_division(): 4 with pytest.raises(ZeroDivisionError): 5 1 / 0 6 7 #有的時候,我們可能需要在測試中用到產生的異常中的某些信息,比如異常的類型type,異常的值value等等。下面我們修改下上面的測試: 8 import pytest 9 def test_recursion_depth(): 10 with pytest.raises(ZeroDivisionError) as excinfo: 11 1/0 12 assert excinfo.type == 'RuntimeError' 13 #因為該測試斷言產生的異常類型是RuntimeError,而實際上產生的異常類型是ZeroDivisionError,所以測試失敗了。在測試結果中,可以看到assert子表達式excinfo.type的值。
  • 在test前,可以通過增加skip或xfail進行跳過(失敗)測試案例
1 import pytest 2 3 # @pytest.mark.skipif() 跳過 4 # @pytest.mark.skip() 跳過 5 # @pytest.mark.xfail() 若出錯跳過,pass也跳過,但會顯示pass 6 def test_123(): 7 # pytest.skip() 也可以實現'跳過'目的 8 assert 1 == 0
  • 簡單例子:
1 # coding:utf-8 2 import pytest 3 4 def fun(x): 5 return x + 1 6 7 def test_fun(): 8 assert fun(2) == 3

結果:

(venvX) F:\test_jiaxin>pytest test_para1.py ============================= test session starts ============================= platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1 rootdir: F:\test_jiaxin, inifile: plugins: allure-adaptor-1.7.10 collected 1 item test_para1.py . [100%]========================== 1 passed in 0.09 seconds ===========================

pytest之feature-scope

  • function:每個test都運行,默認是function的scope.
  • class:每個class的所有test只運行一次.
  • module:每個module的所有test只運行一次.
  • session:每個session只運行一次.

比如你的所有test都需要連接同一個數據庫,那可以設置為module,只需要連接一次數據庫,對于module內的所有test,這樣可以極大的提高運行效率。

代碼:

1 @pytest.fixture(scope="module") 2 def hero_backup_policy(self, acmp_cfg): 3 return AcloudBackupPolicy(acmp_cfg) 4 5 @pytest.fixture(scope="function") 6 def hero_acloud_backup_policy(self, acmp_cfg): 7 return Server(acmp_cfg)

pytest的參數化方式

  • pytest.fixture()方式進行參數化,fixture裝飾的函數可以作為參數傳入其他函數

  • conftest.py 文件中存放參數化函數,可作用于模塊內的所有測試用例

  • pytest.mark.parametrize()方式進行參數化

?

待測試代碼片段:(is_leap_year.py)

1 # coding:utf-8 2 def is_leap_year(year): 3 # 先判斷year是不是整型 4 if isinstance(year, int) is not True: 5 raise TypeError("傳入的參數不是整數") 6 elif year == 0: 7 raise ValueError("公元元年是從公元一年開始!!") 8 elif abs(year) != year: 9 raise ValueError("傳入的參數不是正整數") 10 elif (year % 4 == 0 and year % 100 != 0) or year % 400 == 0: 11 print"%d年是閏年" % year 12 return True 13 else: 14 print"%d年不是閏年" % year 15 return False
  • pytest.fixture()

  • pytest.fixture()中傳入的參數為list,用例執行時,遍歷list中的值,每傳入一次值,則相當于執行一次用例。

  • @pytest.fixture()裝飾的函數中,傳入了一個參數為request。

  • 這里的測試數據是直接存在list中的,能否存入json文件或者xml文件再進行讀取轉換為list呢?

  • 代碼:

    1 # coding:utf-8 2 import is_leap_year 3 import pytest 4 5 class TestPara(): 6 is_leap = [4, 40, 400, 800, 1996, 2996] 7 is_not_leap = [1, 100, 500, 1000, 1999, 3000] 8 is_valueerror = [0, -4, -100, -400, -1996, -2000] 9 is_typeerror = ['-4', '4', '100', 'ins', '**', '中文'] 10 11 @pytest.fixture(params=is_leap) 12 def is_leap(self, request): 13 return request.param 14 15 @pytest.fixture(params=is_typeerror) 16 def is_typeerror(self, request): 17 return request.param 18 19 def test_is_leap(self, is_leap): 20 assert is_leap_year.is_leap_year(is_leap) == True 21 22 def test_is_typeerror(self, is_typeerror): 23 with pytest.raises(TypeError): 24 is_leap_year.is_leap_year(is_typeerror)
    • conftest.py 文件 -- 測試數據與用例分離

  • 采用conftest.py文件存儲參數化數據和函數,模塊下的用例執行時,會自動讀取conftest.py文件中的數據。
  • 代碼:

    conftest.py文件
    1
    # coding:utf-8 2 import pytest 3 4 is_leap = [4, 40, 400, 800, 1996, 2996] 5 is_not_leap = [1, 100, 500, 1000, 1999, 3000] 6 is_valueerror = [0, -4, -100, -400, -1996, -2000] 7 is_typeerror = ['-4', '4', '100', 'ins', '**', '中文'] 8 9 @pytest.fixture(params=is_leap) 10 def is_leap(request): 11 return request.param 12 13 @pytest.fixture(params=is_typeerror) 14 def is_typeerror(request): 15 return request.param test_para.py文件
    1
    # coding:utf-8 2 3 import is_leap_year 4 import pytest 5 6 class TestPara(): 7 def test_is_leap(self, is_leap): 8 assert is_leap_year.is_leap_year(is_leap) == True 9 10 def test_is_typeerror(self, is_typeerror): 11 with pytest.raises(TypeError): 12 is_leap_year.is_leap_year(is_typeerror)
    • pytest.mark.parametrize() -- 進行參數化

  • 采用標記函數參數化,傳入單個參數,pytest.mark.parametrize("參數名",lists)。
  • 采用標記函數傳入多個參數,如pytest.mark.parametrize("para1, para2", [(p1_data_0, p2_data_0), (p1_data_1, p2_data_1),...]。
  • 這里:測試用例中傳入2個參數,year和期望結果,使輸入數據與預期結果對應,構造了2組會失敗的數據,在執行結果中,可以看到失敗原因。
  • 代碼:

    1 # coding:utf-8 2 import is_leap_year 3 import pytest 4 5 class TestPara(): 6 # 參數傳入year中 7 @pytest.mark.parametrize('year, expected', [(1, False), (4,True), (100, False), (400, True), (500, True)]) 8 def test_is_leap(self, year, expected): 9 assert is_leap_year.is_leap_year(year) == expected 10 11 @pytest.mark.parametrize('year, expected', [(0, ValueError),('-4', TypeError), (-4, ValueError), ('ss', TypeError), (100.0, ValueError)]) 12 def test_is_typeerror(self, year, expected): 13 if expected == ValueError: 14 with pytest.raises(ValueError) as excinfo: 15 is_leap_year.is_leap_year(year) 16 assert excinfo.type == expected 17 else: 18 with pytest.raises(TypeError) as excinfo: 19 is_leap_year.is_leap_year(year) 20 assert excinfo.type == expected

    參考鏈接:https://blog.csdn.net/zhusongziye/article/details/79902772

    ?

    pytest-fixture擴展內容

    1.??把一個函數定義為Fixture很簡單,只能在函數聲明之前加上“@pytest.fixture”。其他函數要來調用這個Fixture,只用把它當做一個輸入的參數即可。

    1 import pytest 2 3 @pytest.fixture() 4 def before(): 5 print '\nbefore each test' 6 7 def test_1(before): 8 print 'test_1()' 9 10 def test_2(before): 11 print 'test_2()'

    result:

    (venvX) F:\test_jiaxin>pytest -v -s test_compute.py ============================= test session starts ============================= platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1 -- f:\projects\sandom\venvx\scripts\python.exe cachedir: .pytest_cache rootdir: F:\test_jiaxin, inifile: plugins: allure-adaptor-1.7.10 collected 2 items test_compute.py::test_1 before each test test_1() PASSED test_compute.py::test_2 before each test test_2() PASSED========================== 2 passed in 0.17 seconds ===========================

    ?

    2.? 進行封裝

    1 import pytest 2 3 @pytest.fixture() 4 def before(): 5 print '\nbefore each test' 6 7 # 每個函數前聲明 8 @pytest.mark.usefixtures("before") 9 def test_1(): 10 print 'test_1()' 11 @pytest.mark.usefixtures("before") 12 def test_2(): 13 print 'test_2()' 14 15 #封裝在類里,類里的每個成員函數聲明 16 class Test1: 17 @pytest.mark.usefixtures("before") 18 def test_3(self): 19 print 'test_1()' 20 @pytest.mark.usefixtures("before") 21 def test_4(self): 22 print 'test_2()' 23 24 #封裝在類里在前聲明 25 @pytest.mark.usefixtures("before") 26 class Test2: 27 def test_5(self): 28 print 'test_1()' 29 def test_6(self): 30 print 'test_2()'

    result:

    (venvX) F:\test_jiaxin>pytest -v -s test_compute.py ============================= test session starts ============================= platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1 -- f:\projects\sandom\venvx\scripts\python.exe cachedir: .pytest_cache rootdir: F:\test_jiaxin, inifile: plugins: allure-adaptor-1.7.10 collected 6 items test_compute.py::test_1 before each test test_1() PASSED test_compute.py::test_2 before each test test_2() PASSED test_compute.py::Test1::test_3 before each test test_1() PASSED test_compute.py::Test1::test_4 before each test test_2() PASSED test_compute.py::Test2::test_5 before each test test_1() PASSED test_compute.py::Test2::test_6 before each test test_2() PASSED========================== 6 passed in 0.11 seconds ===========================

    ?

    3.??fixture還可以帶參數,可以把參數賦值給params,默認是None。對于param里面的每個值,fixture都會去調用執行一次,就像執行for循環一樣把params里的值遍歷一次。

    1 import pytest 2 3 @pytest.fixture(params=[1, 2, 3]) 4 def test_data(request): 5 return request.param 6 7 def test_not_2(test_data): 8 print('test_data: %s' % test_data) 9 assert test_data != 2

    result:

    (venvX) F:\test_jiaxin>pytest -v -s test_compute.py ============================= test session starts ============================= platform win32 -- Python 2.7.9, pytest-3.7.1, py-1.5.3, pluggy-0.7.1 -- f:\projects\sandom\venvx\scripts\python.exe cachedir: .pytest_cache rootdir: F:\test_jiaxin, inifile: plugins: allure-adaptor-1.7.10 collected 3 items test_compute.py::test_not_2[1] test_data: 1 PASSED test_compute.py::test_not_2[2] test_data: 2 FAILED test_compute.py::test_not_2[3] test_data: 3 PASSED================================== FAILURES =================================== ________________________________ test_not_2[2] ________________________________test_data = 2def test_not_2(test_data):print('test_data: %s' % test_data) > assert test_data != 2 E assert 2 != 2test_compute.py:64: AssertionError ===================== 1 failed, 2 passed in 0.12 seconds ======================

    ?

    轉載于:https://www.cnblogs.com/sunshine-blog/p/9468399.html

    總結

    以上是生活随笔為你收集整理的pytest单侧模块_入门汇总的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。