Я сейчас делаю небольшой проект по добавлению в putty возможности налету, прямо на уровне терминала, подсвечивать грамматику некоторого языка программирования. Основная сложность у меня в том, что язык крайне неуклюж - это некоторый диалект бейсика с парой сотней операторов, заточенных для работы с базой данных. Грамматика не контекстно-свободна, нерегулярна и полна неоднозначностей, которые разрешаются на основе огромного количества частных случаев.
В итоге я занимаюсь тем, что исправляю то там, то тут эти частные случаи. И обычно меняешь одно, и ломаешь десяток других мест.
В итоге после пары недель мытарств, я таки взял cmockery, написал всю необходимую «обвеску» и переделал все примеры в тесты.
Например:
void test_Ticket_dd6a19efa5_DATE(void **state) { string_eq("0029 ENTRIES<1, AB.CDE.VALUE.DATE> = TODAY", "..............a........................b......"); string_eq("0036 ENTRIES<1, AB.CDE.BOOKING.DATE> = TODAY", "..............a........................b......"); string_eq("0036 ENTRIES<1, AB.CDE.TOOKING DATE> = TODAY", "..............a.................bbbb...c......"); string_eq("0036 DATE = TODAY", ".....aaaa.b......"); string_eq("0036 DATE = TODAY", "......aaaa.b......"); } void test_Ticket_e8e02762a0_V_TIME(void **state) { string_eq("0017 V.TIME = 'x'", "................a.bbb"); string_eq("0034 V.DELTA = TIME() - TIME1", ".................a.bbbb...c......"); } void test_Ticket_0bcfac1fb6_READNEXT_FROM(void **state) { string_eq("0167 READNEXT ID FROM 9 ELSE DONE = 1 ", ".........aaaaaaaa....bbbb.c.dddd......e.f."); }
И таких тестов сотни.
Макрос string_eq
не является стандартным для cmockery, и под ним скрывается приличный кусок моего велосипеда. Вызывается функция подсветки строки, и по ней делается проход для отмечания факта смены цвета путем увеличения индекса (начальный индекс цвета - а
). Точка значит неподсвеченный символ. Немного топорно, но позволяет не хардкодить в тестах коды конретных цветов. Конечно, сильно облегчает жизнь тот факт, что данный язык строчно-ориентированный. Иначе все было бы сложнее.
После этого жизнь радикально изменилась. Теперь я легко меняю код и одной командой проверяю, не сломал ли я чего из старого. Те два дня, что я потратил на написание дополнительного кода для тестов уже в сотни раз окупились.
Каждую новую фичу (=очередной частный случай) или багфикс я начинаю с теста. И только потом код. Реально не могу представить, как бы я дальше работал над проектом без тестов.
Тут получается вообще чистая класска TDD – сначала тесты, а только потом код.