Django4.0 進階測試主題-使用不同的測試框架

2022-03-17 13:59 更新

顯然,?unittest ?并不是唯一的 Python 測試框架。雖然 Django 并沒有提供對替代框架的明確支持,但它確實提供了一種方法來調(diào)用為替代框架構(gòu)建的測試,就像它們是正常的 Django 測試一樣。

當你運行 ?./manage.py test? 時,Django 會查看 ?TEST_RUNNER ?的配置來決定做什么。默認情況下, ?TEST_RUNNER ?指向 ?django.test.runner.DiscoverRunner?。這個類定義了默認的 Django 測試行為。這個行為包括:

  1. 進行全局性的測試前設(shè)置。
  2. 在當前目錄下的任何文件中尋找名稱符合 test*.py 模式的測試。
  3. 創(chuàng)建測試數(shù)據(jù)庫。
  4. 運行 migrate 將模型和初始數(shù)據(jù)安裝到測試數(shù)據(jù)庫中。
  5. 運行 系統(tǒng)檢查。
  6. 運行找到的測試。
  7. 銷毀測試數(shù)據(jù)庫。
  8. 進行全局性的測試后拆解。

如果你定義了自己的測試運行器類,并將 ?TEST_RUNNER ?指向該類,那么每當你運行 ?./manage.py test? 時,Django 就會執(zhí)行你的測試運行器。通過這種方式,可以使用任何可以從 Python 代碼中執(zhí)行的測試框架,也可以修改 Django 測試執(zhí)行過程來滿足你的任何測試需求。

定義測試運行器

測試運行器是一個類,他定義了 ?run_tests()? 方法。Django 自帶一個 ?DiscoverRunner ?類,它定義了默認的 Django 測試行為。該類定義了進入點 ?run_tests()?,再加上對 ?run_tests()? 所使用的其他方法的選擇,以此來建立,執(zhí)行和拆除測試套件。

class DiscoverRunner(pattern='test*.py', top_level=None, verbosity=1, interactive=True, failfast=False, keepdb=False, reverse=False, debug_mode=False, debug_sql=False, parallel=0, tags=None, exclude_tags=None, test_name_patterns=None, pdb=False, buffer=False, enable_faulthandler=True, timing=True, shuffle=False, logger=None, **kwargs)

?DiscoverRunner ?將在任何符合 ?pattern ?的文件中搜索測試。
?top_level ?可以用來指定包含頂級 Python 模塊的目錄。通常 Django 會自動計算出這個目錄,所以不需要指定這個選項。如果指定了這個選項,一般來說,它應(yīng)該是包含你的 ?manage.py? 文件的目錄。
?verbosity ?決定將打印到控制臺的通知和調(diào)試信息的數(shù)量;0 為無輸出,1 為正常輸出,2 為詳細輸出。
如果 ?interactive ?是 ?True?,則測試套件在執(zhí)行測試套件時,有權(quán)限向用戶請求指令。這種行為的一個例子是要求允許刪除一個現(xiàn)有的測試數(shù)據(jù)庫。如果 ?interactive ?為 ?False?,測試套件必須能夠在沒有任何人工干預(yù)的情況下運行。
如果 ?failfast ?為 ?True?,測試套件將在檢測到第一次測試失敗后停止運行。
如果 ?keepdb ?為 ?True?,測試套件將使用現(xiàn)有數(shù)據(jù)庫,或在必要時創(chuàng)建一個數(shù)據(jù)庫。如果 ?False?,將創(chuàng)建一個新的數(shù)據(jù)庫,并提示用戶刪除現(xiàn)有的數(shù)據(jù)庫。

如果 ?reverse ?為 ?True?,則測試用例將以相反的順序執(zhí)行。 這對于調(diào)試未正確隔離并具有副作用的測試可能很有用。 使用此選項時會保留按測試類分組。 此選項可以與 --?shuffle ?結(jié)合使用,以反轉(zhuǎn)特定隨機種子的順序。

