Django4.0 測試工具-測試用例特性

2022-03-17 11:32 更新

默認測試客戶端

SimpleTestCase.client

?django.test.*TestCase? 實例中的每個測試用例都可以訪問一個 Django 測試客戶端的實例。這個客戶端可以用 ?self.client? 來訪問。這個客戶端在每個測試中都會被重新創(chuàng)建,所以你不必擔心狀態(tài)(比如 cookie)會從一個測試轉(zhuǎn)移到另一個測試中。
這意味著,不必每個測試中實例化一個 Client:

import unittest
from django.test import Client

class SimpleTest(unittest.TestCase):
    def test_details(self):
        client = Client()
        response = client.get('/customer/details/')
        self.assertEqual(response.status_code, 200)

    def test_index(self):
        client = Client()
        response = client.get('/customer/index/')
        self.assertEqual(response.status_code, 200)

你也可以引用 ?self.client?,像這樣:

from django.test import TestCase

class SimpleTest(TestCase):
    def test_details(self):
        response = self.client.get('/customer/details/')
        self.assertEqual(response.status_code, 200)

    def test_index(self):
        response = self.client.get('/customer/index/')
        self.assertEqual(response.status_code, 200)

自定義測試客戶端

SimpleTestCase.client_class

如果你想使用不同的 Client 類(例如,一個具有自定義行為的子類),使用 ?client_class ?類屬性:

from django.test import Client, TestCase

class MyTestClient(Client):
    # Specialized methods for your environment
    ...

class MyTest(TestCase):
    client_class = MyTestClient

    def test_my_stuff(self):
        # Here self.client is an instance of MyTestClient...
        call_some_test_code()

輔助工具加載

TransactionTestCase.fixtures

如果數(shù)據(jù)庫中沒有任何數(shù)據(jù),那么數(shù)據(jù)庫支持的網(wǎng)站的測試用例就沒什么用了。測試使用ORM創(chuàng)建對象更易讀,也更易維護,例如在 ?TestCase.setUpTestData()? 中。但是,你也可以使用輔助工具。
輔助工具是 Django 知道如何導(dǎo)入數(shù)據(jù)庫的數(shù)據(jù)集合。例如,如果你的網(wǎng)站有用戶賬戶,你可能會設(shè)置一個假用戶賬戶的輔助工具,以便在測試時填充你的數(shù)據(jù)庫。
創(chuàng)建輔助工具的最直接方法是使用 ?manage.py dumpdata? 命令。這假定你已經(jīng)在你的數(shù)據(jù)庫中擁有一些數(shù)據(jù)。
一旦你創(chuàng)建了一個輔助工具,并把它放在你的 ?INSTALLED_APPS ?中的 ?fixtures ?目錄下,你就可以通過在你的 ?django.test.TestCase? 子類上指定一個 ?fixtures ?類屬性來在你的單元測試中使用它。

from django.test import TestCase
from myapp.models import Animal

class AnimalTestCase(TestCase):
    fixtures = ['mammals.json', 'birds']

    def setUp(self):
        # Test definitions as before.
        call_setup_methods()

    def test_fluffy_animals(self):
        # A test that uses the fixtures.
        call_some_test_code()

具體來說,將發(fā)生以下情況:

  • 在每次測試開始時,在 ?setUp()? 運行之前,Django 會對數(shù)據(jù)庫進行刷新,將數(shù)據(jù)庫直接返回到 ?migrate ?被調(diào)用后的狀態(tài)。
  • 然后,所有命名的輔助工具都會被安裝。在這個例子中,Django 將安裝任何名為 ?mammals ?的 JSON 輔助工具,然后是任何名為 ?birds ?的輔助工具。

出于性能方面的考慮, ?TestCase ?在 ?setUpTestData()? 之前為整個測試類加載一次輔助工具,而不是在每次測試之前加載,并且它在每次測試之前使用事務(wù)來清理數(shù)據(jù)庫。在任何情況下,你都可以確定一個測試的結(jié)果不會受到另一個測試或測試執(zhí)行順序的影響。
默認情況下,輔助工具只被加載到 ?default ?數(shù)據(jù)庫中。如果你使用多個數(shù)據(jù)庫并且設(shè)置了 ?TransactionTestCase.databases?,輔助工具將被加載到所有指定的數(shù)據(jù)庫中。

