Являются ли базовые классы unittest хорошей практикой? (Python / webapp2)

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

class TestBase(unittest.TestCase):
    # some standard tests

class AnotherTest(TestBase):
    # run some more tests in addition to the standard tests

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

test_base.py

import webtest
from google.appengine.ext import testbed
from models import ContentModel

class TestBase(unittest.TestCase):

    def setUp(self):
        self.ContentModel = ContentModel
        self.testbed = testbed.Testbed()
        self.testbed.activate()
        # other useful stuff

    def tearDown(self):
        self.testbed.deactivate()

    def createUser(self, admin=False):
        # create a user that may or may not be an admin

    # possibly other useful things

Похоже, это сэкономит мне массу времени на всех остальных тестах:

another_test.py

from test_base import TestBase

class AnotherTest(TestBase):
    def test_something_authorized(self):
        self.createUser(admin=True)
        # run a test

    def test_something_unauthorized(self):
        self.createUser(admin=False)
        # run a test

    def test_some_interaction_with_the_content_model(self):
        new_instance = self.ContentModel('foo' = 'bar').put()
        # run a test

Примечание: это основано на некоторых из моих работ в webapp2 на движке приложений Google, но я ожидаю, что аналогичная ситуация возникает практически для любого веб-приложения на Python.

Мой вопрос

Является ли хорошей практикой использование базового / вспомогательного класса, который содержит полезные методы / переменные, которые наследуются всеми вашими другими тестами, или каждый тестовый класс должен быть «самодостаточным»?

Спасибо!


person Quentin Donnellan    schedule 13.02.2014    source источник


Ответы (2)


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

Мне нравится такой подход. Но вы также можете попробовать нос. Nose немного легче настроить, и он хорошо поддерживается, если вы идете по маршруту непрерывной интеграции с чем-то вроде Jenkins для автоматической сборки / тестирования / развертывания. Nose не так хорошо форматирует свои сообщения, как стиль xUnit (IMO, конечно). Но по многим вещам вы можете отказаться от этого.

КСТАТИ. Python - это не Java. Таким образом, вполне приемлемо повторно использовать простую старую функцию Python для повторного использования.

person Fred Mitchell    schedule 13.02.2014

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

Также подумайте о ценности просмотра кода в вашем тестовом классе. Хорошим примером является базовый класс, который я использую все время (в C # .NET): я использую SDK - ArcObjects от Esri, для которого требуется лицензия. При нормальном исполнении это обрабатывается где-то еще, но при тестировании я должен проверить (или активировать) лицензию, прежде чем я смогу использовать объекты в библиотеке. Это не имеет абсолютно никакого отношения к функциональности кода, который я тестирую в тестовом классе, но требуется для запуска тестов. Таким образом, я решил убрать эту функциональность в базовый класс, который проверяет лицензию перед тестом и возвращает ее после. Тесты, требующие лицензии, просто наследуются от этого базового класса.

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

person Morten    schedule 13.02.2014