新聞中心
編寫測試
Django 的單元測試采用 Python 的標準模塊: ?unittest?。該模塊以類的形式定義測試。
下面是一個例子,它是 ?django.test.TestCase? 的子類,同時父類也是 ?unittest.TestCase? 的子類,在事務內(nèi)部運行每個測試以提供隔離:

我們提供的服務有:成都網(wǎng)站制作、成都網(wǎng)站建設、微信公眾號開發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認證、宣恩ssl等。為近千家企事業(yè)單位解決了網(wǎng)站和推廣的問題。提供周到的售前咨詢和貼心的售后服務,是有科學管理、有技術的宣恩網(wǎng)站制作公司
from django.test import TestCase
from myapp.models import Animal
class AnimalTestCase(TestCase):
def setUp(self):
Animal.objects.create(name="lion", sound="roar")
Animal.objects.create(name="cat", sound="meow")
def test_animals_can_speak(self):
"""Animals that can speak are correctly identified"""
lion = Animal.objects.get(name="lion")
cat = Animal.objects.get(name="cat")
self.assertEqual(lion.speak(), 'The lion says "roar"')
self.assertEqual(cat.speak(), 'The cat says "meow"')當你 運行你的測試 時,測試工具的默認行為是在任何名字以 ?test? 開頭的文件中找到所有的測試用例(也就是 ?unittest.TestCase? 的子類),從這些測試用例中自動構建一個測試套件,然后運行該套件。
默認的 ?startapp ?會在新的應用程序中創(chuàng)建一個 ?tests.py? 文件。如果你只有幾個測試,這可能是好的,但隨著你的測試套件的增長,你可能會想把它重組為一個測試包,這樣你就可以把你的測試分成不同的子模塊,如 ?test_models.py?、?test_views.py?、?test_forms.py? 等。你可以自由選擇任何你喜歡的組織方案。
如果您的測試依賴于數(shù)據(jù)庫訪問,例如創(chuàng)建或查詢模型,請確保將您的測試類創(chuàng)建為 ?django.test.TestCase? 的子類,而不是 ?unittest.TestCase?。
使用 ?unittest.TestCase? 避免了在事務中運行每個測試并刷新數(shù)據(jù)庫的成本,但是如果您的測試與數(shù)據(jù)庫交互,它們的行為將根據(jù)測試運行器執(zhí)行它們的順序而有所不同。 這可能導致單元測試在單獨運行時通過,但在套件中運行時失敗。
運行測試
編寫完測試后,使用項目的 ?manage.py? 實用程序的 ?test ?命令運行它們:
$ ./manage.py test測試發(fā)現(xiàn)是基于 unittest 模塊的 內(nèi)建測試發(fā)現(xiàn)。默認情況下,這將發(fā)現(xiàn)當前工作目錄下任何名為“test*.py”的文件中的測試。
你可以通過向 ?./manage.py test? 提供任意數(shù)量的測試標簽來指定要運行的特定測試。每個測試標簽可以是指向包、模塊、TestCase 子類或測試方法的點分隔 Python 路徑。例如:
# Run all the tests in the animals.tests module
$ ./manage.py test animals.tests
# Run all the tests found within the 'animals' package
$ ./manage.py test animals
# Run just one test case
$ ./manage.py test animals.tests.AnimalTestCase
# Run just one test method
$ ./manage.py test animals.tests.AnimalTestCase.test_animals_can_speak你還可以提供目錄路徑,以發(fā)現(xiàn)該目錄下的測試:
$ ./manage.py test animals/如果你的測試文件的命名與 ?test*.py? 模式不同,你可以使用 ?-p? (或 ?--pattern?)選項指定一個自定義文件名模式匹配:
$ ./manage.py test --pattern="tests_*.py"如果你在測試運行時按 ?Ctrl+C?,測試運行器將等待當前運行的測試完成,然后優(yōu)雅地退出。在優(yōu)雅退出過程中,測試運行器將輸出任何測試失敗的細節(jié),報告運行了多少次測試,遇到了多少次錯誤和失敗,并像往常一樣銷毀任何測試數(shù)據(jù)庫。因此,如果你忘記了傳入 ?--failfast? 選項,注意到一些測試意外地失敗了,并且想在不等待整個測試運行完成的情況下獲得失敗的細節(jié),那么按下 ?Ctrl+C? 就會非常有用。
如果你不想等待當前正在進行的測試結(jié)束,你可以按兩次 ?Ctrl+C?,測試運行將立即停止,但不會優(yōu)雅地停止。不會報告中斷前運行的測試細節(jié),也不會銷毀運行中創(chuàng)建的任何測試數(shù)據(jù)庫。
測試數(shù)據(jù)庫
需要數(shù)據(jù)庫的測試(即模型測試)將不會使用“實際”(生產(chǎn))數(shù)據(jù)庫。 將為測試創(chuàng)建單獨的空白數(shù)據(jù)庫。
無論測試是通過還是失敗,當所有測試執(zhí)行完畢后,測試數(shù)據(jù)庫都會被銷毀。
你可以通過使用 ?test --keepdb? 選項來防止測試數(shù)據(jù)庫被破壞。 這將在兩次運行之間保留測試數(shù)據(jù)庫。 如果數(shù)據(jù)庫不存在,將首先創(chuàng)建它。 任何遷移都將被應用,以使其保持最新狀態(tài)。
如上一節(jié)所述,如果測試運行被強行中斷,測試數(shù)據(jù)庫可能不會被銷毀。在下一次運行時,你會被問到是要重新使用還是銷毀數(shù)據(jù)庫。使用 ?test --noinput? 選項禁止顯示該提示并自動銷毀數(shù)據(jù)庫。 例如,在持續(xù)集成服務器上運行測試時這很有用,該測試可能會因超時而中斷。
默認的測試數(shù)據(jù)庫名稱是通過在 DATABASES 中每個 ?NAME ?的值前加上 ?test_? 來創(chuàng)建的。當使用 SQLite時,默認情況下測試將使用內(nèi)存數(shù)據(jù)庫(即數(shù)據(jù)庫將在內(nèi)存中創(chuàng)建,完全繞開文件系統(tǒng)?。ATABASES 中的 ?TEST ?字典提供了許多設置來配置你的測試數(shù)據(jù)庫。例如,如果你想使用不同的數(shù)據(jù)庫名稱,給 DATABASES 中的每個數(shù)據(jù)庫在 ?TEST ?字典中指定 ?NAME?。
在 PostgreSQL 上,?USER ?也需要對內(nèi)置的 postgres 數(shù)據(jù)庫進行讀取訪問。
除了使用單獨的數(shù)據(jù)庫外,測試運行器還將使用你在配置文件中的所有相同的數(shù)據(jù)庫設置: ?ENGINE?、?USER?、?HOST ?等。測試數(shù)據(jù)庫是由 ?USER ?指定的用戶創(chuàng)建的,所以你需要確保給定的用戶賬戶有足夠的權限在系統(tǒng)上創(chuàng)建一個新的數(shù)據(jù)庫。
為了對測試數(shù)據(jù)庫的字符編碼進行精細控制,請使用 ?CHARSET ?TEST 選項。如果你使用的是 MySQL,你也可以使用 ?COLLATION ?選項來控制測試數(shù)據(jù)庫使用的特定字符序。
如果使用 SQLite 內(nèi)存數(shù)據(jù)庫,啟用了 共享緩存,你就可以編寫線程之間共享數(shù)據(jù)庫的測試。
執(zhí)行測試的順序
為了保證所有的 ?TestCase ?代碼都從干凈的數(shù)據(jù)庫開始,Django 測試運行器以如下方式重新排序測試:
- 所有 ?
TestCase?的子類首先運行。 - 然后,所有其他基于Django的測試(基于 ?
SimpleTestCase?的測試用例,包括 ?TransactionTestCase?)都會被運行,它們之間不保證也不強制執(zhí)行特定的順序。 - 然后運行任何其他的 ?
unittest.TestCase? 測試(包括 doctests),這些測試可能會改變數(shù)據(jù)庫而不將其恢復到原始狀態(tài)。
回滾模擬
任何在遷移中加載的初始數(shù)據(jù)將只能在 ?TestCase ?測試中使用,而不能在 ?TransactionTestCase ?測試中使用,此外,只有在支持事務的后端(最重要的例外是 MyISAM)上才能使用。對于依賴 ?TransactionTestCase ?的測試也是如此,比如 ?LiveServerTestCase ?和 ?StaticLiveServerTestCase?。
Django 可以通過在 ?TestCase ?或 ?TransactionTestCase ?中設置 ?serialized_rollback ?選項為 ?True ?來為你重新加載每個測試用例的數(shù)據(jù),但請注意,這將使測試套件的速度降低約 3 倍。
第三方應用程序或那些針對 MyISAM 開發(fā)的應用程序?qū)⑿枰O置這個功能;但是,一般來說,你應該針對事務性數(shù)據(jù)庫開發(fā)你自己的項目,并在大多數(shù)測試中使用 ?TestCase?,因此不需要這個設置。
初始序列化通常是非??斓模绻阆M麖倪@個過程中排除一些應用程序(并稍微加快測試運行速度),你可以將這些應用程序添加到 ?TEST_NON_SERIALIZED_APPS?。
為了防止序列化數(shù)據(jù)被加載兩次,設置 ?serialized_rollback=True? 在刷新測試數(shù)據(jù)庫時禁用 ?post_migrate ?信號。
其他測試條件
無論配置文件中的 ?DEBUG ?設置值是多少,所有的 Django 測試都以 ?DEBUG=False? 運行。這是為了確保你的代碼觀察到的輸出與生產(chǎn)環(huán)境下的輸出一致。
每次測試后都不會清除緩存,如果在生產(chǎn)環(huán)境中運行測試,則運行 ?manage.py test fooapp ?可以將測試中的數(shù)據(jù)插入實時系統(tǒng)的緩存中,因為與數(shù)據(jù)庫不同的是,沒有使用單獨的測試緩存。這種行為在未來可能改變。
了解測試輸出
當你運行測試時,你會看到一些消息,因為測試運行器正在做準備。你可以通過命令行上的 ?verbosity ?選項來控制這些消息的詳細程度:
Creating test database...
Creating table myapp_animal
Creating table myapp_mineral這告訴你測試運行程序正在創(chuàng)建測試數(shù)據(jù)庫,如上一節(jié)所述。
創(chuàng)建測試數(shù)據(jù)庫后,Django 將運行你的測試。 如果一切順利,你會看到類似以下內(nèi)容的信息:
----------------------------------------------------------------------
Ran 22 tests in 0.221s
OK但是,如果有測試失敗,你會看到關于哪些測試失敗的完整細節(jié):
======================================================================
FAIL: test_was_published_recently_with_future_poll (polls.tests.PollMethodTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/dev/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_poll
self.assertIs(future_poll.was_published_recently(), False)
AssertionError: True is not False
----------------------------------------------------------------------
Ran 1 test in 0.003s
FAILED (failures=1)對這個錯誤輸出的完整解釋超出了本文的范圍,但它非常直觀。
請注意,對于任何數(shù)量的失敗和錯誤測試,?test-runner? 腳本的返回碼均為 1。 如果所有測試均通過,則返回碼為 0。如果你在 shell 腳本中使用 ?test-runner? 腳本,并且需要在該級別上測試成功或失敗,則此功能很有用。
加快測試
并行運行測試
只要測試正確隔離,你就可以并行運行它們以加快多核硬件的運行速度。
密碼哈希
默認密碼哈希器在設計上相當慢。 如果要在測試中對許多用戶進行身份驗證,則可能需要使用自定義設置文件,并將 ?PASSWORD_HASHERS ?設置為更快的哈希算法:
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.MD5PasswordHasher',
]不要忘記在 ?PASSWORD_HASHERS ?中包含在輔助工具中使用的任何哈希算法,如果有的話。
保留測試數(shù)據(jù)庫
?test --keepdb? 選項在兩次測試運行之間保留測試數(shù)據(jù)庫。 它跳過了創(chuàng)建和銷毀操作,這可以大大減少運行測試的時間。
文章題目:創(chuàng)新互聯(lián)Django4.0教程:Django4.0測試-編寫并運行測試
文章地址:http://m.fisionsoft.com.cn/article/cdhcoos.html


咨詢
建站咨詢