URLconf配置

如果你的應(yīng)用程序提供了視圖,你可能希望包含使用測試客戶端來行使這些視圖的測試。然而,最終用戶可以自由地在他們選擇的任何 URL 上部署應(yīng)用程序中的視圖。這意味著你的測試不能依賴于你的視圖將在特定的 URL 上可用這一事實。用 ?@override_settings(ROOT_URLCONF=...)? 來裝飾你的測試類或測試方法的 URLconf 配置。

多數(shù)據(jù)庫支持

TransactionTestCase.databases

Django 設(shè)置了一個測試數(shù)據(jù)庫,對應(yīng)于你設(shè)置中的 ?DATABASES ?定義的并且至少有一個測試引用了 ?databases ?的每個數(shù)據(jù)庫。
然而,運行一個 Django ?TestCase ?所花費的時間很大一部分是被調(diào)用 ?flush ?所消耗的,它確保了你在每次測試運行開始時有一個干凈的數(shù)據(jù)庫。如果你有多個數(shù)據(jù)庫,就需要多次刷新(每個數(shù)據(jù)庫一個),這可能是一個耗時的活動——特別是當你的測試不需要測試多數(shù)據(jù)庫活動時。
作為一種優(yōu)化,Django 只在每次測試運行開始時刷新 ?default ?數(shù)據(jù)庫。如果你的設(shè)置包含多個數(shù)據(jù)庫,并且你的測試要求每個數(shù)據(jù)庫都是干凈的,你可以使用測試套件上的 ?databases ?屬性來請求額外的數(shù)據(jù)庫被刷新。
例如:

class TestMyViews(TransactionTestCase):
    databases = {'default', 'other'}

    def test_index_page_view(self):
        call_some_test_code()

這個測試用例將在運行 ?test_index_page_view ?之前刷新 ?default ?和 ?other ?測試數(shù)據(jù)庫。你也可以使用 ?'__all__'? 來指定所有的測試數(shù)據(jù)庫必須被刷新。
?databases ?標志也控制 ?TransactionTestCase.fixtures? 被加載到哪些數(shù)據(jù)庫。默認情況下,輔助工具只被加載到 ?default ?數(shù)據(jù)庫中。
對不在 ?databases ?中的數(shù)據(jù)庫的查詢將給出斷言錯誤,以防止測試之間的狀態(tài)泄露。

TestCase.databases

默認情況下,在 ?TestCase ?期間,僅將 ?default ?數(shù)據(jù)庫包裝在事務(wù)中,并且嘗試查詢其他數(shù)據(jù)庫將導(dǎo)致斷言錯誤,以防止測試之間的狀態(tài)泄漏。
在測試類上使用 ?databases ?類屬性來請求對非 ?default ?數(shù)據(jù)庫進行事務(wù)包裝。
例如:

class OtherDBTests(TestCase):
    databases = {'other'}

    def test_other_db_query(self):
        ...

這個測試只允許對 ?other ?數(shù)據(jù)庫進行查詢。就像 ?SimpleTestCase.databases? 和 ?TransactionTestCase.databases? 一樣,?'__all__'? 常量可以用來指定測試應(yīng)該允許對所有數(shù)據(jù)庫進行查詢。

覆蓋配置

警告

使用下面的函數(shù)可以臨時改變測試中的設(shè)置值。不要直接操作 ?django.conf.settings?,因為 Django 不會在這種操作后恢復(fù)原始值。

SimpleTestCase.settings()

為了測試的目的,經(jīng)常需要臨時改變一個設(shè)置,并在運行測試代碼后恢復(fù)到原始值。對于這個用例,Django 提供了一個標準的 Python 上下文管理器(見 PEP 343),叫做 ?settings()?,可以這樣使用:

