Unittest Python 3: можно ли добавить новые методы test_*?

Я использую Python 3.4.1 и модуль unittest для проверки другого программного обеспечения.

Другая часть программного обеспечения должна быть запущена, и ее выходные данные должны быть проанализированы скриптом Python для проверки. Выходной файл представляет собой файл XML, содержащий неизвестное количество элементов.

На данный момент я использую subTest() для создания одного подтеста для каждого элемента XML. Это не совсем то, что я хочу.

Я хотел бы создать один метод test_* для каждого элемента в файле XML. Проблема в том, что я заранее не знаю, сколько элементов будет, поэтому мне нужен способ автоматического добавления новых методов test_* в юниттест. Я думал о наличии метода setUpClass(), который вызывал бы внешнее программное обеспечение для генерации XML и создания списка обновлений тестовых* методов, которые необходимо запустить.

Но я думаю, что методы добавляются в список методов unittest для запуска до выполнения чего-либо, поэтому, как только я доберусь до точки, где я добавлю новые методы (например, используя setattr() изнутри setUpClass()), список уже построен, а новые методы никогда не запускаются...

Можно ли динамически изменять список методов для запуска в unittest?

Спасибо!


person big_gie    schedule 27.08.2014    source источник
comment
Вы можете сделать это с помощью py.test. Но что именно делает subTest проблемой? Кажется, он делает то, что вы хотите?   -  person Simeon Visser    schedule 28.08.2014
comment
subTest близко, но не совсем; каждый элемент ‹test›/test› на самом деле является результатом модульного теста программного обеспечения. Я хотел бы сопоставить тесты с обеих сторон, а не совмещать кучу тестов программного обеспечения с одним тестом в python...   -  person big_gie    schedule 28.08.2014


Ответы (2)


Вот вариант того, что я придумал:

import unittest

class MyClass:
    def setup(self):
        # run external software
    def parse_xml(self):
        # parse the xml file
    def generator(self, test_class, a, b):
        def test(self):
            self.assertEqual(a, b)
        return test

    def add_test_methods(self, test_class):
        for i in range(len(self.all_status)):
            test = self.generator(test_class, self.all_status[i], STATUS_SUCCESS)
            setattr(test_class, "test_uid_%d" % i, test)


class TestIO(unittest.TestCase):
    pass

mb = MyClass()
mb.setup()
mb.parse_xml()
mb.add_test_methods(TestIO)

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

Хитрость заключается в том, чтобы сгенерировать и проанализировать файл XML вне любого класса и добавить полученные методы в класс, используя setatt(). Проблема с этим подходом заключается в том, что он запускает код вне набора тестов, чего я надеялся не делать. Таким образом, сбой приведет к поломке всего пакета (поскольку unittest не поймает ошибку...)

Может быть, я мог бы перенести генерацию XML в отдельный класс тестирования?

Любое лучшее предложение?

person big_gie    schedule 27.08.2014

Я придумал это. Попробовал свои силы в коде, присланном @big_gie. Таким образом, setUp и tearDown также будут работать в соответствии с правилом модульного тестирования.

import unittest

def generator(test_class, a, b): def test(self): self.assertEqual(a, b) return test

def add_test_methods(test_class): test_list = [[2,3, 'one'], [5,5, 'two'], [0,0, 'three']] for case in test_list: test = generator(test_class, case[0], case[1]) setattr(test_class, "test_%s" % case[2], test)

class TestIO(unittest.TestCase): def setUp(self): print 'Setup' pass

def tearDown(self): print 'TearDown' pass

add_test_methods(TestIO)

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

Результат:

>>> 
Setup
FTearDown
Setup
TearDown
.Setup
TearDown
.
======================================================================
FAIL: test_one (__main__.TestIO)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:/inchowar/Desktop/PyTrash/test_auto_3.py", line 5, in test
    self.assertEqual(a, b)
AssertionError: 2 != 3

----------------------------------------------------------------------
Ran 3 tests in 0.019s

FAILED (failures=1)
person Arindam Roychowdhury    schedule 18.12.2015