29

人生でテストを書いたことはありませんが、Django プロジェクトのテストを書き始めたいと思っています。テストに関するいくつかの記事を読み、非常に単純な Django アプリまたは最初のテストを作成することにしました。

このアプリには、2 つのビュー (リスト ビューと詳細ビュー) と、4 つのフィールドを持つモデルがあります。

class News(models.Model):
    title = models.CharField(max_length=250)
    content = models.TextField()
    pub_date = models.DateTimeField(default=datetime.datetime.now)
    slug = models.SlugField(unique=True)

私の tests.py ファイルを見せて、次の質問をしたいと思います。

それは理にかなっていますか?

私は正しいことをテストしていますか?

私が守っていないベスト プラクティスはありますか?

my tests.py (11 個のテストが含まれています):

# -*- coding: utf-8 -*-
from django.test import TestCase
from django.test.client import Client
from django.core.urlresolvers import reverse
import datetime
from someproject.myapp.models import News

class viewTest(TestCase):
    def setUp(self):
        self.test_title = u'Test title: bąrekść'
        self.test_content = u'This is a content 156'
        self.test_slug = u'test-title-bareksc'
        self.test_pub_date = datetime.datetime.today()

        self.test_item = News.objects.create(
            title=self.test_title,
            content=self.test_content,
            slug=self.test_slug,
            pub_date=self.test_pub_date,
        )

        client = Client()
        self.response_detail = client.get(self.test_item.get_absolute_url())
        self.response_index = client.get(reverse('the-list-view'))

    def test_detail_status_code(self):
        """
        HTTP status code for the detail view
        """
        self.failUnlessEqual(self.response_detail.status_code, 200)

    def test_list_status_code(self):
        """
        HTTP status code for the list view 
        """
        self.failUnlessEqual(self.response_index.status_code, 200)

    def test_list_numer_of_items(self):
        self.failUnlessEqual(len(self.response_index.context['object_list']), 1)      

    def test_detail_title(self):
        self.failUnlessEqual(self.response_detail.context['object'].title, self.test_title)    

    def test_list_title(self):
        self.failUnlessEqual(self.response_index.context['object_list'][0].title, self.test_title)

    def test_detail_content(self):
        self.failUnlessEqual(self.response_detail.context['object'].content, self.test_content)    

    def test_list_content(self):
        self.failUnlessEqual(self.response_index.context['object_list'][0].content, self.test_content) 

    def test_detail_slug(self):
        self.failUnlessEqual(self.response_detail.context['object'].slug, self.test_slug)    

    def test_list_slug(self):
        self.failUnlessEqual(self.response_index.context['object_list'][0].slug, self.test_slug)

    def test_detail_template(self):
        self.assertContains(self.response_detail, self.test_title)
        self.assertContains(self.response_detail, self.test_content)

    def test_list_template(self):       
        self.assertContains(self.response_index, self.test_title) 
4

2 に答える 2

18

私はテストで完璧ではありませんが、いくつかの考えがあります:

基本的に、自分で作成したすべての関数、メソッド、クラスなどをテストする必要があります。

これは、フレームワークが提供する関数やクラスなどをテストする必要がないことを意味します。

とはいえ、テスト関数の簡単なチェック:

  • test_detail_status_codeおよびtest_list_status_code:
    ルーティングが適切に構成されているかどうかを確認します。の独自の実装を提供する場合はさらに重要ですget_absolute_url()

  • test_list_numer_of_items:
    特定の数のアイテムがビューによって返される必要がある場合は OK。数が重要でない場合 (つまり、任意) は必要ありません。

  • test_detail_templateand test_list_template:
    テンプレート変数が正しく設定されているかどうかを確認します。

  • その他のすべての機能: 必要ありません。
    ここで基本的にテストしているのは、ORM が適切に機能するかどうか、リストが期待どおりに機能するかどうか、およびオブジェクト プロパティにアクセスできるかどうか (またはアクセスできないかどうか) です。モデルのメソッドなどを変更したり、カスタムロジックを提供したりしない限り、これをテストしません。これが適切に機能するフレームワーク開発者を信頼する必要があります。save()

(上書き) したものだけをテストする必要があります。

モデルクラスはおそらく特殊なケースです。前述したように、カスタム ロジックを提供する場合は、基本的にそれらをテストする必要があります。ただし、要件に対してテストする必要もあります。たとえば、フィールドが許可されていないnull(または、整数などの特定のデータ型でなければならない) 可能性があります。nullしたがって、このフィールドに値がある場合、オブジェクトの保存が失敗することをテストする必要があります。
これは、ORM が仕様に正しく準拠しているかどうかをテストするのではなく、仕様が要件を満たしているかどうかをテストします。モデルを変更し、いくつかの設定を変更した可能性があります (偶然または要件を忘れたため)。ただし、プロパティにアクセスできるかどうかなど
のメソッドをテストする必要はありません。save()

もちろん、バグのあるサードパーティのコードを使用すると、状況が異なる可能性があります。しかし、Django はテスト フレームワーク自体を使用してすべてが機能していることを確認しているため、機能していると思います。

要約する
と、要件に対してテストし、独自のコードをテストします。

これは私の見解です。他の人がより良い提案をしているかもしれません。

于 2010-02-03T00:40:15.003 に答える
6

テストを 2 つの完全に異なる種類に分割します。

  • モデル テスト。これらをmodels.pyモデルとともにファイルに入れます。これらのテストは、モデル クラスのメソッドを実行します。簡単な CRUD (作成、取得、更新、削除) を実行して、モデルが機能することを簡単に証明できます。すべての属性をテストしないでください。興味がある場合は、フィールドのデフォルトとsave()ルールをテストしてください。

    この例では、アイテムTestNewsを作成、取得、更新、および削除するクラスを作成しNewsます。デフォルトの日付結果を必ずテストしてください。このクラスは短く、要点を明確にする必要があります。アプリケーションで必要に応じて、さまざまな種類のフィルター処理をテストできます。単体テスト コードは、フィルター処理の「正しい」方法の例を提供できます (提供する必要があります) News

  • UI テスト。これらを別のtests.pyファイルに入れます。これらのテストは、ビュー機能とテンプレートをテストします。

    • 作成している「条件」で TestCase に名前を付けます。「TestNotLoggedIn」。「TestLoggedIn」。"TestNoValidThis". 「TestNotAllowedToDoThat」。setUpログインおよび必要な条件を確立するために必要なその他の手順は、お客様が行います。

    • アクションと結果を含む各テスト メソッドに名前を付けます。「test_get_noquery_should_list」、「test_post_should_validate_with_errors」、「test_get_query_should_detail」。

于 2010-02-03T03:25:47.717 に答える