from django.test import TestCase

class LoginTestCase(TestCase):

    def test_login(self):

        # First check for the default behavior
        response = self.client.get('/sekrit/')
        self.assertRedirects(response, '/accounts/login/?next=/sekrit/')

        # Then override the LOGIN_URL setting
        with self.settings(LOGIN_URL='/other/login/'):
            response = self.client.get('/sekrit/')
            self.assertRedirects(response, '/other/login/?next=/sekrit/')

此示例將覆蓋 ?with ?塊中代碼的 ?LOGIN_URL ?設(shè)置,然后將其值重置為先前的狀態(tài)。

SimpleTestCase.modify_settings()

重新定義包含一系列值的設(shè)置可能會很麻煩。在實踐中,添加或刪除值通常是足夠的。Django 提供了 ?modify_settings()? 上下文管理器,以方便更改設(shè)置:

from django.test import TestCase

class MiddlewareTestCase(TestCase):

    def test_cache_middleware(self):
        with self.modify_settings(MIDDLEWARE={
            'append': 'django.middleware.cache.FetchFromCacheMiddleware',
            'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
            'remove': [
                'django.contrib.sessions.middleware.SessionMiddleware',
                'django.contrib.auth.middleware.AuthenticationMiddleware',
                'django.contrib.messages.middleware.MessageMiddleware',
            ],
        }):
            response = self.client.get('/')
            # ...

對于每個操作,你可以提供一個值的列表或一個字符串。當值已經(jīng)存在于列表中時,?append ?和 ?prepend ?沒有效果;當值不存在時,?remove ?也沒有效果。

override_settings(**kwargs)

如果你想覆蓋一個測試方法的設(shè)置,Django 提供了 ?override_settings()? 裝飾器。它的用法是這樣的:

from django.test import TestCase, override_settings

class LoginTestCase(TestCase):

    @override_settings(LOGIN_URL='/other/login/')
    def test_login(self):
        response = self.client.get('/sekrit/')
        self.assertRedirects(response, '/other/login/?next=/sekrit/')

裝飾器也可以應(yīng)用于 ?TestCase ?類:

from django.test import TestCase, override_settings

@override_settings(LOGIN_URL='/other/login/')
class LoginTestCase(TestCase):

    def test_login(self):
        response = self.client.get('/sekrit/')
        self.assertRedirects(response, '/other/login/?next=/sekrit/')

modify_settings(*args, **kwargs)

同樣,Django 也提供了 ?modify_settings()? 裝飾器:

from django.test import TestCase, modify_settings

class MiddlewareTestCase(TestCase):

    @modify_settings(MIDDLEWARE={
        'append': 'django.middleware.cache.FetchFromCacheMiddleware',
        'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
    })
    def test_cache_middleware(self):
        response = self.client.get('/')
        # ...

此裝飾器也可以應(yīng)用于測試用例類:

from django.test import TestCase, modify_settings

@modify_settings(MIDDLEWARE={
    'append': 'django.middleware.cache.FetchFromCacheMiddleware',
    'prepend': 'django.middleware.cache.UpdateCacheMiddleware',
})
class MiddlewareTestCase(TestCase):

    def test_cache_middleware(self):
        response = self.client.get('/')
        # ...

當給定一個類時,這些裝飾器直接修改該類并返回它,它們不會創(chuàng)建并返回一個修改后的副本。因此,如果你試圖調(diào)整上面的例子,將返回值分配給一個不同于 ?LoginTestCase? 或 ?MiddlewareTestCase ?的名稱,你可能會驚訝地發(fā)現(xiàn),原來的測試用例類仍然同樣受到裝飾器的影響。對于一個給定的類,?modify_settings()? 總是應(yīng)用在 ?override_settings()? 之后。

