Подтвердить что ты не робот

Как написать пользовательский метод `.assertFoo()` в Python?

Я пишу несколько тестовых примеров для своего приложения, используя Python unittest. Теперь мне нужно сравнить список объектов со списком других объектов, чтобы проверить, являются ли объекты из первого списка ожидаемыми.

Как написать собственный .assertFoo() метод? Что делать? Должен ли он вызывать исключение при неудаче? Если да, то какое исключение? И как передать сообщение об ошибке? Должно ли сообщение об ошибке быть строкой unicode или байтом?

К сожалению, официальная документация не объясняет, как писать настраиваемые методы утверждения.

Если вам нужен реальный пример для этого, продолжайте чтение.


Код, который я пишу, примерно такой:

def assert_object_list(self, objs, expected):
    for index, (item, values) in enumerate(zip(objs, expected)):
        self.assertEqual(
            item.foo, values[0],
            'Item {0}: {1} != {2}'.format(index, item.foo, values[0])
        )
        self.assertEqual(
            item.bar, values[1],
            'Item {0}: {1} != {2}'.format(index, item.bar, values[1])
        )

def test_foobar(self):
    objs = [...]  # Some processing here
    expected = [
        # Expected values for ".foo" and ".bar" for each object
        (1, 'something'),
        (2, 'nothing'),
    ]
    self.assert_object_list(objs, expected)

Этот подход позволяет очень легко описать ожидаемые значения каждого объекта очень компактным образом и без фактического создания полных объектов.

Однако... Когда один объект выходит из строя, никакие другие объекты не сравниваются, и это затрудняет отладку. Я хотел бы написать собственный метод, который бы безоговорочно сравнивал все объекты, а затем отобразил бы все объекты, которые не удались, а не только первый.

4b9b3361

Ответ 1

Я использую множественное наследование в этих случаях. Например:

Во-первых. Я определяю класс с методами, которые будут включать.

import os

class CustomAssertions:
    def assertFileExists(self, path):
        if not os.path.lexists(path):
            raise AssertionError('File not exists in path "' + path + '".')

Теперь я определяю класс, наследующий от unittest.TestCase и CustomAssertion

import unittest

class MyTest(unittest.TestCase, CustomAssertions):
    def test_file_exists(self):
        self.assertFileExists('any/file/path')

if __name__ == '__main__':
    unittest.main()

Ответ 2

Вы должны создать свой собственный класс TestCase, полученный из unittest.TestCase. Затем добавьте свой собственный метод assert в класс тестового примера. Если ваш тест не удается, поднимите AssertionError. Ваше сообщение должно быть строкой. Если вы хотите протестировать все объекты в списке, а не останавливаться на сбое, затем соберите список неудачных индексов, а после цикла над всеми объектами создайте сообщение assert, в котором суммируются ваши результаты.

Ответ 3

Просто пример суммирования с numpy comparaison unittest

import numpy as np
class CustomTestCase(unittest.TestCase):
    def npAssertAlmostEqual(self, first, second, rtol=1e-06, atol=1e-08):
        np.testing.assert_allclose(first, second, rtol=rtol, atol=atol)


class TestVector(CustomTestCase):
    def testFunction(self):
        vx = np.random.rand(size)
        vy = np.random.rand(size)
        self.npAssertAlmostEqual(vx, vy)