?debug_mode ?指定 ?DEBUG ?設(shè)置在運行測試之前應(yīng)該設(shè)置成什么。
?parallel ?指定進程數(shù)。如果 ?parallel ?大于 1,則測試套件會在 ?parallel ?(平行)進程下運行。如果測試用例比配置的進程少,Django 將會相應(yīng)地減少進程數(shù)量。每一個進程都有自己的數(shù)據(jù)庫。該選擇要求使用第三方包 ?tblib ?來正確地顯示回溯信息。
?tags ?用于指定一系列 測試標簽。可以與 ?exclude_tags ?結(jié)合使用。
?exclude_tags ?用于指定一系列 排除測試標簽??梢耘c ?tags ?結(jié)合使用。
如果 ?debug_sql ?為 ?True?,失敗的測試用例會輸出 SQL 查詢記錄到 ?django.db.backends logger? 以及回溯。如果 ?verbosity ?是 2,那么所有測試中的查詢都會輸出。
?test_name_patterns? 可以用來指定一套模式,通過名稱過濾測試方法和類。
如果 ?pdb ?為 ?True?,則每次測試錯誤或失敗時都會產(chǎn)生一個調(diào)試器(pdb 或 ipdb)。
如果 ?buffer ?為 ?True?,通過測試的輸出將被丟棄。
如果 ?enable_faulthandler ?是 ?True?,那么 ?faulthandler ?將被啟用。
如果 ?timing ?是 ?True?,將顯示測試時間,包括數(shù)據(jù)庫設(shè)置和總運行時間。

如果 ?shuffle ?是一個整數(shù),則測試用例將在執(zhí)行之前以隨機順序進行混洗,使用整數(shù)作為隨機種子。 如果 ?shuffle ?為 ?None?,則隨機生成種子。 在這兩種情況下,種子都會在運行測試之前被記錄并設(shè)置為 ?self.shuffle_seed?。 此選項可用于幫助檢測未正確隔離的測試。 使用此選項時會保留按測試類分組。

?logger ?可用于傳遞 Python ?Logger ?對象。 如果提供,記錄器將用于記錄消息而不是打印到控制臺。 記錄器對象將尊重其記錄級別而不是詳細程度。

Django 可能會不時地通過添加新的參數(shù)來擴展測試運行器的功能。?**kwargs? 聲明允許這種擴展。如果你將 ?DiscoverRunner ?子類化,或者編寫你自己的測試運行器,確保它接受? **kwargs?。
你的測試運行器也可以定義額外的命令行選項。創(chuàng)建或覆蓋一個 ?add_arguments(cls, parser)? 類方法,并通過在該方法中調(diào)用 ?parser.add_argument()? 來添加自定義參數(shù),這樣 ?test ?命令就可以使用這些參數(shù)。

屬性

  • ?DiscoverRunner.test_suite?:用于構(gòu)建測試套件的類。默認情況下,它被設(shè)置為 ?unittest.TestSuite?。如果你想實現(xiàn)不同的測試收集邏輯,可以重寫這個類。
  • ?DiscoverRunner.test_runner?:這是低級測試運行器的類,用于執(zhí)行各個測試和格式化結(jié)果。默認情況下,它被設(shè)置為 ?unittest.TextTestRunner?。盡管在命名習(xí)慣上有不幸的相似之處,但這與 ?DiscoverRunner ?不是同一類型的類,后者涵蓋了更廣泛的職責(zé)。你可以覆蓋這個屬性來修改測試運行和報告的方式。
  • ?DiscoverRunner.test_loader?:這是一個加載測試的類,無論是從 TestCases 還是模塊或其他方面加載測試,并將它們捆綁成測試套件供運行者執(zhí)行。默認情況下,它被設(shè)置為 ?unittest.defaultTestLoader?。如果你的測試要以不尋常的方式加載,你可以重寫這個屬性。

方法

DiscoverRunner.run_tests(test_labels, **kwargs)

運行測試套件。
?test_labels? 允許你指定要運行的測試,并支持多種格式。

