pytest 入門學習

Pytest 入門學習

pytest是一個非常成熟的全功能的Python測試框架,主要特點有以下幾點:

簡單靈活,容易上手;

支持參數化;

能夠支持簡單的單元測試和復雜的功能測試,還可以用來做selenium/appnium等自動化測試、接口自動化測試(pytest+requests);

pytest具有很多第三方插件,并且可以自定義擴展,比較好用的如pytest-selenium(集成selenium)、pytest-html(完美html測試報告生成)、pytest-rerunfailures(失敗case重復執行)、pytest-xdist(多CPU分發)等;

測試用例的skip和xfail處理;

可以很好的和jenkins集成;

一、安裝

安裝

pip install -U pytest

檢查是否安裝成功

pytest --version

This is pytest version 4.5.0, imported from c:\python27\lib\site-packages\pytest.pyc

查看幫助命令

pytest -h

二、快速入門

創建一個test_sample.py

def func(x):

     return x + 1

class TestCase():

     def test_answer(self):

           assert func(3) == 5

運行用例

命令行通過以下命令運行:

  1. 運行所有文件:pytest

  2. 運行單個文件:pytest test_sample.py

運行結果:

結論:

從上面看出,當用例運行失敗時,會在控制臺打印具體的錯誤信息,包含用例信息及具體錯誤代碼和預期結果。錯誤信息一目了然。

非命令行運行

代碼右鍵運行或直接從pytest.main()運行,返回結果如下:

三、pytest用例識別

pytest會找當前以及遞查找子文件夾下面所有的test_.py或_test.py的文件,把其當作測試文件
在這些文件里,pytest會收集下面的一些函數或方法,當作測試用例:

1、不在類定義中的以test_開頭的函數或方法
2、在以Test開頭的類中(不能包含init方法),以test_開頭的方法
3、pytest也支持unittest模式的用例定義

四、運行用例

1、運行單個用例

使用命令,pytest+文件名 運行,如運行test_class.py

pytest test_class.py

2、運行多個用例

運行多個用例,使用命令pytest

3、運行指定用例

3.1通過匹配關鍵字,運行用例

使用命令,pytest -k keyword 運行指定關鍵字用例

3.2通過用例標記,運行用例

1)用例標記:pytest允許為測試用例添加屬性通過 pytest markers,@pytest.mark,定義方法: @pytest.mark.<name>

2)運行標記的用例,如運行被標記falled的用例:pytest -m falled

結論:

由上圖可看出,文件中被標記為falled的用例被執行。

3、運行文件夾下的用例

使用命令,pytest + 文件夾,可運行該文件夾下的用例,如運行testing文件夾下的用例

結論:

通過 pytest+文件名/ 命令,可運行該文件夾下的所有用例。

4、運行模塊下類內指定的用例

使用命令,pytest+文件名+類名+方法名,指定運行測試用例,格式為:pytest::test_.py::Test::test

結論:

由上圖可以看到,使用命令 pytest::test_sample.py::TestCase::test01,可以運行test_sample.py文件中TestCase類下的test01方法。

五、運行用例,顯示指定結果信息

運行測試用例,顯示總的結果信息,使用命令 pytest -ra

運行測試用例,顯示通過的結果信息,使用命令 pytest -rp

運行測試用例,顯示錯誤結果信息警告信息,使用命令 pytest -rE

運行測試用例,顯示跳過結果信息,使用命令 pytest -rs

======================== short test summary info ========================

SKIPPED [1] test_skip_case.py:4: unconditional skip

SKIPPED [1] test_skip_case.py:9: unconditional skip

六、環境準備和環境清理

pytest使用Fixture功能為測試用例進行環境準備和環境清理,相當于unittest中的setup\teardown,

setupClass\teardownClass。同時對于傳統的setup/teardown函數做了顯著的改進:

1)測試fixture有明確的名稱,通過在函數/模塊/類或者整個項目中激活來使用。

2)測試fixture是模塊化的實現,使用fixture名即可觸發特定的fixture,fixture可以在其他fixture中進行使用

3)測試fixture不僅可以進行簡單的單元測試,也可以進行復雜的功能測試。可以根據配置和組件的選項進行參數化定制測試,或者跨函數/類/模塊或者整個測試過程進行測試。

1、環境準備

使用@pytest.fixture裝飾器來設置一個函數為測試fixture,后面的測試函數調用到fixture名稱時,pytest會檢測到該fixture并加載其中的數據作為參數傳入。定義fixture的方式:在單個測試文件中定義

