Автоматическая генерация тестов по комментариям к программному коду
1. Московский Государственный Университет им М.В Ломоносова
Факультет Вычислительной Математики и Кибернетики
Автоматическая генерация
тестов по комментариям к
программному коду
Носков А. А.
alexey.noskov@gmail.com
2. Проблемная область
Среди характеристик качественного ПО:
Надежность (достигается тестированием)
Наличие документации к коду
В тестах фиксируется поведение, ожидаемое
от элементов ПО
В документацию входит описание того, какое
поведение ожидается
Дублирование ?
2
3. Конкретизация области
Документация
Интерфейсные комментарии в элементам
кода (функциям, классам, методам, ...)
Предназначены для программиста,
использующего эти элементы
JavaDoc, RDoc, Doxygen, ...
Тесты
Модульные тесты, проверяющие корректность
поведения элементов кода
JUnit, CppUnit, Test::Unit
3
4. Задачи работы
Метод генерации модульных тестов
На основе описания поведения объектов кода
в комментариях
•
Ограниченный ЕЯ, удобный для человека и
автоматической обработки
НЕ включается:
‒ Построение тестов по произвольным
комментариям
‒ Генерация полного тестового покрытия
‒ Генерация регрессионных тестов
4
5. Реализация метода
Плагин для IDE Eclipse, осуществляющий
генерацию модульных тестов JUnit
Генерация тестов к коду на Java
Обрабатываемые комментарии – JavaDoc
Язык реализации – Java
Для выделения конструкций ЕЯ – LSPL
Язык лексико-синтаксических шаблонов
Для морфологического анализа – AOT
5
6. Схема метода
Комментарии на ЕЯ
Выделение
LSPL-шаблоны
именований
именований
объектов кода
Выделение
LSPL-шаблоны
описаний
свойств
свойств объектов
Генерация тестов
Тесты 6
7. Примеры комментариев
/**
* Вычислить факториал.
*
* Например, если аргумент равен 3, то факториал 6.
* А если аргумент 4, то 24
*
* @param value аргумент, больше 0
* @return значение факториала, не меньше аргумента
* @throws IllegalArgumentException если аргумент меньше 0
*/
public static int factorial( int value )
/**
* Нахождение наибольшего общего делителя двух чисел.
*
* @param a первое число
* @param b второе число
*
* Остаток от деления первого числа на результат равен 0.
* Остаток от деления второго числа на результат равен 0.
*
* @return наибольший общий делитель чисел
*/
public static int nod(int a, int b) 7
8. Выделение именований
Объекты кода именуются в комментариях
Эти имена используются человеком при описании
свойств в комментариях
Для выделения именований можно использовать
разметку комментариев в виде тэгов (JavaDoc,
Doxygen, Rdoc)
Выделяются по шаблонам именных групп,
описанным на LSPL (NG = {A|Num} N)
Стандартные именования (“аргумент”, “результат”)
8
9. Выделение именований
Примеры
/**
* Вычислить факториал.
*
* Например, если аргумент равен 3, то факториал 6.
* А если аргумент 4, то 24
*
* @param value аргумент, больше 0
* @return значение факториала, не меньше аргумента
* @throws IllegalArgumentException если аргумент меньше 0
*/
public static int factorial( int value )
/**
* Нахождение наибольшего общего делителя двух чисел.
*
* @param a первое число
* @param b второе число
*
* Остаток от деления первого числа на результат равен 0.
* Остаток от деления второго числа на результат равен 0.
*
* @return наибольший общий делитель чисел
*/
public static int nod(int a, int b) 9
10. Выделение описаний свойств
объектов
LSPL-шаблоны:
Объектов кода (аргументы, результат) –
генерируются на основе именований
Описаний свойств – описываются заранее
Распознование в тексте комментария
описания свойств объектов на основе
шаблонов
Результаты распознавания => внутреннее
представление свойств
10
11. Выделение свойств
Примеры
/**
* Вычислить факториал.
*
* Например, если аргумент равен 3, то факториал 6.
* А если аргумент 4, то 24
*
* @param value аргумент, больше 0
* @return значение факториала, не меньше аргумента
* @throws IllegalArgumentException если аргумент меньше 0
*/
public static int factorial( int value )
/**
* Нахождение наибольшего общего делителя двух чисел.
*
* @param a первое число
* @param b второе число
*
* Остаток от деления первого числа на результат равен 0.
* Остаток от деления второго числа на результат равен 0.
*
* @return наибольший общий делитель чисел
*/
public static int nod(int a, int b) 11
12. Генерация тестов
Выделение тестируемых наборов свойств:
Условия в конкретных примерах
Взаимосвязи между аргументами и
результатом
Выбор значений аргументов, если они не
заданы
Генерация кода тестов для выделенных
наборов свойств
12
13. Генерация тестов
Примеры
@Test public void factorial0() {
int value = 3;
если аргумент равен 3, int result = TestClass.factorial(value);
то факториал 6
assertEquals( 6, result );
}
@Test public void factorial1() {
int value = 4;
int result = TestClass.factorial(value);
если аргумент 4, то 24
assertEquals( 24, result );
}
@Test public void nod0() {
int a = 12;
Остаток от деления int b = 16;
первого числа int result = TestClass.nod( a, b );
на результат равен 0
assertEquals( 0, a % result );
}
@Test public void nod1() {
int a = 5;
Остаток от деления int b = 10;
второго числа int result = TestClass.nod( a, b );
на результат равен 0
assertEquals( 0, b % result ); 13
}
14. Ближайшие планы
Расширения множества описываемых
условий
Обработка условий порождения исключени
Описание изменения состояния объекта:
Доступ к полям
Вызов методов
Обработка условий, заданных в контексте
некоторого элемента
14