Генерация кода JUnit на основе обхода дерева абстрактного синтаксиса - PullRequest
2 голосов
/ 23 марта 2011

Предполагая, что у меня есть следующий класс и метод:

package generation;

class HelloWorld {
  public boolean isEven(int val) {
    if ( (val % 2) == 0)
      return true;
    else
      return false;
  }
}

Предположим, я хочу сгенерировать следующий тест JUnit:

генерация пакетов;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import org.junit.Test;

public class HelloWorldTest {

    @Test
    public void testIsEven() {
        HelloWorld h = new HelloWorld();
        assertTrue(h.isEven(2));
        assertFalse(h.isEven(1));
    }
} 

Учитывая следующий метод обхода дерева синтаксиса Java: Как я могу использовать абстрактное синтаксическое дерево Java Eclipse в проекте вне Eclipse? (т.е. не плагин Eclipse)

Как бы вы сгенерировали код для генерации тестового примера, учитывая пример класса вверху?

Ответы [ 2 ]

2 голосов
/ 24 марта 2011

Вам нужно гораздо больше, чем просто дерево разбора. (Эту ошибку повторяют практически все, кто не создал серьезного инструмента анализа программ; вам нужно гораздо больше механизмов, чтобы делать что-то действительно интересное. Именно поэтому компиляторы не тривиальны).

В «простейшем» случае требуется синтаксический анализ кода метода, подлежащего тестированию, в AST, имя / тип, разрешающий все, чтобы вы знали значение всех символов (вы должны знать, что val в целом числе), и определение управление течет через код и предикаты, управляющие ими.

С этой информацией вы можете по существу перечислить действительные пути потока управления, собирая информацию о предикатах вдоль пути для каждого из них, образуя в сущности соединение всех условий на этом пути. (В вашем примере if .. val% 2 ... return true; - это один путь, управляемый val% 2 == true ). Вы можете беспокоиться о моделировании влияния побочных эффектов на пути на различные предикаты. И вы хотели бы получить информацию о целых числах (и размерах строк, массивов и т. Д.).

Затем для каждого пути вам нужно сгенерировать набор входных аргументов, который делает предикат пути истинным; учитывая, что этот предикат может быть довольно сложным, вам, вероятно, понадобится какой-нибудь SAT solver . С решениями для предиката пути теперь вам нужно сгенерировать AST, соответствующие тестам (например, установить переменные, чтобы аргументы метода могли удовлетворять предикату; для простых целочисленных уравнений вы, скорее всего, можете просто генерировать выражения для аргументов, как в вашем пример). Наконец, соберите тестовые вызовы в AST для метода, вставьте в AST, представляющий метод тестового примера, и распечатайте результат.

Ну, это было не так сложно: -}

Наш инструментарий реинжиниринга программного обеспечения DMS имеет внешний интерфейс Java , который будет анализировать Java, создавать AST, перечислять пути потока управления через метод [это не так просто: рассмотрим исключения ], вычислить ограничения диапазона целочисленных переменных и дать вам общую возможность лазить по AST для извлечения / построения того, что вы хотите. Пока не включает решатель SAT, но мы думали об этом.

0 голосов
/ 24 марта 2011

Возможно, вы захотите пропустить неуклюжую, едва определенную часть ваших вопросов и изучить тестирование на основе свойств .

...