配置文件中包含了一些設(shè)置,這些設(shè)置只有在 Django 內(nèi)部初始化時才會被使用。如果你用 ?override_settings ?改變它們,當你通過?django.conf.settings?模塊訪問會得到被改變的配置。但是,Django 的內(nèi)部程序訪問它的方式是不同的。實際上,使用 ?override_settings()? 或者 ?modify_settings() ?來使用這些設(shè)置,很可能達不到你預(yù)期的效果。
我們不建議改變 ?DATABASES ?的設(shè)置。改變 ?CACHES ?的設(shè)置是可能的,但如果你使用的是內(nèi)部緩存,比如 ?django.contrib.session?,就有點棘手。例如,你必須在使用緩存會話并覆蓋 ?CACHES ?的測試中重新初始化會話后端。
最后,避免將你的配置別名為模塊級常量,因為 ?override_settings()? 不會對這些值起作用,它們只在第一次導(dǎo)入模塊時才被評估。

你也可以在配置被覆蓋后,通過刪除配置來模擬沒有配置,比如這樣:

@override_settings()
def test_something(self):
    del settings.LOGIN_URL
    ...

覆蓋配置時,請確保處理你的應(yīng)用代碼使用即使保留配置更改也能保持狀態(tài)的緩存或類似功能的情況。Django 提供了 ?django.test.signals.setting_changed? 信號,讓你在設(shè)置被改變時,可以注冊回調(diào)來清理和重置狀態(tài)。
Django 自己也使用這個信號來重置各種數(shù)據(jù)。

覆蓋配置 數(shù)據(jù)重置
USE_TZ,TIME_ZONE 數(shù)據(jù)庫時區(qū)
TEMPLATES 模板引擎
SERIALIZATION_MODULES 序列化器緩存
LOCALE_PATHS,LANGUAGE_CODE 默認翻譯和加載的翻譯
MEDIA_ROOT,DEFAULT_FILE_STORAGE 默認文件存儲

清空測試發(fā)件箱

如果你使用任何 Django 的自定義 ?TestCase ?類,測試運行器將在每個測試用例開始時清除測試郵件發(fā)件箱的內(nèi)容。

斷言

由于 Python 的普通 ?unittest.TestCase? 類實現(xiàn)了 ?assertTrue()? 和 ?assertEqual()? 等斷言方法,Django 的自定義 TestCase 類提供了許多對測試 Web 應(yīng)用程序有用的自定義斷言方法。

大多數(shù)這些斷言方法給出的失敗消息可以使用 ?msg_prefix ?參數(shù)進行自定義。 該字符串將作為斷言生成的任何失敗消息的前綴。 這使您可以提供其他詳細信息,以幫助您確定測試套件中失敗的位置和原因。

  • ?SimpleTestCase.assertRaisesMessage(expected_exception, expected_message, callable, *args, **kwargs)?
  • ?SimpleTestCase.assertRaisesMessage(expected_exception, expected_message)?

斷言執(zhí)行 ?callable ?引起 ?expected_exception?,并且在異常信息中發(fā)現(xiàn) ?expected_message?。任何其他結(jié)果都會被報告為失敗。它是 ?unittest.TestCase.assertRaisesRegex()? 的簡單版本,不同的是 ?expected_message? 不作為正則表達式處理。
如果只給了 ?expected_exception? 和 ?expected_message? 參數(shù),則返回一個上下文管理器,以便被測試的代碼可以內(nèi)聯(lián)而不是作為一個函數(shù)來寫:

with self.assertRaisesMessage(ValueError, 'invalid literal for int()'):
    int('a')
  • ?SimpleTestCase.assertWarnsMessage(expected_warning, expected_message, callable, *args, **kwargs)?
  • ?SimpleTestCase.assertWarnsMessage(expected_warning, expected_message)?

類似于 ?SimpleTestCase.assertRaisesMessage()?,但是 ?assertWarnsRegex() ?代替 ?assertRaisesRegex()?。

SimpleTestCase.assertFieldOutput(fieldclass, valid, invalid, field_args=None, field_kwargs=None, empty_value='')

斷言表單字段在不同的輸入情況下表現(xiàn)正確。

