pytest使用總結及採坑指南

pytest總結

  • pytest一個很是優秀的點就是能夠支持擴展不少插件。
  • 安裝python工具包時,時長遇到訪問鏈接不到倉庫的狀況,使用-i命令指定倉庫地址,一般我都是選擇這個地址:
    https://mirrors.ustc.edu.cn/p...
  • pytest插件以下及功能介紹:
  1. 安裝pytest:pip3 install pytest -i https://mirrors.ustc.edu.cn/p...
  2. 因爲項目測試中但願重複執行,因此使用pytest-repeat插件
    --count=2, 指定測試的次數,默認是函數級別的測試
    --repeat-scope, 指定重複執行的域.html

    • 補充說明:pytest有一個域的概念即scope,分爲function、class、module、session
    • 其中function指一個test開頭的函數,class指一個Test開頭的類,而module指一個test開頭的文件,session指此次執行的全部用例。
    • 因此說若是--repeat-scope指定了session則代表是按照session進行重複。
    • 注意:通過測試--xdist命令下不能按照預期的repeat-scope進行執行。
    • 例子:pytest test1.py -s --count=5 --repeat-scope=session
    • 經過在函數上添加@pytest.mark.repeat(count)裝飾,指定函數執行次數。
    @pytest.mark.repeat(5)
    def test_02(start, open_baidu):
        print("測試用例test_02")
  3. pytest-xdist, 併發執行多個非依賴用例
  • 解釋一下,--xdist選項目的是爲了節省測試用例的執行時間,使用多核執行測試用例,可是有個前提條件就是這些用例不存在依賴關係,由於依賴關係是不能被保證的,及時有後邊提到的ordering、dependancy插件
  • 安裝pip3 install pytest-xdist -i https://mirrors.ustc.edu.cn/p...
  • 用法:pytest test.py -n auto指示根據當前cpu信息自動分配合理的核數運行用例,一樣可使用pytest test.py -n 3指定具體的運行核數,併發進程數
  1. pytest相對簡單的保證項目用例先後順序的插件
    pytest-ordering
@pytest.mark.run(order=7)
   def test_delete_port(self, host_ip, module_dict, cfg):
       if "test_create_port" not in module_dict:
           # skip
           pytest.skip("do not have test_create_port result")

       self.delete_port(host_ip, module_dict)

   @pytest.mark.run(order=8)
   def test_delete_subnet(self, host_ip, module_dict, cfg, db_session):
       if "test_create_vpc_subnet" not in module_dict:
           # skip
           pytest.skip("do not have test_create_port result")

       self.delete_subnet(host_ip, module_dict, db_session)

兩段代碼會先執行7在執行8,若是不指定,則按照名字排序執行。python

  1. 自定義參數
  • 有時咱們須要根據不一樣的場景傳入一下參數,參考以下代碼便可:
# pytest_addoption是pytest已經定義好的fixture(固件)能夠直接使用,指定要解析的字段,action表示存儲格式  
def pytest_addoption(parser):  
    parser.addoption("--cmdopt", action="store", default="dev.ini", help="my option: type1 or type2")  
    parser.addoption("--concurrency", action="store", default='False', help="my option: concurrency")

# 定義本身的固件,即其餘測試用例經過哪一個名字獲取這個定義的--cmdopt參數
@pytest.fixture(scope="module")
def cmdopt(request):
    return request.config.getoption("--cmdopt")
  1. 生成報告:
  • 使用簡單的pytest-html插件
    只須要安裝pip3 install pytest-html
    運行命令pytest test.py --html=./report.html,指定輸出的文件爲report.html報告
  • 使用allure工具,界面好看,功能全,安裝複雜web

    • 須要安裝allure插件及工具
    1. 安裝allure brew install allure
    2. 安裝插件pip3 install allure-pytest -i https://mirrors.ustc.edu.cn/p...
    3. 執行命令:pytest -v test_vpc_floatingip.py -n auto --count=5 -q --alluredir ./report
    4. allure generate --clean report/ -o allure-results/ #生成html格式文件
    5. allure open ./allure-results/ 打開文件
    6. 備註:allure使用了兩種方式來渲染頁面,分別是allure open 和 allure serve。前者用於在本地渲染和查看結果,後者用於在本地渲染後對外展現結果,因此要想查看有數據的html內容,須要使用allure open。運行命令 allure open allure-report便可自動打開瀏覽器(耐心等待一下)展現渲染好的結果,其中allure-report爲allure generate生成的結果所在目錄。
    7. 有些人會使用pip3 install pytest-allure-adaptor -i https://mirrors.ustc.edu.cn/p... 會報錯:
      INTERNALERROR> AttributeError: module 'pytest' has no attribute ‘allure’,卸載安裝l allure-pytest,但我這裏會報錯,因此未使用
    8. 重複執行屢次,allure會記錄屢次的結果,可是總的用例數是不變的,可是某一個用例的重複次數會增長
  1. 重點:個人項目測試用例之間有依賴關係,又不想整合到一塊兒會丟失不少test_case細節,又想要併發將此流程執行多遍,此時簡單的使用repeate ordering xdist插件終究不能知足本身的需求,最後只能利用以下方式:
    main函數:
def run(i):
    file_name = '--html=./report/report_{}.html'.format(i[0])
    pytest.main(["-v", "-s", '--log-format="%(asctime)s %(levelname)s %(message)s"',
                 '--log-date-format="%Y-%m-%d %H:%M:%S"', file_name, '', '--alluredir', './report/result', i[1]])
    # pytest.main(['-v', '--alluredir', 'report/result'])


if __name__ == "__main__":
    import sys
    if len(sys.argv) > 1:
        p1 = '--cmdopt={}'.format(sys.argv[1])
        num = int(sys.argv[2])
    else:
        p1 = '--cmdopt=dev.ini'
        num = 1

    import multiprocessing
    pool = multiprocessing.Pool(4)

    _list = [(x, p1) for x in range(num)]
    pool.map(run, _list)
    pool.close()
    pool.join()
  1. 關於日誌輸出:
    能夠經過指定 --log-format="%(asctime)s %(levelname)s %(message)s" 和 --log-date-format="%Y-%m-%d %H:%M:%S"分別指定日誌的格式和日誌的日期格式
  2. 經過pytest.ini指定pytest運行時參數
    pytest的執行能夠分爲幾種,一種是最多見的pytest test.py形式
    第二種是直接執行pytest,第三種是執行python test.py但此時的test.py內容應該是第7節中的run中的pytest.main的運行形式
    值得注意的是,無論哪一種形式pytest都會先找pytest.ini進行加載,若是有覆蓋的信息會被覆蓋,不然就使用pytest.ini內容

開啓日誌功能使用log_cli=true瀏覽器

[pytest]
; addopts = -s -v --html=report/report.html --alluredir ./report/result --count=1 -n auto
testpaths = ./
#python_files = test_*.py
#python_classes = Test*
log_cli=true
log_cli_date_format = %Y-%m-%d %H:%M:%S
log_cli_format = %(asctime)s %(levelname)s %(message)s
log_cli_level = INFO
#log_level=NOTSET
log_file = ./logs/pytest-logs.txt
python_functions = test*

參考:
https://www.jianshu.com/p/ddb...
https://www.cnblogs.com/yoyok... 使用skip跳過用例
https://blog.csdn.net/qq_42610167/article/details/101204066?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-tasksession

相關文章
相關標籤/搜索