、多個文件共享fixture、通過設置fixture中的scope指定作用范圍定義,格式為@pytest.fixture(scope=session/module/class/function),其中作用范圍大小為:session>module>class>function。具體實現詳見例子~

1.1單個函數定義fixture

1)創建一個文件test_fixture01.py

@pytest.fixture()  # 定義some_data函數為測試fixture

def some_data():

       return 42

def test_some_data(some_data):  # 測試函數調用some_data,并做斷言

       assert some_data == 42

2)調用并執行以上文件:執行命令 pytest --setup-show test_fixture01.py

E:\自動化\pytest框架學習\learn_fixture>pytest --setup-show test_fixture01.py

========================test session starts ============================

platform win32 -- Python 3.7.2, pytest-5.2.2, py-1.8.0, pluggy-0.13.0

rootdir: E:\樂乎自動化\pytest框架學習\learn_fixture

plugins: forked-1.1.1, html-2.0.0, metadata-1.8.0, xdist-1.30.0

collected 1 item

test_fixture01.py

SETUP F some_data

test_fixture01.py::test_some_data (fixtures used: some_data).

TEARDOWN F some_data

========================== 1 passed in 0.12s ==========================

結論:

由上執行結果可以看到,在執行test_some_data用例時,test_some_data調用了測試fixture some_data,并在用例執行前后進行了setup和teardown操作。

1.2多個文件共享fixture

在測試用例實現過程中,當需要使用來自多個文件的fixture時,可以將這些fixture函數寫到conftest.py文件中。使用時,不需要導入fixture函數,pytest會自動檢索。

fixture函數的使用從測試類開始,到測試模塊,然后是conftest.py文件,然后是內置的插件和第三方插件。也可以使用conftest為本地目錄實現插件。

1)修改test_fixture01.py文件,分別改為兩個文件,將測試fixture函數存入到conftest.py文件中,測試函數另起一個文件為test_fixture02.py

content of conftest.py

@pytest.fixture()  # 定義some_data函數為測試fixture

def some_data():

       return 42

content of test_fixture02.py

 def test_some_data(some_data):  # 測試函數調用some_data,并做斷言

        assert some_data == 42

2)執行多個文件:執行命令 pytest --setup-show test_fixture01.py test_fixture02.py

結論:

由上圖執行結果可看到,當將測試fixture函數放在conftest.py文件中,測試用例調用時,可實現多個文件共享fixture函數。

1.3通過設置fixture中的scope指定作用范圍

1)指定@pytest.fixture(scope="function"),執行文件時,所有測試文件的每個function函數執行時都會調用fixture函數一次。【不指定情況下,默認為funtion】

結論:

當設置scope="funtion"時,每個用例執行前后都會調用一次function。

2)指定@pytest.fixture(scope="class"),執行文件時,每個類執行前后只調用測試fixture一次。

結論:

當設置sope="class"時,在調用類時,只調用一次funtion。

3)指定@pytest.fixture(scope="module"),執行文件時,只調用fixture一次

創建一個test_fixture04.py包含兩個類及一個測試函數,并執行文件:

結論:

從上圖可以看到,在執行測試文件時,執行前和執行后只進行了一次funtion的調用。

4)指定@pytest.fixture(scope="session"),執行一個會話時,只調用fixture一次。

注:一個會話是一次文件的調用,可以同時調用多個文件。

結論:

當設置scope="session"時,只是在整個會話開始前和結束后調用一次function。

2、環境清理

pytest支持在fixture退出作用域的時候執行相關的清理/結束代碼。使用yield而不是return關鍵字的時候,yield后面的語句將會在fixture退出作用域的時候被調用來清理測試用例。

1)創建一個文件test_fixture06.py,包含test fixture和test function兩部分

import pytest

@pytest.fixture(scope=**"module"**)
def something():

      print(**"**\n**哈哈哈哈****"**)   # setup部分數據

      yield              # 使用yield后面的語句將會在fixture退出作用域的時候被調用來清理測試用例

      print(**"****結束了?****"**)

 def test_smtp(something):

      print(**"****測試中。。。。****"**)

2)運行文件:pytest -s test_fixture06.py

七、設置斷言

斷言,每個測試用例都需要斷言。unittest中使用unittest自帶的斷言機制,與unittest不同的時,pytest使用的是python自帶的assert關鍵字來進行斷言。

assert關鍵字后面可以接一個表達式,只要表達式的最終結果為True,那么斷言通過,用例執行成功,否則用例執行失敗。斷言失敗有詳細的用例失敗描述。

1、斷言

代碼:

def f():

      return 3

def test_function():

      assert f() == 4

執行結果:

總結:

