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 先锋成人资源,久久99免费视频,国内精品在线观看视频

          整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          從0到1上手Pytest

          從0到1上手Pytest


          如果你想快速上手pytest,只關(guān)注"Pytest必會(huì)知識(shí)點(diǎn)"章節(jié)就可以了(該章節(jié)已經(jīng)能夠解決基礎(chǔ)的ui和接口自動(dòng)化測(cè)試需求);

          如果你想要詳細(xì)了解關(guān)于Fixture的使用方法,請(qǐng)關(guān)注"pytest高級(jí)用法"部分。



          Pytest必會(huì)知識(shí)點(diǎn)

          基礎(chǔ)介紹

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

          官網(wǎng)https://docs.pytest.org/en/latest/contents.html

          安裝 pip install pytest

          Pytest的命名規(guī)則

          命名規(guī)則如下:

          1. 測(cè)試文件應(yīng)當(dāng)命名為 test_<something>.py或者<somethins>_test.py

          2. 測(cè)試函數(shù)、測(cè)試類方法應(yīng)當(dāng)命名為test_<something>

          3. 測(cè)試類應(yīng)當(dāng)命名為Test<Something>.

          pytest的setup和teardown函數(shù)

          1)模塊級(jí)(setup_module/teardown_module)開(kāi)始于模塊始末

          2)類級(jí)(setup_class/teardown_class)開(kāi)始于類的始末

          3)類里面的(setup/teardown)(運(yùn)行在調(diào)用函數(shù)的前后)

          4)功能級(jí)(setup_function/teardown_function)開(kāi)始于功能函數(shù)始末(不在類中)

          5)方法級(jí)(setup_method/teardown_method)開(kāi)始于方法始末(在類中)

          pytest的mark

          pytest的mark主要用來(lái)標(biāo)記用例,通過(guò)不同的標(biāo)記實(shí)現(xiàn)不同的運(yùn)行策略

          主要用途:

          標(biāo)記和分類用例: @pytest.mark.level1

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

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

          標(biāo)記使用指定fixture(測(cè)試準(zhǔn)備及清理方法) @pytest.mark.usefixtures()

          參數(shù)化 @pytest.mark.parametrize

          標(biāo)記超時(shí)時(shí)間 @pytest.mark.timeout(60) (需安裝pytest-timeout)

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

          Pytest運(yùn)行用例

          pytest 運(yùn)行目錄下的所有用例

          pytest test_reg.py運(yùn)行指定模塊中的所有用例

          pytest test_reg.py::TestClass::test_method 運(yùn)行指定模塊指定類指定用例

          pytest -m tag 運(yùn)行包含指定標(biāo)簽的所有用例

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

          其他常用參數(shù)

          -q: 安靜模式, 不輸出環(huán)境信息

          -v: 豐富信息模式, 輸出更詳細(xì)的用例執(zhí)行信息

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


          Pytest的插件

          pytest的插件也是通過(guò)pip install 命令進(jìn)行安裝,常用的插件如下

          pytest-rerunfailures 用例重新執(zhí)行

          pytest-html 生成html報(bào)告

          pytest-timeout 限制超時(shí)時(shí)間

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

          –workers (optional) *:多進(jìn)程運(yùn)行需要加此參數(shù), *是進(jìn)程數(shù)。默認(rèn)為1。

          –tests-per-worker (optional) *:多線程運(yùn)行, *是每個(gè)worker運(yùn)行的最大并發(fā)線程數(shù)。默認(rèn)為1

          實(shí)例:多線程執(zhí)行并生成html報(bào)告

          定義兩個(gè)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'])
          


          在包中運(yùn)行腳本

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

          可以看到兩個(gè)py文件中的用例全部被執(zhí)行,并在該目錄下生成了report.html測(cè)試報(bào)告,測(cè)試結(jié)果如下:

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

          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=============================================================================

          高級(jí)用法

          Fixture

          fixture用途

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

          1.做測(cè)試前后的初始化設(shè)置,如測(cè)試數(shù)據(jù)準(zhǔn)備,鏈接數(shù)據(jù)庫(kù),打開(kāi)瀏覽器等這些操作都可以使用fixture來(lái)實(shí)現(xiàn)

          2.測(cè)試用例的前置條件可以使用fixture實(shí)現(xiàn)

          3.支持經(jīng)典的xunit fixture ,像unittest使用的setup和teardown

          fixture區(qū)別于unnitest的傳統(tǒng)單元測(cè)試(setup/teardown)有顯著改進(jìn):

          · 有獨(dú)立的命名,并通過(guò)聲明它們從測(cè)試函數(shù)、模塊、類或整個(gè)項(xiàng)目中的使用來(lái)激活。

          · 按模塊化的方式實(shí)現(xiàn),每個(gè)fixture都可以互相調(diào)用。

          · fixture的范圍從簡(jiǎn)單的單元測(cè)試到復(fù)雜的功能測(cè)試,可以對(duì)fixture配置參數(shù),或者跨函數(shù)function,類class,模塊module或整個(gè)測(cè)試session范圍。

          · fixture可以實(shí)現(xiàn)unittest不能實(shí)現(xiàn)的功能,比如unittest中的測(cè)試用例和測(cè)試用例之間是無(wú)法傳遞參數(shù)和數(shù)據(jù)的,但是fixture卻可以解決這個(gè)問(wèn)題

          fixture的使用

          Fixture名字作為用例的參數(shù)

          fixture的名字直接作為測(cè)試用例的參數(shù),上面的實(shí)例就這這種方式,再來(lái)看一個(gè)實(shí)例

          # test_fixture.py


          import pytest


          @pytest.fixture()

          def fixtureFunc():

          return 'fixtureFunc'


          def test_fixture(fixtureFunc):

          print('我調(diào)用了{(lán)}'.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')裝飾器

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

          實(shí)例

          # 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參數(shù)

          指定fixture的參數(shù)autouse=True這樣每個(gè)測(cè)試用例會(huì)自動(dòng)調(diào)用fixture(其實(shí)這里說(shuō)的不是很準(zhǔn)確,因?yàn)檫€涉及到fixture的作用范圍,那么我們這里默認(rèn)是函數(shù)級(jí)別的,后面會(huì)具體說(shuō)fixture的作用范圍)

          實(shí)例

          # 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'])

          結(jié)果

          fixture->fixtureFunc

          .in test_fixture


          fixture->fixtureFunc

          .in class with text_fixture_class

          [100%]


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

          從結(jié)果可以看到每個(gè)測(cè)試用例執(zhí)行前都自動(dòng)執(zhí)行了fixture


          fixture作用范圍

          上面所有的實(shí)例默認(rèn)都是函數(shù)級(jí)別的,所以測(cè)試函數(shù)只要調(diào)用了fixture,那么在測(cè)試函數(shù)執(zhí)行前都會(huì)先指定fixture。說(shuō)到作用范圍就不得不說(shuō)fixture 的第二個(gè)參數(shù)scope參數(shù)。

          scope參數(shù)可以是session, module,class,function; 默認(rèn)為function

          1.session 會(huì)話級(jí)別(通常這個(gè)級(jí)別會(huì)結(jié)合conftest.py文件使用,所以后面說(shuō)到conftest.py文件的時(shí)候再說(shuō))

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

          3.class 類級(jí)別 :每個(gè)類執(zhí)行前都會(huì)執(zhí)行一次class級(jí)別的fixture

          4.function :前面實(shí)例已經(jīng)說(shuō)了,這個(gè)默認(rèn)是默認(rèn)的模式,函數(shù)級(jí)別的,每個(gè)測(cè)試用例執(zhí)行前都會(huì)執(zhí)行一次function級(jí)別的fixture

          下面我們通過(guò)一個(gè)實(shí)例具體看一下 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實(shí)現(xiàn)teardown

          其實(shí)前面的所有實(shí)例都只是做了測(cè)試用例執(zhí)行之前的準(zhǔn)備工作,那么用例執(zhí)行之后該如何實(shí)現(xiàn)環(huán)境的清理工作呢?這不得不說(shuō)yield關(guān)鍵字了,相比大家都或多或少的知道這個(gè)關(guān)鍵字,他的作用其實(shí)和return差不多,也能夠返回?cái)?shù)據(jù)給調(diào)用者,唯一的不同是被掉函數(shù)執(zhí)行遇到y(tǒng)ield會(huì)停止執(zhí)行,接著執(zhí)行調(diào)用處的函數(shù),調(diào)用出的函數(shù)執(zhí)行完后會(huì)繼續(xù)執(zhí)行yield關(guān)鍵后面的代碼(具體原理可以看下我)??聪孪旅娴膶?shí)例來(lái)了解一下如何實(shí)現(xiàn)teardown功能

          import pytest

          from selenium import webdriver

          import time

          @pytest.fixture()

          def fixtureFunc():  '''實(shí)現(xiàn)瀏覽器的打開(kāi)和關(guān)閉'''

          driver=webdriver.Firefox()

          yield driver

          driver.quit()

          def test_search(fixtureFunc):

          '''訪問(wèn)百度首頁(yè),搜索pytest字符串是否在頁(yè)面源碼中'''

          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'])

          這個(gè)實(shí)例會(huì)先打開(kāi)瀏覽器,然后執(zhí)行測(cè)試用例,最后關(guān)閉瀏覽器。大家可以試試! 通過(guò)yield就實(shí)現(xiàn)了 用例執(zhí)行后的teardown功能


          conftest.py

          1、可以跨.py文件調(diào)用,有多個(gè).py文件調(diào)用時(shí),可讓conftest.py只調(diào)用了一次fixture,或調(diào)用多次fixture

          2、conftest.py與運(yùn)行的用例要在同一個(gè)pakage下,并且有__init__.py文件

          3、不需要import導(dǎo)入 conftest.py,pytest用例會(huì)自動(dòng)識(shí)別該文件,放到項(xiàng)目的根目錄下就可以全局目錄調(diào)用了,如果放到某個(gè)package下,那就在改package內(nèi)有效,可有多個(gè)conftest.py

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

          5、conftest.py文件不能被其他文件導(dǎo)入

          6、所有同目錄測(cè)試文件運(yùn)行前都會(huì)執(zhí)行conftest.py文件


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

          import pytest

          # conftest.py

          @pytest.fixture(scope='session')

          def get_token():

          token='abcd'

          return token

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

          元測(cè)試的概念

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

          單元測(cè)試工具

          不同的編程語(yǔ)言都有比較成熟的單元測(cè)試框架,語(yǔ)法規(guī)則有些差別,其核心思想都是相通的。常見(jiàn)的單

          元測(cè)試框架有:

          Java語(yǔ)言:Junit、TestNG

          Python語(yǔ)言:UnitTest、Pytest

          UnitTest單元測(cè)試框架

          一、UnitTest框架介紹

          UnitTest是Python自帶的一個(gè)單元測(cè)試框架,用它來(lái)做單元測(cè)試。也經(jīng)常應(yīng)用到UI自動(dòng)化測(cè)試和接口自

          動(dòng)化測(cè)試中,用來(lái)管理和維護(hù)測(cè)試用例腳本

          使用UnitTest框架的好處:

          1. 能夠組織多個(gè)用例去執(zhí)行(可以把多條測(cè)試用例封裝成一個(gè)測(cè)試套件,實(shí)現(xiàn)批量執(zhí)行測(cè)試用例)

          2. 提供了豐富的斷言方法,方便對(duì)用例執(zhí)行的結(jié)果進(jìn)行判斷

          3. 能夠生成HTML格式的測(cè)試報(bào)告

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

          UnitTest核心要素:

          • TestCase
          • TestSuite
          • TestRunner
          • TestLoader

          二、TestCase

          TestCase就是表示測(cè)試用例

          案例

          定義一個(gè)實(shí)現(xiàn)加法操作的函數(shù),并對(duì)該函數(shù)進(jìn)行測(cè)試

          如何定義測(cè)試用例

          1.導(dǎo)包:importunittest

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

          3.定義測(cè)試方法:測(cè)試方法名稱命名必須以test開(kāi)頭

          示例代碼:


          ytest 框架可以用來(lái)做 系統(tǒng)測(cè)試 的自動(dòng)化, 它的特點(diǎn)有

          • 用 Python 編寫測(cè)試用例,簡(jiǎn)便易用
          • 可以用 文件系統(tǒng)目錄層次 對(duì)應(yīng) 手工測(cè)試用例 層次結(jié)構(gòu)
          • 靈活的 初始化清除 機(jī)制
          • 可以靈活挑選測(cè)試用例執(zhí)行
          • 利用第三方插件,可以生成不錯(cuò)的報(bào)表

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

          安裝

          pip install pytest

          我們還需要產(chǎn)生測(cè)試報(bào)表,所以要安裝一個(gè)第三方插件 pytest-html ,執(zhí)行如下命令安裝

          pip install pytest-html

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

          快速上手

          pytest 如何知道你哪些代碼是自動(dòng)化的測(cè)試用例?

          官方文檔 給出了 pytest 尋找 測(cè)試項(xiàng) 的 具體規(guī)則

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

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

          測(cè)試用例代碼

          首先,我們編寫的測(cè)試用例代碼文件, 必須以 test_ 開(kāi)頭,或者以 _test 結(jié)尾

          比如,我們創(chuàng)建一個(gè) 文件名為 test_錯(cuò)誤登錄.py ,放在目錄 autotest\cases\登錄 下面。

          其中 autotest 是 我們創(chuàng)建的 自動(dòng)化項(xiàng)目根目錄

          class Test_錯(cuò)誤密碼:
          
              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
          
          如果我們把測(cè)試用例存放在類中, 類名必須以 Test 為前綴的 類 ,用例對(duì)應(yīng)的方法必須以 test 為前綴的方法。
          pytest 中用例的檢查點(diǎn) 直接用 Python 的 assert 斷言。
          
          assert 后面的表達(dá)式結(jié)果 為 True ,就是 檢查點(diǎn) 通過(guò),結(jié)果為False ,就是檢查點(diǎn) 不通過(guò)。

          運(yùn)行測(cè)試

          執(zhí)行測(cè)試非常簡(jiǎn)單,打開(kāi)命令行窗口,進(jìn)入自動(dòng)化項(xiàng)目根目錄(我們這里就是 autotest),執(zhí)行命令程序 pytest 即可

          顯示找到3個(gè)測(cè)試項(xiàng),2個(gè)執(zhí)行通過(guò),1個(gè)不通過(guò)。

          通過(guò)的用例 是用一個(gè)綠色小點(diǎn)表示, 不通過(guò)的用例用一個(gè)紅色的F表示

          并且會(huì)在后面顯示具體不通過(guò)的用例 和不通過(guò)的檢查點(diǎn) 代碼細(xì)節(jié)。


          大家可以發(fā)現(xiàn),用例代碼中有些打印語(yǔ)句沒(méi)有顯示出內(nèi)容。

          因?yàn)閜ytest 會(huì) 截獲print打印的內(nèi)容。

          如果我們希望 顯示測(cè)試代碼中print的內(nèi)容,因?yàn)檫@些打印語(yǔ)句在調(diào)試代碼時(shí)很有用,可以加上命令行參數(shù) -s

          如下

          pytest -s

          如果我們希望得到更詳細(xì)的執(zhí)行信息,包括每個(gè)測(cè)試類、測(cè)試函數(shù)的名字,可以加上參數(shù) -v,這個(gè)參數(shù)可以和 -s 合并為 -sv

          如下

          pytest -sv

          執(zhí)行 pytest 時(shí), 如果命令行沒(méi)有指定目標(biāo)目錄 或者 文件, 它會(huì)自動(dòng)搜索當(dāng)前目錄下所有符合條件的文件、類、函數(shù)。

          所以上面,就找到了3個(gè)測(cè)試方法,對(duì)應(yīng)3個(gè)用例。

          我們目前 項(xiàng)目根目錄 中 只有一個(gè)cases 目錄用例存放測(cè)試用例, 將來(lái)還會(huì)有其他目錄,比如:

          lib目錄存放庫(kù)代碼、cfg目錄存放配置數(shù)據(jù) 等等。

          為了防止 pytest 到其他目錄中找測(cè)試用例項(xiàng),執(zhí)行測(cè)試時(shí),我們可以在命令行加上目標(biāo)目錄 cases ,就是這樣

          pytest cases

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

          產(chǎn)生報(bào)告

          前面在安裝pytest,我們也安裝了 pytest-html 插件,這個(gè)插件就是用來(lái)產(chǎn)生測(cè)試報(bào)告的。

          要產(chǎn)生報(bào)告,在命令行加上 參數(shù) --html=report.html --self-contained-html ,如下

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

          這樣就會(huì)產(chǎn)生名為 report.html 的測(cè)試報(bào)告文件,可以在瀏覽器中打開(kāi)

          但是這個(gè)工具有個(gè)bug,導(dǎo)致測(cè)試目錄、文件、類名 中,如果有中文,顯示為亂碼

          可以這樣修復(fù):

          • 打開(kāi)該插件對(duì)應(yīng)的代碼文件,通常在解釋器目錄下: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): # 白月黑羽修改方法,解決亂碼問(wèn)題 # self.test_id=report.nodeid.encode("utf-8").decode("unicode_escape") self.test_id=report.nodeid

          然后再次運(yùn)行,就可以發(fā)現(xiàn)中文亂碼問(wèn)題已經(jīng)解決了。


          主站蜘蛛池模板: 一区二区视频免费观看| 欧美成人aaa片一区国产精品| 中文字幕一区在线观看视频| 波多野结衣一区在线| 91视频一区二区| 精品一区二区三区在线播放| 韩国美女vip福利一区| 亚洲一区无码精品色| 好吊妞视频一区二区| 久久精品黄AA片一区二区三区 | 国产免费私拍一区二区三区| 亚洲一区二区影院| 无码精品人妻一区二区三区AV| 无码人妻啪啪一区二区| 蜜桃视频一区二区三区在线观看| 国产高清在线精品一区小说| 怡红院美国分院一区二区| 亚洲一区二区三区无码国产| 精品福利一区二区三| 狠狠做深爱婷婷综合一区 | 日韩精品无码Av一区二区| 日韩中文字幕精品免费一区| 无码人妻精品一区二区| 日韩人妻无码一区二区三区综合部| 韩国资源视频一区二区三区| 欲色aV无码一区二区人妻 | 日韩精品中文字幕无码一区| 中文字幕一区二区三区有限公司| 精品一区精品二区| 成人精品视频一区二区| 日本视频一区在线观看免费| 日韩一区二区三区无码影院| 亚洲AV色香蕉一区二区| a级午夜毛片免费一区二区 | 精品少妇一区二区三区在线 | 亚洲国产精品一区二区久久| 日本亚洲成高清一区二区三区| 国产无套精品一区二区| 亚洲一区二区三区自拍公司| 国产一区二区三区乱码| 久久99国产精一区二区三区|