參數(shù):

  • ?fieldclass ?-- 待測試字段的類。
  • ?valid ?-- 一個字典,將有效輸入映射到它們的預(yù)期干凈值。
  • ?invalid ?-- 一個字典,將無效輸入映射到一個或多個引發(fā)的錯誤信息
  • ?field_args ?-- 傳遞給實例化字段的 ?args?。
  • ?field_kwargs ?-- 傳遞給實例化字段的 ?kwargs?。
  • ?empty_value ?-- ?empty_values ?中輸入的預(yù)期干凈輸出。

例如,以下代碼測試 ?EmailField ?接受 ?a@a.com? 作為有效的電子郵件地址,但拒絕 ?aaa?,并給出合理的錯誤信息:

self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': ['Enter a valid email address.']})

SimpleTestCase.assertFormError(response, form, field, errors, msg_prefix='')

斷言表單中的某個字段在表單中呈現(xiàn)時,會引發(fā)所提供的錯誤列表。

?response ?必須是測試客戶端返回的響應(yīng)實例。

?form ?是 ?Form ?實例在響應(yīng)的模板上下文中給出的名稱。

?field ?是表單中要檢查的字段名。如果 ?field ?的值為 ?None?,則會檢查非字段錯誤(可以通過 ?form.non_field_errors()?)。
?errors ?是一個錯誤字符串,或一個錯誤字符串列表,是表單驗證的結(jié)果。

SimpleTestCase.assertFormsetError(response, formset, form_index, field, errors, msg_prefix='')

斷言 ?formset ?在渲染時,會引發(fā)所提供的錯誤列表。

?response ?必須是測試客戶端返回的響應(yīng)實例。

?formset ?是 ?Formset ?實例在響應(yīng)的模板上下文中給出的名稱。

?form_index ?是 ?Formset ?中表單的編號。 如果 ?form_index ?的值為 ?None?,則將檢查非表單錯誤(可以通過 ?formset.non_form_errors()? 訪問的錯誤)。
?field ?是表單中要檢查的字段名。如果 ?field ?的值為 ?None?,則會檢查非字段錯誤(可以通過 ?form.non_field_errors()?)。
?errors ?是一個錯誤字符串,或一個錯誤字符串列表,是表單驗證的結(jié)果。

SimpleTestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='', html=False)

斷言響應(yīng)產(chǎn)生了給定的 ?status_code? 并且該文本出現(xiàn)在其內(nèi)容中。 如果提供了 ?count?,則文本必須在響應(yīng)中準確出現(xiàn) ?count ?次。

將 ?html ?設(shè)置為 ?True?,將 ?text ?作為 HTML 處理。與響應(yīng)內(nèi)容的比較將基于 HTML 語義,而不是逐個字符的平等。在大多數(shù)情況下,空格會被忽略,屬性排序并不重要。

SimpleTestCase.assertNotContains(response, text, status_code=200, msg_prefix='', html=False)

斷言響應(yīng)產(chǎn)生了給定的 ?status_code ?并且該文本未出現(xiàn)在其內(nèi)容中。

將 ?html ?設(shè)置為 ?True?,將 ?text ?作為 HTML 處理。與響應(yīng)內(nèi)容的比較將基于 HTML 語義,而不是逐個字符的平等。在大多數(shù)情況下,空格會被忽略,屬性排序并不重要。

SimpleTestCase.assertTemplateUsed(response, template_name, msg_prefix='', count=None)

斷言具有給定名稱的模板用于呈現(xiàn)響應(yīng)。

?response ?必須是測試客戶端返回的響應(yīng)實例。

?template_name ?應(yīng)該是一個字符串,例如admin/index.html?

?count ?參數(shù)是一個整數(shù),表示模板應(yīng)該被渲染的次數(shù)。 默認為無,這意味著模板應(yīng)該被渲染一次或多次。

您可以將其用作上下文管理器,如下所示:

with self.assertTemplateUsed('index.html'):
    render_to_string('index.html')
with self.assertTemplateUsed(template_name='index.html'):
    render_to_string('index.html')

SimpleTestCase.assertTemplateNotUsed(response, template_name, msg_prefix='')

