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

2022-03-17 13:59 更新

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

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

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

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

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

測(cè)試運(yùn)行器是一個(gè)類,他定義了 ?run_tests()? 方法。Django 自帶一個(gè) ?DiscoverRunner ?類,它定義了默認(rèn)的 Django 測(cè)試行為。該類定義了進(jìn)入點(diǎn) ?run_tests()?,再加上對(duì) ?run_tests()? 所使用的其他方法的選擇,以此來(lái)建立,執(zhí)行和拆除測(cè)試套件。

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

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

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

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

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

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

屬性

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

方法

DiscoverRunner.run_tests(test_labels, **kwargs)

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

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

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

classmethod DiscoverRunner.add_arguments(parser)

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

DiscoverRunner.setup_test_environment(**kwargs)

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

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

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

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

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

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

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

DiscoverRunner.setup_databases(**kwargs)

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

DiscoverRunner.run_checks(databases)

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

DiscoverRunner.run_suite(suite, **kwargs)

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

DiscoverRunner.get_test_runner_kwargs()

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

DiscoverRunner.teardown_databases(old_config, **kwargs)

通過(guò)調(diào)用 ?trapdown_databases()? 來(lái)銷毀測(cè)試數(shù)據(jù)庫(kù),恢復(fù)測(cè)試前的條件。

DiscoverRunner.teardown_test_environment(**kwargs)

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

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

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

DiscoverRunner.log(msg, level=None)

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

測(cè)試工具集

django.test.utils

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

setup_test_environment(debug=None)

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

teardown_test_environment()

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

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

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

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

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

django.db.connection.creation

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

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

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

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

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

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

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

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


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

掃描二維碼

下載編程獅App

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

編程獅公眾號(hào)