4.0 版后已移除:?extra_tests ?是一個額外的 ?TestCase ?實例列表,用于添加到測試運行器執(zhí)行的套件中。這些額外的測試是在 ?test_labels ?中列出的模塊中發(fā)現(xiàn)的測試之外運行的。

這個方法應(yīng)該返回失敗的測試次數(shù)。

classmethod DiscoverRunner.add_arguments(parser)

重寫這個類方法來添加 ?test ?管理命令接受的自定義參數(shù)。

DiscoverRunner.setup_test_environment(**kwargs)

通過調(diào)用 ?setup_test_environment()? 和設(shè)置 ?DEBUG ?為 ?self.debug_mode? (默認為 ?False?)來設(shè)置測試環(huán)境。

DiscoverRunner.build_suite(test_labels=None, **kwargs)

構(gòu)建一個與提供的測試標簽相匹配的測試套件。
?test_labels ?是描述要運行的測試的字符串列表。測試標簽可以采取以下四種形式之一:

  • ?path.to.test_module.TestCase.test_method?——在測試用例中運行一個測試方法。
  • ?path.to.test_module.TestCase?——運行測試用例中的所有測試方法。
  • ?path.to.module?——搜索并運行命名的 Python 包或模塊中的所有測試。
  • ?path/to/directory?——搜索并運行指定目錄下的所有測試。

如果 ?test_labels ?的值為 ?None?,測試運行器將在當前目錄下所有文件中搜索名稱符合 ?pattern ?的測試。

4.0 版后已移除:?extra_tests ?是一個額外的 ?TestCase ?實例列表,用于添加到測試運行器執(zhí)行的套件中。這些額外的測試是在 ?test_labels ?中列出的模塊中發(fā)現(xiàn)的測試之外運行的。

返回一個準備運行的 ?TestSuite ?實例。

DiscoverRunner.setup_databases(**kwargs)

通過調(diào)用 ?setup_databases()? 創(chuàng)建測試數(shù)據(jù)庫。

DiscoverRunner.run_checks(databases)

在測試的 ?databases ?上運行 系統(tǒng)檢查。

DiscoverRunner.run_suite(suite, **kwargs)

運行測試套件。
返回運行測試套件所產(chǎn)生的結(jié)果。

DiscoverRunner.get_test_runner_kwargs()

返回實例化 ?DiscoverRunner.test_runner? 的關(guān)鍵字參數(shù)。

DiscoverRunner.teardown_databases(old_config, **kwargs)

通過調(diào)用 ?trapdown_databases()? 來銷毀測試數(shù)據(jù)庫,恢復(fù)測試前的條件。

DiscoverRunner.teardown_test_environment(**kwargs)

恢復(fù)測試前的環(huán)境

DiscoverRunner.suite_result(suite, result, **kwargs)

計算并返回一個返回碼,基于測試套件和測試套件返回的結(jié)果。

DiscoverRunner.log(msg, level=None)

如果設(shè)置了記錄器,則以給定的整數(shù)記錄級別記錄消息(例如 ?logging.DEBUG?、?logging.INFO? 或 ?logging.WARNING?)。 否則,消息將打印到控制臺,并考慮當前的詳細程度。 例如,?verbosity ?為 0 時不打印消息,?verbosity ?至少為 1 時打印 ?INFO ?及以上,至少為 2 時打印 ?DEBUG?。級別默認為 ?logging.INFO?。

測試工具集

django.test.utils

為了幫助創(chuàng)建自己的測試運行器,Django 在 ?django.test.utils? 模塊中提供了一些實用的方法。

setup_test_environment(debug=None)

執(zhí)行全局性的測試前設(shè)置,如為模板渲染系統(tǒng)安裝儀器,設(shè)置虛擬的電子郵件發(fā)件箱。
如果 ?debug ?不是 ?None?,則 DEBUG 配置更新為其值。

teardown_test_environment()

進行全局性的測試后拆解,如從模板系統(tǒng)中刪除儀器設(shè)備,恢復(fù)正常的郵件服務(wù)。

