Я пишу юнит-тесты для системы рулевого управления для видеоигры. Система имеет несколько вариантов поведения (избегайте этой области по причине A, избегайте этой области по причине B, каждый из которых добавляет немного контекста к карте региона. Затем отдельная функция анализирует карту и производит желаемое движение.
У меня проблемы с решением, как написать модульные тесты для поведения. Как предполагает TDD, меня интересует только то, как поведение влияет на желаемое движение. Например, избегание по причине причины A должно привести к отходу от предполагаемой плохой позиции. Меня не волнует, как и почему поведение добавляет контекст на карту, только то, что желаемое движение находится вдали от позиции.
Поэтому мои тесты для каждого поведения настраивали поведение, заставляли его записывать на карту, а затем выполняли функцию анализа карты, чтобы выработать желаемое движение. Если это движение удовлетворяет моим требованиям, я счастлив.
Однако теперь мои тесты зависят как от правильного поведения, так и от функции синтаксического анализа карты. Если функция синтаксического анализа завершится неудачно, я получу сотни неудачных тестов, а не пару. Многие руководства по написанию тестов предполагают, что это плохая идея.
Однако, если я протестирую напрямую по результатам поведения путем макетирования карты, то наверняка я слишком тесно связан с реализацией? Если я могу получить то же самое желаемое движение с карты, используя немного другое поведение, тогда тесты все равно должны пройти.
Так что теперь я страдаю от когнитивного диссонанса. Каков наилучший способ структурировать эти тесты?
источник
Ответы:
В идеальном мире у вас действительно будет набор совершенно ортогональных модульных тестов, все на одном уровне абстракции.
В реальности у вас обычно есть тесты на разных уровнях приложения, поэтому часто тесты более высокого уровня имеют функциональность, которая уже была протестирована с помощью специализированных тестов более низкого уровня. (Многие люди предпочитают называть такие высокоуровневые тесты подсистемными / интеграционными тестами, а не модульными тестами; тем не менее они все еще могут работать на той же платформе модульного тестирования, поэтому с технической точки зрения нет большой разницы.)
Я не думаю, что это плохо. Суть в том, чтобы ваш код был протестирован наилучшим образом, который соответствует вашему проекту и вашей ситуации, а не придерживаться «идеального пути».
источник
Этот вид тестирования - вот почему были изобретены макеты. Основная идея: вы пишете макет для вашего объекта (карта, поведение, персонаж, ...), а затем пишете тесты, используя этот макет вместо реального объекта. Люди иногда называют фиктивные окурки, и я считаю, что есть и другие слова для обоих.
В вашем случае вы должны написать макет для карты всякий раз, когда вам нужно проверить поведение, и другие макеты для поведения, когда вы хотите проверить карту. Ваши макеты в идеале должны быть намного проще, чем реальное поведение, над которым вы издеваетесь, только с использованием методов или переменных, которые вам действительно нужны для этого теста. Возможно, вам придется написать разные макеты для каждого теста, или вы можете повторно использовать некоторые макеты. В любом случае, они должны подходить для теста и не должны пытаться быть настолько похожими на реальное поведение, насколько это возможно.
Если бы вы включили несколько примеров карт или поведения, возможно, кто-то мог бы привести примеры издевательств, которые вы могли бы написать. Не я, поскольку я никогда не программировал более продвинутую видеоигру, чем Понг, и даже тогда я следил за книгой, но, возможно, кто-то хорошо разбирался в юнит-тестировании и разработке игр.
источник
Я думаю, что вы пытаетесь проверить вещи, которые намного выше уровня, чем юнит.
Большинство поведенческих тестов требуют некоторого интеллекта, чтобы определить, правильно ли он себя ведет. Это не может быть легко сделано с помощью автоматического тестирования.
источник