Я большой поклонник TDD и использую его для подавляющего большинства моих разработок в наши дни. Однако одна ситуация, с которой я сталкиваюсь довольно часто и никогда не находила того, что я считал «хорошим» ответом, - это что-то вроде следующего (надуманного) примера.
Предположим, у меня есть такой интерфейс (пишу на Java, но на самом деле это относится к любому языку OO):
public interface PathFinder {
GraphNode[] getShortestPath(GraphNode start, GraphNode goal);
int getShortestPathLength(GraphNode start, GraphNode goal);
}
Теперь предположим, что я хочу создать три реализации этого интерфейса. Давайте назовем их DijkstraPathFinder
, DepthFirstPathFinder
и AStarPathFinder
.
Вопрос в том, как мне разработать эти три реализации с использованием TDD? Их открытый интерфейс будет одинаковым, и, по-видимому, я бы написал одинаковые тесты для каждого, поскольку результаты getShortestPath () и getShortestPathLength () должны быть согласованы для всех трех реализаций.
Кажется, мой выбор:
Напишите один набор тестов против PathFinder
, поскольку я кодирую первую реализацию. Затем напишите две другие реализации "вслепую" и убедитесь, что они прошли тесты PathFinder
. Это кажется неправильным, потому что я не использую TDD для разработки вторых двух классов реализации.
Разрабатывайте каждый класс реализации тестовым способом. Это кажется неправильным, потому что я буду писать одинаковые тесты для каждого класса.
Объедините две техники выше; теперь у меня есть набор тестов для интерфейса и набор тестов для каждого класса реализации, что приятно, но тесты все те же, что нехорошо.
Это кажется довольно распространенной ситуацией, особенно при реализации шаблона Стратегии, и, конечно, различия между реализациями могут быть не просто временными сложностями. Как другие справляются с этой ситуацией? Есть ли шаблон для разработки в первую очередь для интерфейса, о котором я не знаю?