斷言給定名稱的模板在渲染響應(yīng)時 沒有 被使用。
你可以用 ?assertTemplateUsed()? 一樣的方式將其作為上下文管理器。

SimpleTestCase.assertURLEqual(url1, url2, msg_prefix='')

斷言兩個 URL 是相同的,忽略查詢字符串參數(shù)的順序,但同名參數(shù)除外。例如,?/path/?x=1&y=2? 等于 ?/path/?y=2&x=1?,但 ?/path/?a=1&a=2 ?不等于 ?/path/?a=2&a=1?。

SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='', fetch_redirect_response=True)

斷言響應(yīng)返回了 ?status_code ?重定向狀態(tài),重定向到了 ?expected_url?(包括任何 GET 數(shù)據(jù)),并且最后一頁收到了 ?target_status_code?。

如果您的請求使用了 ?follow ?參數(shù),則 ?expected_url ?和 ?target_status_code ?將是重定向鏈最后點的 url 和狀態(tài)碼。

如果 ?fetch_redirect_response ?為 ?False?,則不會加載最終頁面。 由于測試客戶端無法獲取外部 URL,因此如果 ?expected_url ?不是您的 Django 應(yīng)用程序的一部分,這將特別有用。

在兩個 URL 之間進行比較時,Scheme 得到了正確處理。 如果在我們被重定向到的位置沒有指定任何方案,則使用原始請求的方案。 如果存在,則 ?expected_url ?中的方案是用于進行比較的方案。

SimpleTestCase.assertHTMLEqual(html1, html2, msg=None)

斷言字符串 html1 和 html2 相等。比較是基于 HTML 語義的。比較時考慮到以下因素:

  • 忽略 HTML 標記前后的空格。
  • 所有類型的空格都被認為是等效的。
  • 所有打開的標簽都是隱式關(guān)閉的,例如 當周圍的標記關(guān)閉或 HTML 文檔結(jié)束時。
  • 空標簽相當于它們的自閉合版本。
  • HTML 元素的屬性順序并不重要。
  • 沒有參數(shù)的布爾屬性(如檢查)等于名稱和值相等的屬性。
  • 引用相同字符的文本、字符引用和實體引用是等效的。

下面的例子是有效的測試,并且沒有引起任何 ?AssertionError?:

self.assertHTMLEqual(
    '<p>Hello <b>&#x27;world&#x27;!</p>',
    '''<p>
        Hello   <b>&#39;world&#39;! </b>
    </p>'''
)
self.assertHTMLEqual(
    '<input type="checkbox" checked="checked" id="id_accept_terms" />',
    '<input id="id_accept_terms" type="checkbox" checked>'
)

html1 和 html2 必須包含 HTML。如果其中一個不能被解析,將產(chǎn)生一個 ?AssertionError?。
錯誤時的輸出可以用 msg 參數(shù)自定義。

SimpleTestCase.assertHTMLNotEqual(html1, html2, msg=None)

斷言字符串 html1 和 html2 不 相等。比較是基于 HTML 語義的。
html1 和 html2 必須包含 HTML。如果其中一個不能被解析,將產(chǎn)生一個 ?AssertionError?。
錯誤時的輸出可以用 ?msg ?參數(shù)自定義。

SimpleTestCase.assertXMLEqual(xml1, xml2, msg=None)

斷言字符串 xml1 和 xml2 相等。比較是基于 XML 語義的。與 ?assertHTMLEqual()? 類似,比較是在解析內(nèi)容上進行的,因此只考慮語義差異,而不是語法差異。當任何參數(shù)中傳遞了無效的 XML 時,即使兩個字符串相同,也總是會引發(fā)一個 ?AssertionError?。
忽略 XML 聲明、文檔類型、處理指令和注釋。只有根元素和它的子元素被比較。
錯誤時的輸出可以用 ?msg ?參數(shù)自定義。

SimpleTestCase.assertXMLNotEqual(xml1, xml2, msg=None)

斷言字符串 xml1 和 xml2 不 相等。比較是基于 XML 語義的。
錯誤時的輸出可以用 ?msg ?參數(shù)自定義。

