Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 日韩视频一区二区,91精选国产,在线播放你懂

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          從0到1上手Pytest

          從0到1上手Pytest


          如果你想快速上手pytest,只關注"Pytest必會知識點"章節就可以了(該章節已經能夠解決基礎的ui和接口自動化測試需求);

          如果你想要詳細了解關于Fixture的使用方法,請關注"pytest高級用法"部分。



          Pytest必會知識點

          基礎介紹

          pytest 是 python 的第三方單元測試框架,比unittest 更簡潔和高效,支持315種以上的插件,同時兼容 nose、unittest 框架。

          官網https://docs.pytest.org/en/latest/contents.html

          安裝 pip install pytest

          Pytest的命名規則

          命名規則如下:

          1. 測試文件應當命名為 test_<something>.py或者<somethins>_test.py

          2. 測試函數、測試類方法應當命名為test_<something>

          3. 測試類應當命名為Test<Something>.

          pytest的setup和teardown函數

          1)模塊級(setup_module/teardown_module)開始于模塊始末

          2)類級(setup_class/teardown_class)開始于類的始末

          3)類里面的(setup/teardown)(運行在調用函數的前后)

          4)功能級(setup_function/teardown_function)開始于功能函數始末(不在類中)

          5)方法級(setup_method/teardown_method)開始于方法始末(在類中)

          pytest的mark

          pytest的mark主要用來標記用例,通過不同的標記實現不同的運行策略

          主要用途:

          標記和分類用例: @pytest.mark.level1

          標記用例執行順順序pytest.mark.run(order=1) (需安裝pytest-ordering)

          標記用例在指定條件下跳過或直接失敗 @pytest.mark.skipif()/xfail()

          標記使用指定fixture(測試準備及清理方法) @pytest.mark.usefixtures()

          參數化 @pytest.mark.parametrize

          標記超時時間 @pytest.mark.timeout(60) (需安裝pytest-timeout)

          標記失敗重跑次數@pytest.mark.flaky(reruns=5, reruns_delay=1) (需安裝pytest-rerunfailures)

          Pytest運行用例

          pytest 運行目錄下的所有用例

          pytest test_reg.py運行指定模塊中的所有用例

          pytest test_reg.py::TestClass::test_method 運行指定模塊指定類指定用例

          pytest -m tag 運行包含指定標簽的所有用例

          pytest -k "test_a and test_b" 運行名稱包含指定表達式的用例 (支持and or not)

          其他常用參數

          -q: 安靜模式, 不輸出環境信息

          -v: 豐富信息模式, 輸出更詳細的用例執行信息

          -s: 顯示程序中的print/logging輸出


          Pytest的插件

          pytest的插件也是通過pip install 命令進行安裝,常用的插件如下

          pytest-rerunfailures 用例重新執行

          pytest-html 生成html報告

          pytest-timeout 限制超時時間

          pytest-parallel 多線程使用,常用配置命令如下:

          –workers (optional) *:多進程運行需要加此參數, *是進程數。默認為1。

          –tests-per-worker (optional) *:多線程運行, *是每個worker運行的最大并發線程數。默認為1

          實例:多線程執行并生成html報告

          定義兩個py文件test_demo1.py和test_demo2.py并放入同一包中

          #test_demo1.py

          import pytest
          import time
          class TestPrint:
              def setup(self):
          
                  print("setup")
          
              @pytest.mark.smoke
              def test_test1(self):
                  time.sleep(2)
          
                  assert (1==1)
          
              def test_test2(self):
                  time.sleep (2)
                  assert (1==2)
          
              @pytest.mark.smoke
              def test_test3(self):
                  time.sleep (2)
                  assert (1==1)
          
              def teardown(self):
                  print ("teardown")
          
          
          if __name__=='__main__':
              pytest.main(['-s', 'demo1.py'])
          

          #test_demo2.py

          import pytest
          import time
          class TestPrint:
              def setup(self):
          
                  print("setup")
          
              def test_test11(self):
                  time.sleep(2)
          
                  assert (1==1)
          
              @pytest.mark.smoke
              def test_test21(self):
                  time.sleep (2)
                  assert (1==2)
          
              def test_test31(self):
                  time.sleep (2)
                  assert (1==1)
          
              def teardown(self):
                  print ("teardown")
          
          
          if __name__=='__main__':
              pytest.main(['-s', 'demo2.py'])
          


          在包中運行腳本

          pytest -v --tests-per-worker 2 --html=report.html

          可以看到兩個py文件中的用例全部被執行,并在該目錄下生成了report.html測試報告,測試結果如下:

          ============================================================================

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

          platform win32 -- Python 3.7.4, pytest-5.3.2, py-1.8.1, pluggy-0.13.1 -- c:\python37\python.exe

          cachedir: .pytest_cache

          metadata: {'Python': '3.7.4', 'Platform': 'Windows-10-10.0.17763-SP0', 'Packages': {'pytest': '5.3.2', 'py': '1.8.1', 'pluggy': '0.13.1'}, 'Plugins': {'forked': '1.1.3', 'html': '2.0.1', 'metadata': '1.8.0', 'parallel': '0.0.10', 'rerunfailures': '8.0', '

          xdist': '1.31.0'}, 'JAVA_HOME': 'C:\Program Files\Java\jdk1.8.0_151'}

          rootdir: C:\Users\Kevin\NewLesson\pytest_demo2

          plugins: forked-1.1.3, html-2.0.1, metadata-1.8.0, parallel-0.0.10, rerunfailures-8.0, xdist-1.31.0

          collected 6 items

          pytest-parallel: 1 worker (process), 2 tests per worker (threads)


          test_demo1.py::TestPrint::test_test1 test_demo1.py::TestPrint::test_test2

          test_demo1.py::TestPrint::test_test1 PASSED

          test_demo1.py::TestPrint::test_test3

          test_demo1.py::TestPrint::test_test2 FAILED

          test_demo2.py::TestPrint::test_test11

          test_demo1.py::TestPrint::test_test3 PASSED

          test_demo2.py::TestPrint::test_test21

          test_demo2.py::TestPrint::test_test11 PASSED

          test_demo2.py::TestPrint::test_test31

          test_demo2.py::TestPrint::test_test21 FAILED

          test_demo2.py::TestPrint::test_test31 PASSED


          ===========================================================================FAILURES===========================================================================

          ________________________________________________________________________________ TestPrint.test_test2 ________________________________________________________________________________


          self=<pytest_demo2.test_demo1.TestPrint object at 0x000002B81DFBDEC8>


          def test_test2(self):

          time.sleep (2)

          > assert (1==2)

          E assert 1==2

          E -1

          E +2


          test_demo1.py:16: AssertionError

          ------------------------------------------------------------------------------------------------------------------- Captured stdout setup ------------------------------------------------------------------------------------------------------------------

          setupsetup


          ------------------------------------------------------------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------------------------------------------------------------

          teardown

          ______________________________________________________________________________

          TestPrint.test_test21 ______________________________________________________________________________

          self=<pytest_demo2.test_demo2.TestPrint object at 0x000002B81E02B108>


          @pytest.mark.smoke

          def test_test21(self):

          time.sleep (2)

          > assert (1==2)

          E assert 1==2

          E -1

          E +2


          test_demo2.py:16: AssertionError

          ------------------------------------------------------------------------------------------------------------------- Captured stdout setup --------------------------------------------------------------------------------------------------------------------

          setup

          ------------------------------------------------------------------------------------------------------------------ Captured stdout teardown ------------------------------------------------------------------------------------------------------------------

          teardown

          ==============================================================================warnings summary==============================================================================

          c:\python37\lib\site-packages\_pytest\mark\structures.py:327

          c:\python37\lib\site-packages\_pytest\mark\structures.py:327: PytestUnknownMarkWarning: Unknown pytest.mark.smoke - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/latest/mark.html

          PytestUnknownMarkWarning,


          -- Docs: https://docs.pytest.org/en/latest/warnings.html

          --------------------------------------------------------------------------------------- generated html file: file://C:\Users\Kevin\NewLesson\pytest_demo2\report.html ----------------------------------------------------------------------------------------

          =============================================================================2 failed, 4 passed, 1 warning in 6.42s=============================================================================

          高級用法

          Fixture

          fixture用途

          備注: 這里主要引用 https://www.cnblogs.com/linuxchao/p/linuxchao-pytest-fixture.html

          1.做測試前后的初始化設置,如測試數據準備,鏈接數據庫,打開瀏覽器等這些操作都可以使用fixture來實現

          2.測試用例的前置條件可以使用fixture實現

          3.支持經典的xunit fixture ,像unittest使用的setup和teardown

          fixture區別于unnitest的傳統單元測試(setup/teardown)有顯著改進:

          · 有獨立的命名,并通過聲明它們從測試函數、模塊、類或整個項目中的使用來激活。

          · 按模塊化的方式實現,每個fixture都可以互相調用。

          · fixture的范圍從簡單的單元測試到復雜的功能測試,可以對fixture配置參數,或者跨函數function,類class,模塊module或整個測試session范圍。

          · fixture可以實現unittest不能實現的功能,比如unittest中的測試用例和測試用例之間是無法傳遞參數和數據的,但是fixture卻可以解決這個問題

          fixture的使用

          Fixture名字作為用例的參數

          fixture的名字直接作為測試用例的參數,上面的實例就這這種方式,再來看一個實例

          # test_fixture.py


          import pytest


          @pytest.fixture()

          def fixtureFunc():

          return 'fixtureFunc'


          def test_fixture(fixtureFunc):

          print('我調用了{}'.format(fixtureFunc))


          class TestFixture(object):

          def test_fixture_class(self, fixtureFunc):

          print('在類中使用fixture "{}"'.format(fixtureFunc))


          if __name__=='__main__':

          pytest.main(['-v', 'test_fixture.py'])


          使用@pytest.mark.usefixtures('fixture')裝飾器

          每個函數或者類前使用@pytest.mark.usefixtures('fixture')裝飾器裝飾

          實例

          # test_fixture.py

          import pytest

          @pytest.fixture()

          def fixtureFunc():

          print('\n fixture->fixtureFunc')


          @pytest.mark.usefixtures('fixtureFunc')

          def test_fixture():

          print('in test_fixture')


          @pytest.mark.usefixtures('fixtureFunc')

          class TestFixture(object):

          def test_fixture_class(self):

          print('in class with text_fixture_class')


          if __name__=='__main__':

          pytest.main(['-v', 'test_fixture.py'])


          使用autouse參數

          指定fixture的參數autouse=True這樣每個測試用例會自動調用fixture(其實這里說的不是很準確,因為還涉及到fixture的作用范圍,那么我們這里默認是函數級別的,后面會具體說fixture的作用范圍)

          實例

          # test_fixture.py

          import pytest

          @pytest.fixture(autouse=True)

          def fixtureFunc():

          print('\n fixture->fixtureFunc')


          def test_fixture():

          print('in test_fixture')


          class TestFixture(object):

          def test_fixture_class(self):

          print('in class with text_fixture_class')


          if __name__=='__main__':

          pytest.main(['-v', 'test_fixture.py'])

          結果

          fixture->fixtureFunc

          .in test_fixture


          fixture->fixtureFunc

          .in class with text_fixture_class

          [100%]


          ==========================2 passed in 0.04 seconds===========================

          從結果可以看到每個測試用例執行前都自動執行了fixture


          fixture作用范圍

          上面所有的實例默認都是函數級別的,所以測試函數只要調用了fixture,那么在測試函數執行前都會先指定fixture。說到作用范圍就不得不說fixture 的第二個參數scope參數。

          scope參數可以是session, module,class,function; 默認為function

          1.session 會話級別(通常這個級別會結合conftest.py文件使用,所以后面說到conftest.py文件的時候再說)

          2.module 模塊級別: 模塊里所有的用例執行前執行一次module級別的fixture

          3.class 類級別 :每個類執行前都會執行一次class級別的fixture

          4.function :前面實例已經說了,這個默認是默認的模式,函數級別的,每個測試用例執行前都會執行一次function級別的fixture

          下面我們通過一個實例具體看一下 fixture的作用范圍

          # test_fixture.py

          import pytest


          @pytest.fixture(scope='module', autouse=True)

          def module_fixture():

          print('\n-----------------')

          print('我是module fixture')

          print('-----------------')

          @pytest.fixture(scope='class')

          def class_fixture():

          print('\n-----------------')

          print('我是class fixture')

          print('-------------------')

          @pytest.fixture(scope='function', autouse=True)

          def func_fixture():

          print('\n-----------------')

          print('我是function fixture')

          print('-------------------')


          def test_1():

          print('\n 我是test1')


          @pytest.mark.usefixtures('class_fixture')

          class TestFixture1(object):

          def test_2(self):

          print('\n我是class1里面的test2')

          def test_3(self):

          print('\n我是class1里面的test3')

          @pytest.mark.usefixtures('class_fixture')

          class TestFixture2(object):

          def test_4(self):

          print('\n我是class2里面的test4')

          def test_5(self):

          print('\n我是class2里面的test5')


          if __name__=='__main__':

          pytest.main(['-v', '--setup-show', 'test_fixture.py'])


          fixture實現teardown

          其實前面的所有實例都只是做了測試用例執行之前的準備工作,那么用例執行之后該如何實現環境的清理工作呢?這不得不說yield關鍵字了,相比大家都或多或少的知道這個關鍵字,他的作用其實和return差不多,也能夠返回數據給調用者,唯一的不同是被掉函數執行遇到yield會停止執行,接著執行調用處的函數,調用出的函數執行完后會繼續執行yield關鍵后面的代碼(具體原理可以看下我)。看下下面的實例來了解一下如何實現teardown功能

          import pytest

          from selenium import webdriver

          import time

          @pytest.fixture()

          def fixtureFunc():  '''實現瀏覽器的打開和關閉'''

          driver=webdriver.Firefox()

          yield driver

          driver.quit()

          def test_search(fixtureFunc):

          '''訪問百度首頁,搜索pytest字符串是否在頁面源碼中'''

          driver=fixtureFunc

          driver.get('http://www.baidu.com')

          driver.find_element_by_id('kw').send_keys('pytest')

          driver.find_element_by_id('su').click()

          time.sleep(3)

          source=driver.page_source

          assert 'pytest' in source


          if __name__=='__main__':

          pytest.main(['--setup-show', 'test_fixture.py'])

          這個實例會先打開瀏覽器,然后執行測試用例,最后關閉瀏覽器。大家可以試試! 通過yield就實現了 用例執行后的teardown功能


          conftest.py

          1、可以跨.py文件調用,有多個.py文件調用時,可讓conftest.py只調用了一次fixture,或調用多次fixture

          2、conftest.py與運行的用例要在同一個pakage下,并且有__init__.py文件

          3、不需要import導入 conftest.py,pytest用例會自動識別該文件,放到項目的根目錄下就可以全局目錄調用了,如果放到某個package下,那就在改package內有效,可有多個conftest.py

          4、conftest.py配置腳本名稱是固定的,不能改名稱

          5、conftest.py文件不能被其他文件導入

          6、所有同目錄測試文件運行前都會執行conftest.py文件


          主要用途之一共享變量,代碼如下:

          import pytest

          # conftest.py

          @pytest.fixture(scope='session')

          def get_token():

          token='abcd'

          return token

          這樣,在多個測試用例中使用fixture get_token()時就可以共享 token值了

          元測試的概念

          • 單元測試(unit testing),是指對軟件中的最小可測試單元進行檢查和驗證。
          • 對于單元測試中單元的含義,要根據實際情況去判定其具體含義。
          • 一個單元可能是功能模塊、類、方法(函數)等。

          單元測試工具

          不同的編程語言都有比較成熟的單元測試框架,語法規則有些差別,其核心思想都是相通的。常見的單

          元測試框架有:

          Java語言:Junit、TestNG

          Python語言:UnitTest、Pytest

          UnitTest單元測試框架

          一、UnitTest框架介紹

          UnitTest是Python自帶的一個單元測試框架,用它來做單元測試。也經常應用到UI自動化測試和接口自

          動化測試中,用來管理和維護測試用例腳本

          使用UnitTest框架的好處:

          1. 能夠組織多個用例去執行(可以把多條測試用例封裝成一個測試套件,實現批量執行測試用例)

          2. 提供了豐富的斷言方法,方便對用例執行的結果進行判斷

          3. 能夠生成HTML格式的測試報告

          4. 使用Fixture功能可以減少代碼的冗余

          UnitTest核心要素:

          • TestCase
          • TestSuite
          • TestRunner
          • TestLoader

          二、TestCase

          TestCase就是表示測試用例

          案例

          定義一個實現加法操作的函數,并對該函數進行測試

          如何定義測試用例

          1.導包:importunittest

          2.定義測試類:新建測試類必須繼承unittest.TestCase

          3.定義測試方法:測試方法名稱命名必須以test開頭

          示例代碼:


          ytest 框架可以用來做 系統測試 的自動化, 它的特點有

          • 用 Python 編寫測試用例,簡便易用
          • 可以用 文件系統目錄層次 對應 手工測試用例 層次結構
          • 靈活的 初始化清除 機制
          • 可以靈活挑選測試用例執行
          • 利用第三方插件,可以生成不錯的報表

          ----------------------------------------------------------------------------------------------

          安裝

          pip install pytest

          我們還需要產生測試報表,所以要安裝一個第三方插件 pytest-html ,執行如下命令安裝

          pip install pytest-html

          -----------------------------------------------------------------------------------------

          快速上手

          pytest 如何知道你哪些代碼是自動化的測試用例?

          官方文檔 給出了 pytest 尋找 測試項 的 具體規則

          • 如果未指定命令行參數,則從 testpath(如果已配置)或當前目錄開始收集。如果命令行參數, 指定了 目錄、文件名 或 node id 的任何組合,則按參數來找
          • 尋找過程會遞歸到目錄中,除非它們匹配上 norecursedirs。
          • 在這些目錄中,搜索由其測試包名稱導入的 test_*.py 或 *_test.py 文件。
          • 從這些文件中,收集如下測試項:test為前綴 的 函數Test為前綴的 類 里面的 test為前綴的方法

          -----------------------------------------------------------------------------------------

          測試用例代碼

          首先,我們編寫的測試用例代碼文件, 必須以 test_ 開頭,或者以 _test 結尾

          比如,我們創建一個 文件名為 test_錯誤登錄.py ,放在目錄 autotest\cases\登錄 下面。

          其中 autotest 是 我們創建的 自動化項目根目錄

          class Test_錯誤密碼:
          
              def test_C001001(self):
                  print('\n用例C001001')
                  assert 1==1
                  
              def test_C001002(self):
                  print('\n用例C001002')
                  assert 2==2
                  
              def test_C001003(self):
                  print('\n用例C001003')
                  assert 3==2
          
          如果我們把測試用例存放在類中, 類名必須以 Test 為前綴的 類 ,用例對應的方法必須以 test 為前綴的方法。
          pytest 中用例的檢查點 直接用 Python 的 assert 斷言。
          
          assert 后面的表達式結果 為 True ,就是 檢查點 通過,結果為False ,就是檢查點 不通過。

          運行測試

          執行測試非常簡單,打開命令行窗口,進入自動化項目根目錄(我們這里就是 autotest),執行命令程序 pytest 即可

          顯示找到3個測試項,2個執行通過,1個不通過。

          通過的用例 是用一個綠色小點表示, 不通過的用例用一個紅色的F表示

          并且會在后面顯示具體不通過的用例 和不通過的檢查點 代碼細節。


          大家可以發現,用例代碼中有些打印語句沒有顯示出內容。

          因為pytest 會 截獲print打印的內容。

          如果我們希望 顯示測試代碼中print的內容,因為這些打印語句在調試代碼時很有用,可以加上命令行參數 -s

          如下

          pytest -s

          如果我們希望得到更詳細的執行信息,包括每個測試類、測試函數的名字,可以加上參數 -v,這個參數可以和 -s 合并為 -sv

          如下

          pytest -sv

          執行 pytest 時, 如果命令行沒有指定目標目錄 或者 文件, 它會自動搜索當前目錄下所有符合條件的文件、類、函數。

          所以上面,就找到了3個測試方法,對應3個用例。

          我們目前 項目根目錄 中 只有一個cases 目錄用例存放測試用例, 將來還會有其他目錄,比如:

          lib目錄存放庫代碼、cfg目錄存放配置數據 等等。

          為了防止 pytest 到其他目錄中找測試用例項,執行測試時,我們可以在命令行加上目標目錄 cases ,就是這樣

          pytest cases

          --------------------------------------------------------------------------------------------------------------

          產生報告

          前面在安裝pytest,我們也安裝了 pytest-html 插件,這個插件就是用來產生測試報告的。

          要產生報告,在命令行加上 參數 --html=report.html --self-contained-html ,如下

          pytest cases --html=report.html --self-contained-html

          這樣就會產生名為 report.html 的測試報告文件,可以在瀏覽器中打開

          但是這個工具有個bug,導致測試目錄、文件、類名 中,如果有中文,顯示為亂碼

          可以這樣修復:

          • 打開該插件對應的代碼文件,通常在解釋器目錄下:site-packages\pytest_html\plugin.py
          • 找到如下代碼 class TestResult: def __init__(self, outcome, report, logfile, config): self.test_id=report.nodeid.encode("utf-8").decode("unicode_escape") 改為 class TestResult: def __init__(self, outcome, report, logfile, config): # 白月黑羽修改方法,解決亂碼問題 # self.test_id=report.nodeid.encode("utf-8").decode("unicode_escape") self.test_id=report.nodeid

          然后再次運行,就可以發現中文亂碼問題已經解決了。


          主站蜘蛛池模板: 天天看高清无码一区二区三区| 一区二区乱子伦在线播放| 亚洲一区二区三区首页| 亚洲av区一区二区三| 精品一区二区久久久久久久网精| 亚洲综合av一区二区三区不卡| 精品国产一区二区三区不卡 | 韩国福利一区二区美女视频| 日本一区二区三区爆乳| 国产成人av一区二区三区在线 | 国产精品久久久久一区二区三区| 亚洲一区无码中文字幕乱码| 亚洲av日韩综合一区二区三区| 日韩福利视频一区| 国产一区二区精品久久凹凸| 亚洲欧洲无码一区二区三区| 成人免费av一区二区三区| 亚洲一区在线视频| 国产福利视频一区二区| 在线观看一区二区三区av| 国产av天堂一区二区三区| 日韩视频一区二区| 国产精品分类视频分类一区| 亚洲国产一区二区三区| 亚洲香蕉久久一区二区| 亚洲国产国产综合一区首页| 色屁屁一区二区三区视频国产| 日本一区二区在线| 国产伦精品一区二区免费| 免费看AV毛片一区二区三区| 一区二区三区日韩| 国产区精品一区二区不卡中文| 国产免费一区二区三区VR| 国产成人欧美一区二区三区| 少妇无码一区二区三区| 日韩精品一区二区三区大桥未久| av无码一区二区三区| 丰满岳妇乱一区二区三区| 国产精品无码一区二区在线观一| 日韩成人无码一区二区三区| 无码日韩精品一区二区免费|