1. 程式人生 > 程式設計 >詳解如何使用Pytest進行自動化測試

詳解如何使用Pytest進行自動化測試

為什麼需要自動化測試

自動化測試有很多優點,但這裡有3個主要的點

  • 可重用性:不需要總是編寫新的指令碼,除非必要,即使是新的作業系統版本也不需要編寫指令碼。
  • 可靠性:人容易出錯,機器不太可能。當執行不能跳過的重複步驟/測試時,速度會更快。
  • 全天執行:您可以在任何時間或遠端啟動測試。夜間執行正在測試你的軟體,即使是在你睡著的時候。

成熟的、功能齊全的Python測試工具——pytest

目前有多種可用的測試框架和工具。這些框架的風格也各不相同,比如資料驅動、關鍵字驅動、混合、BDD等等。您可以選擇最適合您的要求。

Python和pytest在這場競爭中佔據了巨大的份額。Python及其相關工具之所以被大量使用,可能是因為與其他語言相比,沒有或很少程式設計經驗的人更能負擔得起它們。

pytest框架使得編寫小型測試變得很容易,但是可以擴充套件到支援應用程式和庫的複雜功能測試。

Pytest的一些主要特性:

  • 自動發現測試模組和功能
  • 有效的CLI來更好地控制您想要執行或跳過的內容
  • 大型第三方外掛生態系統
  • 固定裝置-不同的型別,不同的範圍
  • 與傳統的單元測試框架一起工作
  • 如何使用Pytest進行自動化測試

自動和可配置的測試發現

在預設情況下,pytest期望在名稱以test_開頭或以test.py結尾的python模組中找到測試。在預設情況下,它期望測試函式名以test 開頭。但是,可以通過在pytest的一個配置檔案中新增您自己的配置來修改這個測試發現協議。

# content of pytest.ini
# Example 1: have pytest look for "check" instead of "test"
# can also be defined in tox.ini or setup.cfg file,although the section
# name in setup.cfg files should be "tool:pytest"
[pytest]
python_files = check_*.py
python_classes = Check
python_functions = *_check

讓我們看一下非常基本的測試函式。

class CheckClass(object):
  def one_check(self):
    x = "this"
    assert 'h' in x

  def two_check(self):
    x = "hello"
    assert hasattr(x,'check')

你注意到什麼了嗎?沒有花哨的assertEqual或assertDictEqual等,只是簡單明瞭的斷言。對於比較兩個物件的簡單操作,不需要匯入這些斷言函式。assert是python已經提供的功能,因此無需重新發明。

固定裝置會起作用的

檢視測試功能,測試錢包軟體的基本操作,比如,

// test_wallet.py
from wallet import Walletdef test_default_initial_amount():
  wallet = Wallet()
  assert wallet.balance == 0
  wallet.close()def test_setting_initial_amount():
  wallet = Wallet(initial_amount=100)
  assert wallet.balance == 100
  wallet.close()def test_wallet_add_cash():
  wallet = Wallet(initial_amount=10)
  wallet.add_cash(amount=90)
  assert wallet.balance == 100
  wallet.close()def test_wallet_spend_cash():
  wallet = Wallet(initial_amount=20)
  wallet.spend_cash(amount=10)
  assert wallet.balance == 10
  wallet.close()

嗯,有意思!你注意到了嗎,很多樣板檔案。另一件值得注意的事情是,測試除了測試功能之外還做了一些其他的事情,例如例項化錢包並關閉它——Wallet .close()

現在讓我們看看如何使用pytest fixture去除樣板

