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

Как документировать документальные тесты?

Я пытаюсь улучшить количество и качество тестов в моих проектах Python. Одна из трудностей, с которыми я столкнулся, по мере увеличения количества тестов, - это знание того, что делает каждый тест и как оно должно помочь выявить проблемы. Я знаю, что часть отслеживания тестов лучше unit test имен (которые были адресованы в другом месте), но я также заинтересован в понимании того, как документация и модульное тестирование идти вместе.

Как можно документировать документированные модульные тесты, чтобы улучшить их полезность, когда эти тесты не удастся в будущем? В частности, что делает хороший unit test docstring?

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

4b9b3361

Ответ 1

Я документирую большинство своих модульных тестов исключительно с помощью имени метода:

testInitializeSetsUpChessBoardCorrectly()
testSuccessfulPromotionAddsCorrectPiece()

Для почти 100% моих тестовых примеров это четко объясняет, что проверяет unit test и что все, что я использую. Однако в нескольких более сложных тестовых примерах я добавлю несколько комментариев по всему методу, чтобы объяснить, что делают несколько строк.

Я видел инструмент раньше (я считаю, что это для Ruby), который будет генерировать файлы документации, анализируя имена всех тестовых примеров в проекте, но я не помню имя. Если у вас были тестовые примеры для класса Queen Queen:

testCanMoveStraightUpWhenNotBlocked()
testCanMoveStraightLeftWhenNotBlocked()

инструмент создаст HTML-документ с содержимым примерно так:

Queen requirements:
 - can move straight up when not blocked.
 - can move straight left when not blocked.

Ответ 2

Возможно, проблема заключается не в том, как лучше всего писать тестовые docstrings, а как сами писать тесты? Рефакторинг тестов таким образом, что они сами документируют, могут пройти долгий путь, и ваша документация не будет устаревать при изменении кода.

Есть несколько вещей, которые вы можете сделать, чтобы сделать тесты более ясными:

  • Явные и описательные имена методов тестирования (уже упоминалось)
  • тестовое тело должно быть четким и кратким (самодокументирующимся)
  • абстрактные прочь сложная настройка/разрывы и т.д. в методах
  • больше?

Например, если у вас есть такой тест:

def test_widget_run_returns_0():
    widget = Widget(param1, param2, "another param")
    widget.set_option(true)
    widget.set_temp_dir("/tmp/widget_tmp")
    widget.destination_ip = "10.10.10.99"

    return_value = widget.run()

    assert return_value == 0
    assert widget.response == "My expected response"
    assert widget.errors == None

Вы можете заменить операторы установки вызовом метода:

def test_widget_run_returns_0():
    widget = create_basic_widget()
    return_value = widget.run()
    assert return_value == 0
    assert_basic_widget(widget)

def create_basic_widget():
    widget = Widget(param1, param2, "another param")
    widget.set_option(true)
    widget.set_temp_dir("/tmp/widget_tmp")
    widget.destination_ip = "10.10.10.99"
    return widget

def assert_basic_widget():
    assert widget.response == "My expected response"
    assert widget.errors == None

Обратите внимание, что ваш тестовый метод теперь состоит из серии вызовов методов с раскрывающимися именами, своего рода DSL, специфичным для ваших тестов. Необходим ли такой тест для документации?

Еще одна вещь, которую следует отметить, заключается в том, что ваш метод тестирования в основном на одном уровне абстракции. Кто-то, читающий тестовый метод, увидит, что алгоритм:

  • создание виджета
  • вызов прогона в виджетах
  • утверждение кода делало то, что мы ожидаем

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

Первая версия метода тестирования следует за Inline Setup. Вторая версия следует Метод создания и Делегированные настройки.

В общем, я против комментариев, кроме тех случаев, когда они объясняют "почему" кода. Чтение дяди Боба Мартина Clean Code убедил меня в этом. Существует глава по комментариям, и есть глава по тестированию. Я рекомендую его.

Подробнее о методах автоматического тестирования см. xUnit Patterns.

Ответ 3

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

Ответ 4

Вы должны использовать комбинацию описательных имен методов и комментариев в строке doc. Хороший способ сделать это включает в себя базовую процедуру и шаги проверки в строке документа. Затем, если вы запустите эти тесты из какой-либо структуры тестирования, которая автоматизирует запуск тестов и сбор результатов, вы можете иметь фреймворк для регистрации содержимого строки документа для каждого метода тестирования вместе со своим stdout + stderr.

Вот базовый пример:

class SimpelTestCase(unittest.TestCase):
    def testSomething(self):
        """ Procedure:
            1. Print something
            2. Print something else
            ---------
            Verification:
            3. Verify no errors occurred
        """
        print "something"
        print "something else"

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

Ответ 5

Когда тест завершится с ошибкой (который должен быть до того, как он когда-либо пройдет), вы увидите сообщение об ошибке и сможете сказать, что происходит. Это происходит только в том случае, если вы планируете это.

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

Этого не происходит, если именем прибора является ClassXTests, а имя теста - TestMethodX, и сообщение об ошибке "ожидается true, false false". Это признак небрежного написания теста.

В большинстве случаев вам не нужно читать тест или какие-либо комментарии, чтобы знать, что произошло.