Автоматическая генерация тестирования низкого уровня на основе желаемых поведенческих примеров высокого уровня - PullRequest
1 голос
/ 14 апреля 2019

Проблема верхнего уровня

Наша команда унаследовала очень большую и хрупкую кодовую базу Python 2 (и C, C ++, несколько других), которую очень сложно и дорого обновить.Тонны зависимостей.Очень мало тестов.Добавление улучшения поведения и переход на Python 3 оба оказались монументальными задачами.Даже делая небольшие изменения в новом выпуске, нам приходилось много раз возвращаться, потому что он что-то сломал.

Это история недостаточного тестирования и значительных технических долгов.

Тем не менее, проект настолько большой и полезный, что, кажется, нет ничего проще, чем обновить его, чем заново изобрести все, что он делает.

Подзадача

Как добавить огромное количество пропавших без вестинебольшие тесты.Как мы можем автоматически генерировать даже простые модульные тесты ввода / вывода из высокоуровневых пользовательских приемочных тестов?

Попытка решения

Существует около 50 больших поведенческих тестов высокого уровня, которые должна обрабатывать эта кодовая база,К сожалению, для их запуска требуются дни, а не секунды.Они используют весь код, который нас больше всего интересует, но они слишком медленные.(Также занудное наблюдение, 80% одного и того же кода выполняется в каждом).Есть ли способ автоматически генерировать модульные тесты ввода / вывода из автоматической проверки стека при их запуске?

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

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

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

Какие-нибудь подсказки для инструментов автоматического тестирования?Я много гуглял и нашел некоторые вещи, которые могут работать на C, но я не могу найти ничего для python, который генерирует pytests / unittest / nose или что-то еще.Мне все равно, какой тестовый фреймворк Python он использует (хотя предпочел бы pytest).Должно быть, я искал неправильные термины, так как кажется невероятным, что инструмент создания тестов для python не существует.

Ответы [ 2 ]

1 голос
/ 21 апреля 2019

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

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

  • Какими должны быть тестируемые блоки?Отдельные методы, группы методов, группы классов?Например, методы установки не могут быть разумно протестированы без других методов.Или, чтобы протестировать любой метод, сначала должен существовать созданный объект, и, следовательно, потребуется некоторый вызов конструктора.
  • Каковы границы компонента?Какие компоненты зависят?С какими из зависимых компонентов вы можете просто жить, над чем нужно было бы издеваться?Многие компоненты могут быть просто использованы как есть - вы не будете высмеивать математические функции, такие как sin или cos, например.
  • Каковы границы между юнит-тестами, то есть в каких точках долгосрочной работытесты, которые вы считаете модульным тестом, чтобы начать и закончить?Какая часть записи считается настройкой, какое выполнение, какая проверка?

Все эти трудности объясняют мне, почему некоторые общие инструменты могут быть трудно найти, и вам, вероятно, придется оставить специально созданные сценариидля генерации тестового кода.

0 голосов
/ 28 мая 2019

Я выбрал очень ленивое и практичное несовершенное решение, и мне потребовалось около 40 часов: 20 из них обернули мою голову вокруг части C достаточно, чтобы написать для нее модульные тесты и исправить ее, что составило около 30 строк- остальные 20 исправляли в основном тривиальные проблемы с байтами / строками, которые невозможно было решить с помощью futurize, и настраивали CI.

  1. Run futurize
  2. Запуск наиболее желательного варианта использования в качествеПроблемы тестирования и исправления E2E, дополненные новыми критическими модульными тестами
  3. CI с токсиком в 2.7 / 3.x для этих

Конечным результатом является неизмененная 2.7 кодовая база и минимально работающаякодовая база бета-версии 3.7, поддержка длинного хвоста 3.7 для вторичных вариантов использования, которые должны быть решены с течением времени, см. долгосрочный ответ Дирка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...