SimpleTestCase.assertInHTML(needle, haystack, count=None, msg_prefix='')

斷言 HTML 片段 ?needle ?包含在 ?haystack ?中。
如果指定了 ?count ?整數(shù)參數(shù),則將嚴格核查 ?needle ?的出現(xiàn)次數(shù)。
在大多數(shù)情況下,空白是被忽略的,屬性排序并不重要。

SimpleTestCase.assertJSONEqual(raw, expected_data, msg=None)

斷言 JSON 片段 ?raw ?和 ?expected_data ?相等。通常的 JSON 非顯性空格規(guī)則適用,因為重量級是委托給 json 庫的。
錯誤時的輸出可以用 ?msg ?參數(shù)自定義。

SimpleTestCase.assertJSONNotEqual(raw, expected_data, msg=None)

斷言 JSON 片段 ?raw ?和 ?expected_data ?不相等。
錯誤時的輸出可以用 ?msg ?參數(shù)自定義。

TransactionTestCase.assertQuerysetEqual(qs, values, transform=None, ordered=True, msg=None)

斷言一個查詢集 ?qs ?與一個特定的可迭代對象 ?values ?的值匹配。
如果提供了 ?transform?,?values ?將與應(yīng)用 ?transform ?于 ?qs ?而產(chǎn)生的列表中每個成員進行比較。
默認情況下,比較也是依賴于順序的。如果 ?qs ?不提供隱式排序,你可以將 ?ordered ?參數(shù)設(shè)置為 ?False?,這將使比較變成 ?collections.Counter? 比較。如果順序是未定義的(如果給定的 ?qs ?不是有序的,并且比較的對象是一個以上的有序值),會產(chǎn)生一個 ?ValueError?。
錯誤時的輸出可以用 ?msg ?參數(shù)自定義。

TransactionTestCase.assertNumQueries(num, func, *args, **kwargs)

斷言當 ?func ?與 ?*args? 和 ?**kwargs? 一起調(diào)用時,會執(zhí)行 ?num ?次數(shù)據(jù)庫查詢。
如果 ?kwargs ?中存在 ?using ?鍵,則使用該鍵作為數(shù)據(jù)庫別名,以檢查查詢次數(shù):

self.assertNumQueries(7, using='non_default_db')

如果你想調(diào)用一個帶有 ?using ?參數(shù)的函數(shù),你可以通過用 ?lambda ?包裝調(diào)用來增加一個額外的參數(shù):

self.assertNumQueries(7, lambda: my_function(using=7))

你也可以用它作為上下文管理器:

with self.assertNumQueries(2):
    Person.objects.create(name="Aaron")
    Person.objects.create(name="Daniel")

標記測試

你可以給你的測試打上標簽,這樣你就可以輕松地運行一個特定的子集。例如,你可以標記快速或慢速測試:

from django.test import tag

class SampleTestCase(TestCase):

    @tag('fast')
    def test_fast(self):
        ...

    @tag('slow')
    def test_slow(self):
        ...

    @tag('slow', 'core')
    def test_slow_but_core(self):
        ...

你也可以標記一個測試用例:

@tag('slow', 'core')
class SampleTestCase(TestCase):
    ...

子類從超類繼承標簽,方法從其類繼承標簽。如:

@tag('foo')
class SampleTestCaseChild(SampleTestCase):

    @tag('bar')
    def test(self):
        ...

?SampleTestCaseChild.test ?將用 slow?、?core?、?bar?和 ?foo ?來標注。
然后你可以選擇要運行的測試。例如,只運行快速測試:

...\> manage.py test --tag=fast

或者運行快速測試和核心測試(即使它很慢):

...\> manage.py test --tag=fast --tag=core

你也可以通過標簽來排除測試。如果要運行不慢的核心測試:

...\> manage.py test --tag=core --exclude-tag=slow

?test --exclud-tag? 優(yōu)先于 ?test --tag?,所以如果一個測試有兩個標簽,你選擇了其中一個而排除了另一個,測試就不會被運行。


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號