Вопрос:

How to use same unit test for different implementations in python?

python unit-testing automated-tests tdd python-unittest

1182 просмотра

3 ответа

1267 Репутация автора

I am developing multiple functions that answer a same problem but using different algorithm.

So the same input for all functions should generate the same output, that's why I wnted to use the same unit tests instead of having to create multiple tests with the same logic.

I was using the Python unittest framework, and I wanted to use an abstract test class to have the generic tests defined with a function variable so that I could just instantiate that generic function with the one I want to test in another normal test class. But it seems I can't instantiate the function variable in the child class.

So here is an example abstract class with generic tests for multiple functions.

class AbstractTestCase():

    def test_generic_input_one(self):
        result = self.function("input 1")
        self.assertFalse(result)

    def test_generic_input_two(self):
        result = self.function("input 2")
        self.assertTrue(result)

И здесь у вас будет специальный класс теста для function_aобъекта, который наследует общие тесты AbstractTestCaseкласса и реализует его самостоятельно.

class TestsFunctionA(AbstractTestCase, unittest.TestCase):

    def setUp(self):
        self.function = function_a

    def test_specific_input(self):
        result = self.assertTrue(self.function("specific input"))
        self.assertTrue(result)

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

Какой должен быть самый простой и лучший способ сделать это?

Автор: Sylhare Источник Размещён: 12.01.2018 10:06

Ответы (3)


2 плюса

1267 Репутация автора

Решение

Я искал это и получил пару примеров, таких как:

Но больше всего мне помог ответ Вегарда о создании фабрики классов, которая бы принимала параметры и соответственно создавала TestCase

Функция принимает параметры параметризованного тестового примера, и реальный класс TestCase может обращаться к ним без каких-либо проблем.

Вот пример, возьмите foo.pyфайл с:

import unittest

def make_test_case(x):
    class MyTestCase(unittest.TestCase):
        def test_foo(self):
            self.assertEquals(x, 1)

    return MyTestCase

class ConcreteTestCase(make_test_case(1)): 
    pass

Затем запустите тест (ы):

python -m unittest -v foo

По сути, это очень гибко и очень хорошо адаптировано к моему сценарию использования.

Автор: Sylhare Размещён: 09.02.2018 06:21

4 плюса

9051 Репутация автора

В основном вам нужно параметризовать ваши тесты с функцией.

Для unittestвы можете использовать ддт

@ddt
class ProblemTestCase(unittest.TestCase):
    def test_specific_input(self):
        self.assertTrue(function_a("specific input"))

    @data(function_a, function_b)
    def test_generic_input_one(self, function):
        result = function("input 1")
        self.assertFalse(result)

    @data(function_a, function_b)
    def test_generic_input_two(self, function):
        result = function("input 2")
        self.assertTrue(result)

В качестве альтернативы вы можете использовать просто ООП:

class AbstractTestCase(object):

    def test_generic_input_one(self):
        result = self.function("input 1")
        self.assertFalse(result)

    def test_generic_input_two(self):
        result = self.function("input 2")
        self.assertTrue(result)

class TestsFunctionA(AbstractTestCase, unittest.TestCase):

    def function(self, param):
        return function_a(param)

    def test_specific_input(self):
        self.assertTrue(self.function("specific input"))

class TestsFunctionB(AbstractTestCase, unittest.TestCase):

    def function(self, param):
        return function_b(param)

    def test_another_specific_input(self):
        self.assertTrue(self.function("another specific input"))
Автор: Roman Konoval Размещён: 28.03.2018 10:56

0 плюса

986 Репутация автора

Я пришел сюда в поисках способа протестировать несколько реализаций одной и той же функции. Мой пример использования - тестирование представлений учащегося о различных алгоритмах поиска, которые все содержат одни и те же тестовые данные и должны возвращать одинаковые результаты.

Ответ Сильхаре было легко принять, но поделиться им не помешает, поэтому вот как:

import unittest

def function_a():
    result = ...
    return result

def function_b():
    result = ...
    return result

def make_test(function):

    class TestImplementation(unittest.TestCase):

        def test_foo(self):
            self.assertEquals(function, 1)

    return TestImplementation

class TestImplementationA(make_test(function_a)): 
    pass

class TestImplementationB(make_test(function_b)): 
    pass
Автор: bugmenot123 Размещён: 08.05.2019 02:32
Вопросы из категории :
32x32