Страница 1 из 2
Unit test в разрезе паскаля
Добавлено:
16.03.2010 07:54:28
Brainenjii
Последнее время часто слышу словосочетание "Unit test". Почитал википедию - штука вроде классная - часто после обновления куска кода получал мелкие глюки в совершенно неожиданных местах ^_^ Но как это реализовывать на fpc? Кто-нибудь пробовал?
Re: Unit test в разрезе паскаля
Добавлено:
16.03.2010 09:50:55
Climber
Теория.Юнит-тестированию лучше всего поддается код, написанный в функциональном стиле (см.
функциональное программирование). То есть все параметры, от которых может зависеть результат работы функции, лучше передавать в нее в качестве аргументов. Это не всегда удается, но чем чаще, тем лучше.
Практика.Есть модуль fpcunit в папке lazarus/components/fpcunit. Там лежит обычный пакет, после установки которого в меню "Создать" появляется пункт "fpcunit application". На freepascal.org есть файлик fpcunit.pdf, там мануал, могу скинуть. Пакет содержит набор классов для тестирования и гуи оболочку. Модуль является аналогом JUnit (java).
Re: Unit test в разрезе паскаля
Добавлено:
16.03.2010 10:26:01
Brainenjii
Вы с ним работали? Насколько это применимо? ^_^ Сейчас смотрю на свой код - не представляю как это реализовать
Re: Unit test в разрезе паскаля
Добавлено:
16.03.2010 11:59:39
Climber
Работал. Применимо. Осталось одолеть свою всепобеждающую лень и написать тесты на каждый чих в программе. Проблема в том, что написание теста занимает довольно много времени, а времени всегда не хватает. Ну и есть пара глюков - не глюков, но вопросов... Короче, тесты тоже надо тестировать - задавать заведомо провальные условия и смотреть, ругнется или нет. Некоторые из тамошних Assert'ов, как мне показалось, не работают.
Добавлено спустя 2 минуты 41 секунду:
Я даже пытался написать свою надстройку для тестирования GUI и реализации некоторых плюшек, которые давно появились в JUnit (например, выполнение нескольких тестов с общими SetUp и TearDown). Но что-то у меня заглохло это дело...
Re: Unit test в разрезе паскаля
Добавлено:
03.05.2011 09:11:29
Brainenjii
Подниму тему ^_^
Почитал книжки, узнал забавную аббревиатуру TDD и снова вернулся в FPCUnit. Стало понятнее, даже заработало, но стало напрягать отсутствие интеграции с IDE. В описании к новому проекту FPCUnit Application сказано, что "Application source is automatically maintained by Lazarus", но не совсем понятно, как это самое automatically maintained добиться. Сейчас у меня два разных проекта - основной и тестовый. Тестовый использует модули основного, но писать так в стиле TDD почти невозможно - сборка тестового проекта запускает не основной, а, что характерно, тестовый...
Кто как пользуется FPCUnit?
Re: Unit test в разрезе паскаля
Добавлено:
04.05.2011 11:29:54
vada
В JAVA всяческие IDE, типа (NetBeabs, Eclipse) код для JUtil тестов генерится одним нажатием пипки. Только потом подправить надо параметры для методов и что ожидаем получить. Кода генерит уйму. Руками столько писать, реально, влом. Ошибок вылавливается, на удивление, много. Совершенно в неожиданных местах. Основная это NulPointException. Это когда какая-то шняга в классе еще значения не получила, а ее уже юзать пытаемся. Такую ошибку можно поймать только при прогоне программы. Юнит тесты помогают почти автоматически их ловить.
Re: Unit test в разрезе паскаля
Добавлено:
09.05.2011 10:49:16
Brainenjii
А можно поконкретней - что именно генерируется автоматически? ^_^ Начал писать пакет к лазарю, интегрирующий FPCUnit в IDE, можно попробовать туда и автоматический генератор тестов (ну или шаблонов к тестам) приделать ^_^
https://github.com/Brainenjii/lazunit
Re: Unit test в разрезе паскаля
Добавлено:
10.05.2011 11:42:43
vada
Ну вот из какого-то старого брошеного проекта.
Тестируется класс EntityBean таблицы базы данных PaperGroup
- Код: Выделить всё
package ru.printbroker.model;
// Generated 20.10.2009 11:30:43 by Hibernate Tools 3.2.1.GA
import java.util.HashSet;
import java.util.Set;
/**
* Papergroup generated by hbm2java
*/
public class Papergroup implements java.io.Serializable {
private int pkPaperGroup;
private String namePaperGroup;
private Set papertypes = new HashSet(0);
public Papergroup() {
}
public Papergroup(int pkPaperGroup) {
this.pkPaperGroup = pkPaperGroup;
}
public Papergroup(int pkPaperGroup, String namePaperGroup, Set papertypes) {
this.pkPaperGroup = pkPaperGroup;
this.namePaperGroup = namePaperGroup;
this.papertypes = papertypes;
}
public int getPkPaperGroup() {
return this.pkPaperGroup;
}
public void setPkPaperGroup(int pkPaperGroup) {
this.pkPaperGroup = pkPaperGroup;
}
public String getNamePaperGroup() {
return this.namePaperGroup;
}
public void setNamePaperGroup(String namePaperGroup) {
this.namePaperGroup = namePaperGroup;
}
public Set getPapertypes() {
return this.papertypes;
}
public void setPapertypes(Set papertypes) {
this.papertypes = papertypes;
}
}
Для этого класса генерится тестовый класс, который вызывает все методы класса PaperGroup
- Код: Выделить всё
/*
*
*
*/
package ru.printbroker.model;
import java.util.Set;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
* @author pikin
*/
public class PapergroupTest {
public PapergroupTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@Before
public void setUp() {
}
@After
public void tearDown() {
}
/**
* Test of getPkPaperGroup method, of class Papergroup.
*/
@Test
public void testGetPkPaperGroup() {
System.out.println("getPkPaperGroup");
Papergroup instance = new Papergroup();
int expResult = 0;
int result = instance.getPkPaperGroup();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of setPkPaperGroup method, of class Papergroup.
*/
@Test
public void testSetPkPaperGroup() {
System.out.println("setPkPaperGroup");
int pkPaperGroup = 0;
Papergroup instance = new Papergroup();
instance.setPkPaperGroup(pkPaperGroup);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getNamePaperGroup method, of class Papergroup.
*/
@Test
public void testGetNamePaperGroup() {
System.out.println("getNamePaperGroup");
Papergroup instance = new Papergroup();
String expResult = "";
String result = instance.getNamePaperGroup();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of setNamePaperGroup method, of class Papergroup.
*/
@Test
public void testSetNamePaperGroup() {
System.out.println("setNamePaperGroup");
String namePaperGroup = "";
Papergroup instance = new Papergroup();
instance.setNamePaperGroup(namePaperGroup);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of getPapertypes method, of class Papergroup.
*/
@Test
public void testGetPapertypes() {
System.out.println("getPapertypes");
Papergroup instance = new Papergroup();
Set expResult = null;
Set result = instance.getPapertypes();
assertEquals(expResult, result);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
/**
* Test of setPapertypes method, of class Papergroup.
*/
@Test
public void testSetPapertypes() {
System.out.println("setPapertypes");
Set papertypes = null;
Papergroup instance = new Papergroup();
instance.setPapertypes(papertypes);
// TODO review the generated test code and remove the default call to fail.
fail("The test case is a prototype.");
}
}
В тестовом классе в методах следует подправить значения, которые подставляются для вызовов методов... В данном варианте ничего не подправлено. Все в девственном виде после генерации.
И такие классы генерятся для всех классов указанного для генерации пакета. Потом генерится main класс из которого вызываются все тесты. Валится огромный лог из кторого выиискиваем какой метод у нас вернул false или exception. Разбираемся чёпочём....
Надеюсь, у паскалистов не будет проблем с чтением JAVA кода.
Re: Unit test в разрезе паскаля
Добавлено:
10.05.2011 12:05:53
Brainenjii
А в процессе дополнения класса Papergroup - в тестовом классе автоматом появляются шаблоны новых тестов?
Re: Unit test в разрезе паскаля
Добавлено:
10.05.2011 12:15:53
vada
А в процессе дополнения класса Papergroup - в тестовом классе автоматом появляются шаблоны новых тестов?
Нет. Надо перегенерить и поновой доработать напильником. Хотя... зуб не дам. Не приходилось серьезно класс ломать.
Re: Unit test в разрезе паскаля
Добавлено:
10.05.2011 14:16:26
Max Rusov
IMHO - ерунда какая-то. Какой смысл создавать по экземпляру для вызова каждого метода? Что так можно протестировать? Из этого "тестового" класса придется выкинуть 90% мусора и все значимые проверки писать руками - что мы имеем и без этих хлопот. Лишний раз показывает что вся эта "автоматизация" - от лукавого.
Re: Unit test в разрезе паскаля
Добавлено:
10.05.2011 14:38:48
vada
Я привел самый простейший код. Чтоб понятно было что и как.
На самом деле даже такой тест совсем не ерунда. И в такой "ерунде" встречаются ошибки.
Есть такое понятие как правильность программы. Причем, правильность программы можно доказать математически.
Доказательство операется на положение что если на в ход блока подаются правильные данные и из блока выходят правильные данные то такой блок является правильным. Эти тесты в частности для этого и служат.
Re: Unit test в разрезе паскаля
Добавлено:
10.05.2011 16:45:53
Max Rusov
Методы класса работают в совокупности, какой смысл проверять их на новом экземпляре? Например: get/set. Типично проверить, что get возвратил то, что перед этим установили через set; что крайние значения устанавливаются корректно, а значения выходящие за допустимый диапазон возбуждают корректные ошибки... Ничего подобного в приведенном примере и близко не наблюдается, 90% кода - мусор.
vada писал(а):Причем, правильность программы можно доказать математически.
Разница между теорией и практикой на практике гораздо глубже чем разница между теорией и практикой в теории...
Re: Unit test в разрезе паскаля
Добавлено:
11.05.2011 09:58:07
vada
Разница между теорией и практикой на практике гораздо глубже чем разница между теорией и практикой в теории...
Только на практике ни один нормальный заказчик не пример работу без JUNIT тестов.
Re: Unit test в разрезе паскаля
Добавлено:
11.05.2011 10:57:13
Max Rusov
vada писал(а):Только на практике ни один нормальный заказчик не пример работу без JUNIT тестов.
Смешно.