Модульное тестирование, когда вывод представляет собой стену текста - PullRequest
3 голосов
/ 10 октября 2011

В настоящее время я тестирую часть моего приложения (мы будем предполагать, что это класс с именем X), который принимает в качестве параметра метод java отражения и распечатывает некоторый код Java на его основе (то есть этогенератор кода).Например, при передаче String.toString() в X вывод отображаемой строки будет выглядеть так:

public static java.lang.String toString(String thisObj, boolean isMonitoring) {
    String thisObjOld = (String)thisObj.clone(thisObj, false);

    if (isMonitoring) {
        toStringPre(thisObj);
    }

    java.lang.String result = thisObj.toString_Original();

    if (isMonitoring) {
        toStringPost(thisObj, thisObjOld, result);
    }

    return result
}

Теперь мне интересно, как проверить этот вывод.Я хотел бы проверить разные вещи (индивидуально).

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

Примеры того, что я ищу для проверки:

  • Если тип возвращаемого значения правильный (java.lang.String);
  • Если имя метода правильное (toString), а также его параметры `(String thisObj, boolean isMonitoring).

Как лучше подойти к этому?Используя регулярные выражения?Использование String.split()?

Ответы [ 3 ]

2 голосов
/ 10 октября 2011

Как насчет компилирования сгенерированного кода - Проверьте, что код синтаксически корректен.

Затем используйте Reflection для проверки имени, параметра и типа возврата.

Затем запустите его в Mocked-среде, чтобы убедиться, что он делает то, что должен.

1 голос
/ 10 октября 2011

Я думаю, что если сгенерированный код является очень детерминированным (и если посмотреть на ваш вопрос, он выглядит выглядит детерминированным), то я сначала вручную напишу правильный вывод строки из X и выполню сравнение строк,

Например, пример junit:

public void testX(){
   X gnerator = new X(getTestMethodObject());
   Assert.assertEquals(StringUtils.readFully(new File("expected_output.txt")), generator.generate());
}

Очевидно, что это будет выполнять сравнение строк, и когда сгенерированное содержимое изменится, вам придется вручную написать новый ожидаемый результат.Следовательно, хотя это и просто, но может в дальнейшем стать кошмаром обслуживания.

Другой способ, конечно, заключается в том, чтобы сгенерировать сгенерированный вывод и проверить сгенерированные токены (я предполагаю, что вы не можете скомпилировать сгенерированный код в своей тестовой среде).Скажем, http://code.google.com/p/java-lexer/, который является действительно простым лексором (я не ручаюсь за это - я просто нашел его за пару минут поиска в Google ... но у него есть некоторые базовые тесты , так что яПредположим, это хорошо?).Или используйте что-то более сложное , например antlr , что, вероятно, излишне для тестирования.

Лично я бы остановился на сравнении ожидаемого результата, написанного от руки, с генерируемым результатом.Его гораздо более низкий ключ, и он легче обнаруживает ошибки, чем использование полноценных лексоров.

0 голосов
/ 10 октября 2011

Почему бы вам не 1) скомпилировать сгенерированный код и использовать отражение для утверждения "семантики", или, если компиляция и загрузка невозможны из-за зависимостей и прочего, 2) использовать анализатор JAVA для создания абстрактного синтаксиса дерево, которое вы можете пройти и сделать утверждения. (Проект ANTLR имеет грамматики для JAVA 6, например).

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