import pytest
from _pytest.fixtures import SubRequest
from wallet import Wallet#==================== fixtures
@pytest.fixture
def wallet(request: SubRequest):
  param = getattr(request,‘param',None)
  if param:
   prepared_wallet = Wallet(initial_amount=param[0])
  else:
   prepared_wallet = Wallet()
  yield prepared_wallet
  prepared_wallet.close()#==================== testsdef test_default_initial_amount(wallet):
  assert wallet.balance == [email protected](‘wallet',[(100,)],indirect=True)
def test_setting_initial_amount(wallet):
  assert wallet.balance == [email protected](‘wallet',[(10,indirect=True)
def test_wallet_add_cash(wallet):
  wallet.add_cash(amount=90)
  assert wallet.balance == [email protected](‘wallet',[(20,indirect=True)
def test_wallet_spend_cash(wallet):
  wallet.spend_cash(amount=10)
  assert wallet.balance == 10

整潔!不是嗎。測試函式非常微妙,只做它們想做的事情。夾具錢包負責設定和拆卸、例項化和關閉錢包。它不僅有助於編寫可重用的程式碼,還增加了資料分離的本質。如果仔細看,錢包數量是一塊測試邏輯之外提供的測試資料,而不是硬編碼在測試函式內部。

@pytest.mark.parametrize(‘wallet',indirect=True)

在更可控的環境中,您可以在儲存庫中有一個測試資料檔案,例如test-data.ini,以及讀取該檔案的包裝器,並且您的測試函式可以呼叫包裝器的另一個介面來讀取測試資料。

但是,建議將您的fixture作為conftest.py檔案的一部分。這是pytest中的一個特殊檔案,它允許測試發現全域性fixture。

但是,有一個針對許多不同資料集執行的測試用例!

不用擔心,pytest有一個很酷的特性來引數化您的fixture。讓我們用一個例子來看看它。

假設您的產品公開CLI介面以在本地管理它。此外,您的產品在啟動時設定了許多預設引數,您需要驗證所有這些引數的預設值。

我們可以考慮為每個設定編寫一個測試用例,但是使用pytest就容易得多了

@pytest.mark.parametrize(“setting_name,setting_value”,[(‘qdb_mem_usage',‘low'),(‘report_crashes',‘yes'),(‘stop_download_on_hang',‘no'),(‘stop_download_on_disconnect',(‘reduce_connections_on_congestion',(‘global.max_web_users',‘1024'),(‘global.max_downloads',‘5'),(‘use_kernel_congestion_detection',(‘log_type',‘normal'),(‘no_signature_check',(‘disable_xmlrpc',(‘disable_ntp',(‘ssl_mode',‘tls_1_2'),])def test_settings_defaults(self,setting_name,setting_value):
  assert product_shell.run_command(setting_name) == \
   self.”The current value for \'{0}\' is   \'{1}\'.”.format(setting_name,setting_value),\
 ‘The {} default should be {}'.format(preference_name,preference_value)

很酷,不是嗎!,你只寫了13個測試用例(每個不同setting_value),在未來如果你新增一個新的設定到你的產品,你需要做的就是,再新增一個tuple上面。

它是如何與selenium和API測試的UI測試整合的

嗯,你的產品可以有多種介面。CLI -就像我們上面討論的。類似地,GUI和API。在部署軟體之前,對所有軟體進行測試是很重要的。在多個元件相互依賴和耦合的企業軟體中,某個部分的更改可能會影響其他部分。

記住,pytest只是一個促進“測試”的框架,而不是特定型別的測試。因此,您可以使用selenium構建GUI測試,或者使用Python的請求庫構建API測試,然後使用pytest執行它。

例如,在高層次上,這可能是您的測試儲存庫結構。

詳解如何使用Pytest進行自動化測試

正如您在上面看到的,這可以很好地分離元件。

  • apiobjects:為呼叫API端點建立包裝器的好地方。您可以使用BaseAPIObject和派生類來滿足您的需求。
  • helper:編寫您的helper方法
  • 庫檔案,它可以被不同的元件使用,例如你的fixture在conftest,pageobjects等。
  • pageobjects:pageobjects設計模式可用於建立不同GUI頁面的類。我們在站得住使
  • 用Webium,它是Python的一個頁面物件模式實現庫。
  • 套件:您可以在這裡編寫pylint程式碼驗證套件,這將有助於您對程式碼質量有信心。
  • 測試:可以根據測試的風格對測試目錄進行分類。它使管理和研究您的測試變得容易。

這只是供參考,儲存庫的結構和依賴關係可以按照您的需要進行佈局。

我有足夠的測試用例,想並行執行它們

您的測試套件中可能有大量的測試用例,並且有時您可能想並行地執行測試用例,以減少總體測試執行時間。

Pytest提供了一個很棒的並行執行測試的外掛,名為Pytest -xdist,它用一些獨特的執行模式擴充套件了Pytest。使用pip安裝此外掛

pip install pytest-xdist

讓我們通過一個示例來快速研究它。

我有一個自動化測試儲存庫CloudApp,用於使用selenium進行GUI測試。此外,它還隨著新的測試用例不斷增長,現在已經有了數百個測試。我想做的是並行執行它們,並減少測試執行時間。

在終端中,只需在專案根資料夾/ tests資料夾中鍵入pytest。這將執行所有測試。

pytest -s -v -n=2

詳解如何使用Pytest進行自動化測試

並行執行測試的pytest-xdist

這還可以幫助您在多個瀏覽器上並行執行測試。

報告

Pytest內建支援建立結果檔案,可由Jenkins、Bamboo或其他持續整合伺服器讀取,使用如下呼叫:

pytest test/file/path — junitxml=path

這可以生成很好的XML風格的輸出,可以由許多CI系統解析器解釋。

結論

Pytest的受歡迎程度逐年上升。此外,它還擁有廣泛的社群支援,這讓您可以訪問很多擴充套件,比如pytest-django,它可以幫助您為Django web應用程式整合編寫測試。記住,pytest支援執行unittest測試用例,所以如果您正在使用unittest,pytest是值得考慮的。

到此這篇關於詳解如何使用Pytest進行自動化測試的文章就介紹到這了,更多相關Pytest 自動化測試內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!