setup_databases(verbosity, interactive, *, time_keeper=None, keepdb=False, debug_sql=False, parallel=0, aliases=None, serialized_aliases=None, **kwargs)

創(chuàng)建測試數(shù)據(jù)庫。
返回一個數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)提供了足夠的細節(jié)來撤銷已做的更改。這些數(shù)據(jù)將在測試結(jié)束后提供給 ?teardown_databases()? 函數(shù)。

?aliases ?參數(shù)確定應(yīng)該為哪些 ?DATABASES ?別名測試數(shù)據(jù)庫設(shè)置。 如果未提供,則默認為所有 ?DATABASES ?別名。

?serialized_aliases ?參數(shù)確定別名測試數(shù)據(jù)庫的哪個子集應(yīng)該對其狀態(tài)進行序列化以允許使用 ?serialized_rollback ?功能。 如果未提供,則默認為別名。

teardown_databases(old_config, parallel=0, keepdb=False)

銷毀測試數(shù)據(jù)庫,恢復(fù)測試前的條件。
?old_config ?是一個數(shù)據(jù)結(jié)構(gòu),定義了數(shù)據(jù)庫配置中需要撤銷的變化。它是 ?setup_databases()? 方法的返回值。

django.db.connection.creation

數(shù)據(jù)庫后臺的創(chuàng)建模塊還提供了一些在測試過程中有用的實用程序。

create_test_db(verbosity=1, autoclobber=False, serialize=True, keepdb=False)

創(chuàng)建一個新的測試數(shù)據(jù)庫并對其運行 ?migrate?。
?verbosity ?與 ?run_tests()? 中的行為相同。
?autoclobber ?描述了在發(fā)現(xiàn)與測試數(shù)據(jù)庫同名的數(shù)據(jù)庫時將發(fā)生的行為。

  • 如果 ?autoclobber ?為 ?False?,將要求用戶批準銷毀現(xiàn)有數(shù)據(jù)庫。如果用戶不同意,則調(diào)用 ?sys.exit?。
  • 如果 ?autoclobber ?為 ?True?,數(shù)據(jù)庫將在不與用戶協(xié)商的情況下被銷毀。

?serialize ?決定 Django 是否在運行測試之前將數(shù)據(jù)庫序列化為內(nèi)存中的 JSON 字符串(如果沒有事務(wù),用于在測試之間恢復(fù)數(shù)據(jù)庫狀態(tài))。如果你沒有使用 ?serialized_rollback=True? 的測試類,你可以將其設(shè)置為 ?False ?以加快創(chuàng)建時間。
如果你使用的是默認的測試運行器,你可以通過 ?TEST ?條目來控制。
?keepdb ?決定測試運行是否應(yīng)使用現(xiàn)有數(shù)據(jù)庫,還是創(chuàng)建一個新的數(shù)據(jù)庫。如果 ?True?,則使用現(xiàn)有的數(shù)據(jù)庫,如果不存在,則創(chuàng)建新的數(shù)據(jù)庫。如果 ?False?,則創(chuàng)建一個新的數(shù)據(jù)庫,并提示用戶刪除現(xiàn)有的數(shù)據(jù)庫(如果存在)。
返回其創(chuàng)建的測試數(shù)據(jù)庫的名稱。

?create_test_db()? 的副作用是修改 ?DATABASES ?中的 ?NAME ?的值,使其與測試數(shù)據(jù)庫的名稱相匹配。

destroy_test_db(old_database_name, verbosity=1, keepdb=False)

銷毀名稱為 ?DATABASES ?中 ?NAME ?值的數(shù)據(jù)庫,并將 ?NAME ?設(shè)置為 ?old_database_name ?值。
?verbosity ?參數(shù)和測試類 ?DiscoverRunner ?的行為一樣。
如果 ?keepdb ?的參數(shù)為 ?True ?,數(shù)據(jù)庫連接會被關(guān)閉,但是數(shù)據(jù)庫不會被銷毀。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號