Django4.0 進(jìn)階測試主題-使用不同的測試框架

2022-03-17 13:59 更新

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

當(dāng)你運(yùn)行 ?./manage.py test? 時(shí),Django 會(huì)查看 ?TEST_RUNNER ?的配置來決定做什么。默認(rèn)情況下, ?TEST_RUNNER ?指向 ?django.test.runner.DiscoverRunner?。這個(gè)類定義了默認(rèn)的 Django 測試行為。這個(gè)行為包括:

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

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

定義測試運(yùn)行器

測試運(yùn)行器是一個(gè)類,他定義了 ?run_tests()? 方法。Django 自帶一個(gè) ?DiscoverRunner ?類,它定義了默認(rèn)的 Django 測試行為。該類定義了進(jìn)入點(diǎn) ?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 會(huì)自動(dòng)計(jì)算出這個(gè)目錄,所以不需要指定這個(gè)選項(xiàng)。如果指定了這個(gè)選項(xiàng),一般來說,它應(yīng)該是包含你的 ?manage.py? 文件的目錄。
?verbosity ?決定將打印到控制臺(tái)的通知和調(diào)試信息的數(shù)量;0 為無輸出,1 為正常輸出,2 為詳細(xì)輸出。
如果 ?interactive ?是 ?True?,則測試套件在執(zhí)行測試套件時(shí),有權(quán)限向用戶請求指令。這種行為的一個(gè)例子是要求允許刪除一個(gè)現(xiàn)有的測試數(shù)據(jù)庫。如果 ?interactive ?為 ?False?,測試套件必須能夠在沒有任何人工干預(yù)的情況下運(yùn)行。
如果 ?failfast ?為 ?True?,測試套件將在檢測到第一次測試失敗后停止運(yùn)行。
如果 ?keepdb ?為 ?True?,測試套件將使用現(xiàn)有數(shù)據(jù)庫,或在必要時(shí)創(chuàng)建一個(gè)數(shù)據(jù)庫。如果 ?False?,將創(chuàng)建一個(gè)新的數(shù)據(jù)庫,并提示用戶刪除現(xiàn)有的數(shù)據(jù)庫。

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

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

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

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

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

屬性

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

方法

DiscoverRunner.run_tests(test_labels, **kwargs)

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

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

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

classmethod DiscoverRunner.add_arguments(parser)

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

DiscoverRunner.setup_test_environment(**kwargs)

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

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

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

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

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

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

返回一個(gè)準(zhǔn)備運(yùn)行的 ?TestSuite ?實(shí)例。

DiscoverRunner.setup_databases(**kwargs)

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

DiscoverRunner.run_checks(databases)

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

DiscoverRunner.run_suite(suite, **kwargs)

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

DiscoverRunner.get_test_runner_kwargs()

返回實(shí)例化 ?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)

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

DiscoverRunner.log(msg, level=None)

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

測試工具集

django.test.utils

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

setup_test_environment(debug=None)

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

teardown_test_environment()

進(jìn)行全局性的測試后拆解,如從模板系統(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ù)庫。
返回一個(gè)數(shù)據(jù)結(jié)構(gòu),該結(jié)構(gòu)提供了足夠的細(xì)節(jié)來撤銷已做的更改。這些數(shù)據(jù)將在測試結(jié)束后提供給 ?teardown_databases()? 函數(shù)。

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

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

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

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

django.db.connection.creation

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

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

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

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

?serialize ?決定 Django 是否在運(yùn)行測試之前將數(shù)據(jù)庫序列化為內(nèi)存中的 JSON 字符串(如果沒有事務(wù),用于在測試之間恢復(fù)數(shù)據(jù)庫狀態(tài))。如果你沒有使用 ?serialized_rollback=True? 的測試類,你可以將其設(shè)置為 ?False ?以加快創(chuàng)建時(shí)間。
如果你使用的是默認(rèn)的測試運(yùn)行器,你可以通過 ?TEST ?條目來控制。
?keepdb ?決定測試運(yùn)行是否應(yīng)使用現(xiàn)有數(shù)據(jù)庫,還是創(chuàng)建一個(gè)新的數(shù)據(jù)庫。如果 ?True?,則使用現(xiàn)有的數(shù)據(jù)庫,如果不存在,則創(chuàng)建新的數(shù)據(jù)庫。如果 ?False?,則創(chuàng)建一個(gè)新的數(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ù)庫連接會(huì)被關(guān)閉,但是數(shù)據(jù)庫不會(huì)被銷毀。


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

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)