Большинство алгоритмов оптимизации (включая эвристику) работают с некоторыми конфигурациями (в вашем примере с маршрутом), применяя к ним операции. Операции сами по себе должны гарантировать, что они доставляют только допустимые конфигурации, поэтому сначала необходимо провести модульные тесты для каждой из них. Когда вы точно знаете, что алгоритм оптимизации использует только эти операции, обычно не нужно проверять правильность результата алгоритма.
Чтобы создать хорошие модульные тесты для любого более сложного алгоритма, нужно знать сам алгоритм подробно . Для простых эвристик, таких как «восхождение на гору», вы обычно можете предсказать результат для небольших входных данных. Например, для начальных маршрутов от 3 до 5 баллов при задании в определенном порядке вы можете предсказать, что произойдет. Это останется верным для большинства детерминированных эвристических алгоритмов, которые я знаю, так что это, вероятно, хорошее место для начала.
Для более сложных алгоритмов и большего размера входных данных, когда вы просто вводите входные данные в алгоритм и пытаетесь проверить выходные данные, вы на самом деле больше не выполняете модульный тест, вы проводите приемочный или интеграционный тест. Причина, по которой у вас возникают проблемы с «модульным тестированием» такого алгоритма, заключается в том, что он обычно состоит из нескольких небольших частей (отдельных блоков). Таким образом, для действительно модульного тестирования такого алгоритма вам придется идентифицировать эти части и тестировать их по отдельности. Кроме того, вы можете использовать покрытие кода или методы покрытия филиала, чтобы убедиться, что у вас достаточно тестовых случаев.
Если вы ищете не юнит-тесты, а автоматические приемочные или интеграционные тесты, вы можете попробовать то, что @Phillip предложил в (2) или (3) .