W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Django 的單元測試采用 Python 的標準模塊: ?unittest
?。該模塊以類的形式定義測試。
下面是一個例子,它是 ?django.test.TestCase
? 的子類,同時父類也是 ?unittest.TestCase
? 的子類,在事務內(nèi)部運行每個測試以提供隔離:
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
? 就會非常有用。
如果你不想等待當前正在進行的測試結束,你可以按兩次 ?Ctrl+C
?,測試運行將立即停止,但不會優(yōu)雅地停止。不會報告中斷前運行的測試細節(jié),也不會銷毀運行中創(chuàng)建的任何測試數(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ù)庫的測試。
為了保證所有的 ?TestCase
?代碼都從干凈的數(shù)據(jù)庫開始,Django 測試運行器以如下方式重新排序測試:
TestCase
?的子類首先運行。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ā)的應用程序將需要設置這個功能;但是,一般來說,你應該針對事務性數(shù)據(jù)庫開發(fā)你自己的項目,并在大多數(shù)測試中使用 ?TestCase
?,因此不需要這個設置。
初始序列化通常是非??斓?,但如果你希望從這個過程中排除一些應用程序(并稍微加快測試運行速度),你可以將這些應用程序添加到 ?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
?中包含在輔助工具中使用的任何哈希算法,如果有的話。
?test --keepdb
? 選項在兩次測試運行之間保留測試數(shù)據(jù)庫。 它跳過了創(chuàng)建和銷毀操作,這可以大大減少運行測試的時間。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: