web-dev-qa-db-ja.com

書き方Djangoテストは失敗するつもりですか?

Thingと呼ばれる属性を持つモデルnameがあり、名前をonly 3文字の長さのcharフィールドにする必要があります。

どうすればそのためのテストを書けますか?

class TestCase1(TestCase):
    def test1(self):
        thing = Thing(name='1234')

そのテストは失敗するはずです。そのオブジェクトが失敗したときにテストpassesになるようにテストを適切に書き込むにはどうすればよいですか?

54
Alexander Bird

Thing(name = '1234')が例外を発生させることを期待している場合、これに対処するには2つの方法があります。

1つは、DjangoのassertRaisesを使用することです(実際にはunittest/unittest2から):

def mytest(self):
    self.assertRaises(FooException, Thing, name='1234')

Thing(name = '1234')がFooExceptionエラーを発生させない限り、これは失敗します。別の方法は、次のように、予期される例外をキャッチし、それが発生しない場合は1つ発生させることです。

def mytest(self):
    try:
        thing = Thing(name='1234')
        self.fail("your message here")
    except FooException:
        pass

明らかに、FooExceptionを、長すぎる文字列でオブジェクトを作成することで得られるはずのものに置き換えます。 ValidationError?

3番目のオプション(Python 2.7現在))は、assertRaisesをコンテキストマネージャとして使用することです。これにより、コードがよりクリーンで読みやすくなります。

def mytest(self):
    with self.assertRaises(FooException):
        thing = Thing(name='1234')

残念ながら、これではカスタムテストの失敗メッセージが許可されないため、テストを十分に文書化してください。詳細は https://hg.python.org/cpython/file/2.7/Lib/unittest/case.py#l97 を参照してください。

85
GDorn

私は現在 nittestexpectedFailureデコレーターを使用しています。これは宣伝どおりに機能します。エラーがない場合は失敗し、エラーがある場合は成功します。

私はexpectedFailureを使用して、カスタムアサートルーチンが実際に機能することを確認しています。

import unittest
from Django.test import TestCase

class EmojiTestCase(TestCase):

    @unittest.expectedFailure
    def testCustomAssert(self):
        self.assertHappyFace(':(') # must fail.

ただし、テスト中に警告メッセージを出力します。 Django and Noseで使用します。どれ others も見ました。

/usr/lib64/python3.4/unittest/case.py:525:RuntimeWarning:TestResultにはaddExpectedFailureメソッドがなく、RuntimeWarningをパスとして報告します)

より良い解決策を見つけるためにここに来ましたが、見つかりませんでした。だから私は少なくとも他の人たちに私が取り組んできたことを伝えたかったのです。

3
Chris