從執行結果可以看到,用例斷言失敗了,且有詳細的失敗信息描述,可以一眼看出是哪兒出了問題。

2、斷言異常拋出

八、用例參數化

參數化測試是用于一些測試流程一樣,測試數據不同的測試用例,以此來簡化代碼。

pytest支持使用fixture中通過param="參數集"初始化需要傳入的參數,再將fixture作為參數傳入用例中實現參數化。也可通過使用parametrize支持多個參數化傳入。

1、參數化fixture(參數化1個)

校驗用戶弱密碼~

users文件:

[

 {"name":"jack","password":"Iloverose"},

 {"name":"rose","password":"Ilovejack"},

 {"name":"tom","password":"password123"},

 {"name":"mike","password":"password"},

 {"name":"james","password":"AGoodPasswordWordShouldBeLongEnough"}

 ]

用例文件:

   '''用例需求:

    校驗多個用戶、密碼是否存在弱密碼。

    用例設計:

    使用參數化形式,一個測試方法傳入user集參數,使用例一次性校驗所有用戶 
    是否存在弱密碼。

 '''

import pytest

import json

users = json.loads(open(**'./user.json'**, **'r'**).read())  # 從user.json文件中讀取出用戶數據

class TestUserPasswordWithParam():

@pytest.fixture(params=users)    # 將user作為參數傳入,并返回user中的每個用戶信息。再將此fixture作為參數傳入到用例中數據

def user(self, request):

    user_info = request.param         # 使用request.param從users中一個一個地拿出數據并返回

    return user_info

def test_user_password(self, user):

    password = user[**'password'**]

    assert len(password) >= 6

    msg = **"****用戶****%s****存在弱密碼****"** % (user[**'name'**])

    assert password != **'password'**, msg

    assert password != **'password123'**, msg

測試結果:

總結:

從上面運行結果可以看到,用例一共運行了5次。

2、parametrize多參數(參數化多個)

此功能,類似unittest中的ddt數據驅動模式

@pytest.mark.parametrize 裝飾器可以讓我們每次參數化fixture的時候傳入多個項目

校驗算數加法:

import pytest

@pytest.mark.parametrize(

**"a,b,c"**,             # 參數名---多個參數

[(1, 2, 3),          # 參數值---參數值與參數對應,可傳入多個需要校驗的參數值

 (3, 4, 7),

 (5, 6, 11)]

)

def test_add(a, b, c):

       assert a+b == c

測試結果:

總結:

加法校驗case中,傳入了3組參數值,實際用例也運行了3次,每次取不同的數據。

九、跳過用例

當遇到不想運行的用例,可對該用例標記為跳過,在執行測試時,會自動跳轉被標記的用例。使用

@pytest.mark.skip 標記跳過用例,使用@pytest.mark.xfail 標記用例時,則用例失敗執行失敗后,無任何錯誤信息。

下面的詳細的用例代碼:

test_skip_case.py

 import pytest

@pytest.mark.skip    # skip標記跳過用例,不執行
def test_add_1():

        assert 100 + 200 == 400, **"failed"**

@pytest.mark.skip
def test_add_2():

        assert 100 + 200 == 300, **"failed"**

 @pytest.mark.xfail   # xfail標記執行用例,但是不統計執行結果
 def test_add_3():

       assert 15 + 13 == 28, **"passed"**

 @pytest.mark.xfail
 def test_add_4():

      assert 15 + 13 == 100, **"failed"**

 def test_add_5():

      assert 3 + 2 == 5, **"passed"**

 def test_add_6():

       assert 3 + 2 == 6, **"failed"**

執行用例:pytest -v test_skip_case.py

[圖片上傳失敗...(image-f7e8d5-1573551303032)]

可以看到,測試用例文件中,前兩個用例未執行,第三、四個執行了,且第三個執行失敗了,未收集失敗信息。第五、第六個正常執行,第六個執行失敗,顯示具體的失敗追蹤信息。

十、生成測試報告

1、生成HTML格式的測試報告

生成html格式的測試報告,需要用例到插件pytest-html。具體步驟如下:

1)安裝插件:pip install pytest-html

2)執行測試并生成測試報告:pytest -v -s --html=report.html

2、生成XML格式的測試報告

生成junit格式的xml報告,在命令行中加入--junit-xml=path 參數就可以了.

pytest -v --junit-xml=report.xml

十一、常見命令行參數

參考:
https://blog.csdn.net/lb245557472/article/details/90341297)
http://www.testclass.net/pytest
https://blog.csdn.net/crazyskady
http://pytest.org/en/latest/contents.html
https://www.bilibili.com/video/av59183665/

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374