8

Django/unittest で単体テストを学ぼうとしています。

これらは私のモデルの単純なバージョンです:

class Device(models.Model):
    name = models.CharField(max_length=100)

    def get_ips(self):
        return DeviceIP.objects.filter(device=self.id)


class DeviceIP(models.Model):
    ip = models.GenericIPAddressField()
    device = models.ForeignKey(Device)

そして、これは私が思いついたテストコードです:

from django.test import TestCase

class DeviceTest(TestCase):

    def test_get_ips(self):
        device = Device()
        device.name = 'My Device'

        ip1 = DeviceIP()
        ip1.ip = '127.0.0.1'
        ip1.device = device
        ip1.save()

        ip2 = DeviceIP()
        ip2.ip = '127.0.0.2'
        ip2.device = device
        ip2.save()

        ip3 = DeviceIP()
        ip3.ip = '127.0.0.3'
        ip3.device = device
        ip3.save()

        self.assertEqual(device.get_ips(), [ip1, ip2, ip3])

との文字列表現が同一AssertionErrorであるにもかかわらず、on のため、テスト結果は失敗します。device.get_ips()[ip1, ip2, ip3]

使用しようとすると、リストではなく QuerySet であるself.assertListEqualため、エラーが発生します。device.get_ips()

試してみると " "self.assertQuerySetEqualというエラーが表示されますが、 extendsの TestCase.DeviceTest object has no attribute assertQuerySetEqualDeviceTestdjango.test

このようなテストをどのように行う必要がありますか?

また、「実際の」プロジェクトでは、このような単純なテストを行うのは理にかなっていますか?

4

3 に答える 3

10

実際には正しい方法であり、djangoproject が推奨するのは次のとおりです。

    self.assertEqual(list(device.get_ips()), [ip1, ip2, ip3])

queryset と list を強制sortedすると、テスト シナリオが変更され、望ましくありません。

于 2016-04-18T10:35:00.037 に答える
6

呼び出しはリストをdevice.get_ips()返しますQuerySet[ip1, ip2, ip3]したがって、それらは現在等しくありません。

重要でないこと (.filter()データベースから行が返される順序) をテストしたくない場合は、次のようにテストすることをお勧めします。

results = device.get_ips()
result_ips = [ip.ip for ip in results]
self.assertEqual(len(results), 3)
self.assertTrue(ip1.ip in result_ips)
self.assertTrue(ip2.ip in result_ips)
self.assertTrue(ip3.ip in result_ips)

このテスト: 3 つの結果と IP が同じです。これにより、同じオブジェクトを取得しているという合理的な確信が得られます (ただし、必要に応じてさらにアサーションを追加できます)。

于 2013-11-13T23:17:25.930 に答える
1

あなたが入力self.assertQuerySetEqualした、それはする必要がありますself.assertQuerysetEqual、試してみてください:

self.assertQuerysetEqual(device.get_ips(), [repr(ip1), repr(ip2), repr(ip3)], 
                         ordered=False)

または、リストに対してテストしたい場合は、次のようにします。

self.assertItemsEqual(device.get_ips(), [ip1, ip2, ip3])
于 2018-12-03T10:03:17.200 に答える