Тестирование блоков с помощью JUnit

Э

Та глава посвящена технологии, которая называется Тестированием блоков {Unit Testing). Идея тестирования блоков заключается в том, чтобы написать булевы методы для тестирования как можно большего количества аспектов кода. C помо­щью инструмента JUnit эти методы могут вызываться автоматически, а генерируе­мый ими отчет будет говорить об успешном или неудачном выполнении каждого отдельного теста.

Тестирование блоков — это, своего рода, стиль жизни. Это часть философии раз­работки, носящей название "экстремальное программирование". Одна из ключевых концепций экстремального программирования состоит в разработке кода, который всегда компилируется и выполняется правильно. Даже если написана только одна часть проекта, состоящего из сотен подобных частей, вам все равно необходимо до­биться того, чтобы эта одна часть выполнялась правильно.

Для подтверждения правильного функционирования программы необходимо на­писать последовательность булевых проверок, которые демонстрируют коррект­ность написанного кода. При добавлении кода в проект необходимо создавать новые проверки. Все тесты должны выполняться, по крайней мере, один раз, а же­лательно несколько раз в день. Они предоставят не только данные о работоспособ­ности новых частей кода, но и проверят, не нарушает ли вновь введенный код ранее написанный и протестированный код.

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

Большинство средств интеграции утилиты JUnit в JBuiIder присутствует только в редакции Enterprise. Тем не менее, JUnit представляет собой проект с откры­тым исходным кодом. Поэтому не волнуйтесь, вы сможете, да, собственно, и должны ис­пользовать утилиту JUnit независимо от редакции JBuiIder. Сначала в этой главе будет показано, каким образом средства JUnit интегрируются в среду JBuiIder, а затем кратко будет рассмотрен процесс написания и выполнения тестов при работе с редакцией JBuiIder Personal. Утилитой JUnit должны пользоваться все разработчики, а не только те, кто располагает редакцией Enterprise. Вы должны прочитать эту главу от начала до конца, независимо от используемой редакции JBuiIder, поскольку вы найдете здесь немало по­Лезной информации для всех редакций.

Тестирование блоков в редакции Enterprise

примечаниеВ этом разделе будет показано, как использовать утилиту JUnit В редакции JBuilder Enterprise. В последующих разделах мы остановимся на работе с JUnit В ре­дакции JBuilder Personal. Код, содержащийся в этой главе, в основном, взят из про­граммы UnitTesting, Которая входит в состав сопровождающих книгу материалов.

Код, генерируемый JBuiIder Enterprise, является всего лишь исходным ко­дом на языке Java для использования вместе с проектом JUnit. Таким образом, вы мо­жете выгрузить JUnit из Web-сайта Www. junit. org и выполнить сценарии, описанные ниже в этой главе. Сами сценарии не представляют никаких сложностей для понимания, и у вас вряд ли возникнут проблемы при их ручном наборе. Кроме того, на сайте проекта JUnit находится код, предназначенный для автоматической генерации тестов, поэтому от­крытый код можно использоваться в редакции JBuiIder Enterprise. Таким образом, эта глава Предназначена для всех читателей, а не только пользователей JBuiIder Enterprise.

В соответствии с указаниями, приведенными в главе 3, создайте новое приложе­ние, и в файл Framel. Java Поместите следующий код:

Public int add(int a, int Ь)

{

Return А + Ь;

)

Public int multiply (int a, int Ь)

{

Return А * Ь;

)

Не беспокойтесь о вызове приведенных в примере методов. Пока что достаточно ТОГО факта, ЧТО ОНИ ВКЛЮЧенЫ В файл Framel. Java.

Убедитесь, что в панели содержимого выбран Framel. В меню JBuilder выберите File I New и перейдите на страницу Test (Тестирование) окна Object Gallery. Выберите опцию Test Case (Тестовый случай). На экране появится диалоговое окно, показан­ное на рис. 30.1. Выберите два открытых метода, содержащиеся в диалоговом окне,

рис. 30.1. выбор методов add и multiply из framel для их тестирования с помощью junit

626

И нажмите кнопку Finish. Сейчас можно не проходить по всем шагам мастера и пос­ле ввода данных на первой странице сразу щелкнуть на кнопке Finish.

После щелчка на кнопке Finish код, приведенный в листинге 30.1, будет создан автоматически. Это код теста, необходимого для проверки корректной работы мето­да. Обратите внимание на присутствие очень важного оператора import junit. framework.* в начале исходного кода. Обратите внимание также на то, что класс TestFramel расширяет класс из платформы JUnit с именем TestCase. Класс расширяется с целью введения в него функциональных возможностей для тестиро­вания двух приведенных ранее методов. Все остальные функциональные возможно­сти, необходимые для автоматического вызова методов и вывода графического сооб­щения об успешном выполнении методов, встроены в сам инструмент ju∏it.

Листинг 30.1. Класс, сгенерированный средой JBuiIder и предназначенный для тестирования методов класса Framel

В приведенный код необходимо добавить только операторы assert

Package unitteβting;

Import junit. framework.*;

Import java. awt. event.*;

Import unittesting.*;

Public class TestFramel extends TestCase {

Public TestFramel(String s)

<

ɛuper(s);

)

Protected void setŋp()

{

1

Protected void tearDown()

{

1

Public void testAdd ()

(

Framel framel — new Framel(); int ale 2; intb2= 2;

Int IntRet = framel. add(al, b2);

)

Public void testMultiply()

{

Framel framel = new Framel () ; int al= 2; int b2= 3;

Int intRet = framel. multiply(al, b2);

B нашем случае код для настройки или разбивки класса не используется, поэто­му его можно удалить или просто проигнорировать. Кроме того, в методы testAdd и testMultiply потребуется вставить код, который собственно и будет выполнять те­стирование. Он рассматривается непосредственно после листинга 30.2. В результате мы получаем класс, код которого показан в листинге 30.2.

Листинг 30-2. Код тестирования класса Framel

Package Unittesting;

Import junit. framework.* ;

Import unittesting.*;

Public class TestFramel extends TestCase {

Public TestFramel(String s)

{

Super(s);

public void testʌdd()
[
framel frame 1 = new framel (); int al= 2; int b2= 2;
int intret = framel. add (al, b2); assertfquals( intret, 4);

}

Public void testMultiply()

Framel f ramel = new Framel (); int al= 2; int b2= 3 ;

Int IntRet = framel. multiply(alr b2); assertEquals( intRet, 6) ;

Давайте рассмотрим метод TestʌDd. Он использует код, созданный JBuilder, для подготовки теста, а затем вызывает метод AssertEquals. Метод AssertEquals Про­веряет, что возвращаемое методом Framel.Add значение равно 4. Если возвращае­мое значение равно 4, Тест считается выполненным успешно, в противном случае тест завершается неудачно. Аналогичный принцип положен и в основу метода TestMultiply.

Теперь, когда все подготовительные работы для тестирования выполнены, следу­ющий шаг заключается в запуске тестового кода и оценке правильности его выпол­нения. Для этого выберите в панели проекта файл TestFrameIjava. Щелкните пра­вой кнопкой мыши и в появившемся контекстном меню выберите пункт Run. Вы запускаете не главное приложение, а только код тестирования, который сгенериро­ван мастером JBuilder Wizard. Результат успешного выполнения тестового кода по­казан на рис. 30.2.

Интегрированная среда разработки JBuilder выдает визуальный результат, кото­рый позволяет оценить правильность выполнения тестового кода. На рис. 30.2 по­казан случай, когда оба теста были выполнены успешно, в то время как на рис. 30.3 показан случай, когда второй тест выполняется неправильно. На цветном мониторе успешное и неудачное выполнение тестов отличается цветом сообщений. Так, ус­пешные тесты отмечаются зеленым цветом, а неудачные — красным.

Второй тест может завершиться неудачно, если метод TestMultiply Изменить следующим образом:

Public void testMult±ply()

1

Fraunel f ramel = new Fraunel () ; int al= 3; int b2= 3 ;

In⅛ intRet = framel. multiply(al, b2) ; assertEquals( intRet, 6) ;

}

Тест даст негативный результат, поскольку произведение 3 на 3 не будет равно б, а вызов метода assertεquais указывает, что значение переменной intRet должно быть равно б. Если оно равно б, метод выполняется без ошибок, в противном случае инструмент JUnit регистрирует ошибку.

Метод assertEquals представляет собой один из серии методов, содержащихся в утилите JUnit и предназначенных для тестирования кода. Остальные методы на­зываются assertNotMull, assertNull, assertSame и assertTrue. В утилите также определен метод assert, однако его использования следует избегать, поскольку ме­тод с таким же именем имеется в JDK. Метод assertTrue был специально введен для замены метода assert в JUnit.

о? jbuilder 7 - g:/5rc java∕jbbook∕debug∕unittestiπg∕test∕uni..,,file edit search view project run team wizaras tools window help
0⅛5iw5⅛(5⅛⅛⅛⅛∙
m fnt∣∏rpause* ɪj ⅜⅜ ⅞⅜ "ft i £ - j⅛j
,<f *,t f⅜ ’ jw ¾ ⅛∣ <fr,ft β ⅛f ʃ) ip unlfteet
i® uniitestingjpx
e-⅜ «project source* t ⅜ unittesting «
c⅛ framei jaxa
,es ⅛ imports *
e- ⅛ testframei
■ ⅛> testcase ' 'i
 l *5> tpsterampi rstrjnn.sλ -ɪl
,к & frame1 * ⅛ testframel ∣ package unltcescing;,lɪnɪort junit.cranevork.*;,testframeijava,source ∣ design ∣ beanpjml j ooc ] histαιγj рис. 30.2. успешный прогон теста с помощью junit в ide-среде jbuilder. обратите внимание на изображения галочек в кружочках, которые присутствуют в панели сообщений

'4
в
6 о uninesung testframel
stestadd i
' iestmultiplyillllinilinuiiiii* testframai:buhd succeeded wtbi o files comp∣∣βα build iрис. 30.3. неудачный прогон теста с помощью junit в ide-среде jbuilder.
обратите внимание на изображения x в кружочках, которые присутствуют в панели сообщений. на экране эти пиктограммы должны быть красного цвета
jbuilder 7 - gt/src java∕jbbook∕debug∕uπittestin√test∕uni. .. xfile edit search view project run team wizards ɪooɪs window helpq <s β * ⅜ ш β ⅜*t ~i⅜ b
m fintlncpause" 3 *h ⅞⅜ ⅜1 lς⅛ ’
ft & df sl gp unittest
si' unlttestingjpx
s® «project source*
⅛ e unittesting s
- φ frame1 java
⅜ ⅜'1<j,
×j⅛ framel testframel ∣
 itaseɪ ɪtuier *τβtfτrraιertττ
int ttl= 3j;
int b2- 3:
int intree ■ ccanel.multiply(el, b2); assertequals( intret, 6);
9j e-q unittesting testframei
o testdd
otestmuitjpiy —=—.
 
■ > illllllllllllllllllllllllllllliniliiiitini 2∣n total,...
x. testframef xjtestftamel Γ
bu⅜d sttccaededwlth i ffle romphed. buildlopko seconds

æ- йз imports
(3 <⅛ testframei
c⅛ testcase .
 .ft te-slframelzfatinn. si ju
ж- ⅛ fc . rag⅛tf
cstframeljaxa 27:15 i insert
source jpesignj seanj uml ∣ doc ∣ htstory ∣

629

Добавление тестов для класса CodeBox

Теперь, когда вы получили представление о принципах работы инструменталь­ных средств JUnit, Давайте-ка займемся созданием более сложного теста. В частно­сти, мы напишем тест для модуля StringBox, Находящегося в JAR-файле проекта CodeBox компании Elvenware, который распространяется вместе с сопровождающи­ми книгу материалами.

Добавьте код Elvenware на странице Paths диалогового окна Project Properties, как показано на рис. 30.4. После установки на жестком диске кодов примеров книги в вашей системе должен появиться каталог с именем JbbookSrcPβrsonai. Именно этот каталог должен быть внесен в список путей к исходному коду.

После щелчка на кнопке OK в диалоговом окне Project Properties щелкните на кнопке Refresh (четвертая слева) в панели инструментов. После щелчка на ней вы увидите пакеты com. elvenware.*, как показано на рис. 30.5.

рис. 30.4. настройка пути к исходным кодам для вашего проекта, которая позволяет получить доступ к пакетам, разработанным компанией elvenware
project properties,paths i oeneralj run j buildj code style j import sfyto ∣ editorj ,∣ml∣ setverj jjava131b24,jdk
outputpath:
backiippath:
,jθ jsrcjavaljbbooktdebugajnittestinqlclasses,gjsi .avaljbbcu√d `b igjuniitestfngjbak vvorklng jirectoty 1fg jsrcjavajjbbookjdebugiunntestin ŋ

Source

path,c oisrcjaivaljbbooktdebugiunittestingisrc
f? i giisrcjavaljbbooktdebuaiunhtestingitest
10 isffjaraijbbooktorejperwem ∣
,edit.
remo a
,movetjp,ar jbuilder 7 - [g√jb7∕extras∕juπit∕src. jar]∕junft∕framewσrk∕...,reset j,file edn search view project run team wizards ɪoois window help
o tf s∙¾⅛∙⅛f⅛ ∙∕
m jprinttocpa∪se^ ⅜ ’a ∫⅞⅛ *[⅛tl > ’ Φ ’ *j fit * ** ^*tj Φ ‘
⅛0Λ1s 5p unlftest.. ’ ×j⅛ aaaert ∣ ,⅜⅜ frame1 j x ⅜teefftamef j
assetts tΛ∆t t⅛ιc∙ rrɪts at* equal. *j
,3p uniftesting |p« ι ⅛ι ж *o'0je∣∙* soun-o*,* ж eom.e∣venware.todβbto ж tomeɪvenware.comp ж mm elvenware struetume
i si-ж unitlestlnq & framel java ⅛, testframel java
j i ∙∙⅛∣ unltteshng.html ж unlitestingjava
,»/
static public void msertiqualsjstr
,assertlqualsinessage, new integer,рис. 30.5. после щелчка на кнопке refresh в панели проекта у вас появляется возможности просмотреть новые пакеты, добавленные в путь к исходным кодам

t ɪest case wizard - step 1 of 4select methods to tmthighlight the methods you wantto be tested, if no methods are highlighted, e skeletontsstrasewtli be generated.*2 test case wizard - step 2 of 4рис. 30.7. использование поля package для определения, где должны сохраняться тестовые случаиciase1jcorp etvenvɜre √odebox,stringboxclaesname: teststrinpbox
base claes: ijunit framework testcase
5- ♦£ comlelvenwarexodebox-strfngbox
* petfirstword(btrtng) ^fociudecr(btring)
* includetreillngoelimi'' г ⅜ inttostrpado(inttint)
* иммж
,* ^aymouse(mouseevent)
* snorten(str∣ng, irffj
6- •# java.lang.object
sp c^1⅛ test с__я class «fc.ti.tnpackage: unittesting

«back
i next> ∣ i £lnish~~] i 9ancel i i heip i

630

Откройте класс StringBox Из пакета Com.Elvenware. Codeboχ. Убедитесь, что он выделен в панели содержимого в IDE-среде. В меню JBuilder выберите пункт File | New и перейдите на страницу Test. Запустите первый элемент — Test Case.

На первой странице мастера Test Case Wizard выберите все методы из файла StringBox. Java, Кроме метода SayMousβ, Как показано на рис. 30.6. Щелкните на кнопке Next.

На второй странице мастера убедитесь, что класс TeststringBox Находится в па­кете Unittesting, Как показано на рис. 30.7, а не в пакете EɪVenware. Codebox. Это видно из верхнего поля в диалоговом окне, которое называется Package (Пакет). Все, что находится в пакете Codebox, В конце концов, будет помещено в файл CodeBox. Jar. Тем не менее, тестовые программы в JAR файл переноситься не будут. Как результат, их желательно не включать в пакет Codeboχ, Вследствие чего они по ошибке могут оказаться в JAR-файле. Для включения тестовых программ в пакет Unittesting Воспользуйтесь полем Package. После щелчка на кнопке Finish будет сгенерирован код, приведенный в листинге 30.3

Рис. 30.6. Выбор методов для тестирования из класса StringBox

Fill Ntħβ fields belowto set the package, name, and base class for Ihe new Java test Case class to be created.

Листинг 30.3. Код, сгенерированный JBuiIder для тестирования класса StringBox

Package com. elvenware. codebox;

Import junit. framework.*;

Public class TestStringBox extends TestCase

{

Public TestStringBox(String s)

{

Super(s) ;

}

Protected void setup()

<

}

Protected void tearDown()

{

}

Public void testGetFirstWord() {

String valuel= "STRINGO”;

String StringRet = StringBox. getFirstWord(valuel);

/♦* βtodo: Insert test code here. Use assertEquals(), for example. */

)

Public void testIncludeCR() {

String valuel= "STRINGO”;

String StringRet = StringBox-IncludeCR(Valuel);

∕** @todo: Insert test code here. Use assertEqualβ(), for example. */

)

Public void testIncludeTrailingDelimiter() {

String fIleNamel= "STRINGO";

String StringRet = StringBox. IncludeTrailingDelimiter(fIleNamel);

∕** @todo: Insert test code here. Use aβsertEquals(), for example. */

}

Public void testlntToStrPadO() { int valuel= O; int paddings2= O;

String StringRet ≈ StringBox. IntToStrPadO(valuel, paddings2);

/*♦ @todo: Insert test code here. Use assertEgualsO, for example. */

}

Public void testReverse() {

S tring s trIngToReversel= " STRINGO n;

String StringRet ≈ StringBox. reverse (StringToReversel);

∕** @todo: Insert test code here. Use assertEguals(), for example. */

)

Public void testShorten() {

String sl= "STRINGO”; int charsToCut2= O;

String StringRet = StringBox. shorten(si, charsToCut2);

∕** gtodo: Insert test code here. Use assertEguals(), for example. */

)

Public void testStripFirstWord() {

String valuel= "STRINGO";

String StringRet = StringBox. StripFirstWord(Valuel);

∕** 6todo: Insert test code here. Use assertEguals(), for exaπψle. */

Как видите, для каждого метода класса StringBox создан один метод тестирования. Все, что осталось сделать, так это установить несколько переменных и реализовать ме­тод assertEguals или assertτrue, который покажет, что созданные тесты работают.

Используемый тестовый случай приведен в листинге 30.4.

Листинг 30.4. Тестовый случай для класса StringBox

Package unittesting;

Inport junit. framework.*;

Import com. eɪvenware. codebox.*;

Public class TestStringBox extends TestCase

{

Public TestStringBox(String s)

{

Super(s);

}

Protected void set∏p()

{

)

Protected void tearDown()

{

}

Public void testGetFirstWord()

{

Int value = 1;

String theWord = "OneWord";

String result = StringBox. getFirstWord(theWord); Systern. out. printin("GetFirstWord: " + result);

AssertTrue(result. equals(theWord));

}

Public void testGetFirstWord2()

{

Int value ≈ 1;

String theWord = "";

String result = StringBox. getFirstWord(theWord); System. out. println("GetFirstWord: " + result);

AssertTrue(result. equals(theWord));

}

Public void testGetFirstWord3()

(

Int value ≈ 1;

String theWord = "Two words";

String result = StringBox. getFirstWord(theWord); System. out. printIn("GetFirstWord: " + result);

AssertTrue(result. equals("Two"));

}

Public void testGetFirstWord4()

{

Int value = 1;

String theWord = " A then this is another test"; String result = StringBox. getFirstWord(theWord); System. out. println("GetFirstWord: " + result);

AssertTrue(result. equals("A"));

}

Public void testIncludeCR()

{

String valuel= "STRINGO";

String StringRet ≈ StringBox. IncludeCR(valuel); assertTrue(StringRet. endsWith("N"));

)

Public void testIncludβTrailingDelimiter()

F

String fIlcNamel= nSTRINGO";

String StringRet = StringBox. includeTrailingDelimiter(filβNamel); assertTrue((stringRet. endsWith("∖∖")) (StringRet. endsWith("∕n)));

}

Public void testlnToStrPadO()

{

Int value = 1; int paddings2≈ 3;

String result ≈ StringBox-IntToStrPadO(value, paddings2);

System. out. println("IntToStrPadO: " + result);

AssertTrue(result. equals("001"));

)

Public void testlntToStrPadO()

{

Int valuel= O; int paddings2= O;

String StringRet = StringBox. intToStrPadO(valuel, paddings2); assertTrue(StringRet. equals("O"));

)

Public void testReverse()

{

String StringToReversel= "STRINGO";

String StringRet = StringBox. reverse (StringToReversel); assertEquals(StringRet, "OGNIRTS");

)

Public void testShorten()

{

String sl= "STRINGO"; int charsToCut2= 4;

String StringRet = StringBox. shorten(si, charsToCut2); assertEquals(stringRet, "STR");

)

Public void testStripFirstWord()

{

String valuel= "STRINGO";

String stringRet = StringBox-StripFirstWord(Valuel); assertEquals (stringRet, ",,);

}

Public void testStripFirstWord2()

{

String valuel= "";

String stringRet = StringBox. StripFirstWord(Valuel); assertEquals(stringRet, "");

)

Public void teststriρFirstWord3()

{

String valuel= "This time";

String stringRet = StringBox-StripFirstWord(Valuel); assertEquals(stringRet, "time");

)

Public void testStripFirstWord4()

{

String valuel= "This time is true";

String stringRet = StringBox-StripFirstWord(Valuel); assertFquals(stringRet, "time is true");

примечаниеСамой интересной особенностью приведенного кода является количество повто­рений отдельных фрагментов. Например, для методов StripFirstword И GetFirstword В коде содержится по четыре тестовых случая. Тесты включают про­верку правильности выполнения методов при работе со строкой с несколькими сло­вами, со строкой из одного слова и с полностью пустой строкой. Чем больше изоб­ретательности вы проявите при выборе тестовых случаев, тем больше вероятность того, что в коде не будет ошибок. При обнаружении ошибки в каком-нибудь из ме­тодов потребуется добавить новые тесты. Разработчики, придерживающиеся прин­ципов экстремального программирования, скажут, что тест нужно добавлять даже перед попыткой устранения ошибки. На первом шаге потребуется создать тест для проверки состояния ошибки, а на втором — устранить саму ошибку.

Usw∙⅛⅛*β Многие сторонники экстремального программирования даже могут по­рекомендовать начать разработку проекта с написания теста. Как только тест будет го­тов, можно приступать к написанию программы, которая будет успешно проходить тест. Более подробно принципы экстремального программирования описаны на Web-сайте по адресу http: //www. extremeprogramming. org. Еще одним интересным ресурсом по экстремальному программированию по праву считается сайт Http://ootips. org/ Xp. html.

Тесты позволяют точно определить назначение каждого метода. Например, зара­нее трудно решить, должен ЛИ Метод StripFirstWord Возвращать одно слово или же пустую строку при передаче ему в качестве аргумента строки, состоящей всего из одного слова. При выборе тестовых случаев для этого метода нужно было четко оп­ределиться с функциями метода и прийти к окончательному решению. (Было реше­но, что метод в описанном случае должен возвращать пустую строку.)

Второй важной особенностью такого рода тестов является уверенность в процес­се устранения ошибок или расширении функциональных возможностей кода. При необходимости расширения функциональных возможностей метода GetFirstWord Изменения можно вносить с достаточной степенью уверенности, поскольку имею­щиеся тесты перехватят наиболее очевидные ошибки, которые могут быть внесены в процессе расширения кода.

Одна из основных идей экстремального программирования состоит в том, что написание тестов — это своего рода развлечение: вы пишете небольшой фрагмент кода и практически мгновенно получаете результат. Более того, вам не нужно беспо­коиться, что написанный код будет снижать скорость работы программы. Вы мак­симально используете свой творческий потенциал и создаете как можно большее число тестов. Подобный подход к программированию должен войти в привычку. К тому же написание тестов может оказаться полезным занятием в случае, когда у вас нет сил для решения более сложных задач.

Тестирование методов, возвращающих строки

Когда вы чувствуете, что ваш творческий потенциал на данный момент иссяк, попытайтесь составить для себя некоторые правила, которые помогут вам писать те­сты. Например, при тестировании функций, работающих со строками, всегда нужно разрабатывать, по крайней мере, два теста:

■ тест для проверки метода при передаче ему нормальной строки;

■ тест для проверки метода при передаче ему пустой строки.

Ниже приведены два примера таких тестов для методов класса StringBox:

Public void testReverse()

{

String valuel= "abc";

String StringRet = StringBox. reverse(valuel); assertEquals(stringRet, ,,cbaπ) ;

)

Public void testReverseEmpty()

{

String valuel= ,, ” ;

String stringRet = StringBox. reverse (valuel) ; assertEquals(stringRet, ,,n) ;

}

Вспомогательные объекты

Пока что мы рассмотрели две первых страницы мастера Test Case Wizard. После­дняя страница этого мастера предназначена для создания объектов, которые назы­ваются Вспомогательными объектами (fixtures). Вспомогательные объекты использу­ются для настройки и разбивки тестовых случаев. Вспомогательный объект может быть классом или набором переменных, которые применяются в настроенных и разбитых методах для обеспечения запуска тестов. Такие объекты могут быть пред­назначены для простой инициализации переменных.

Обратите внимание, что настроенные и разбитые методы будут вызываться меж­ду каждым отдельным тестом в тестовом случае. Таким образом, вы можете гаранти­ровать, что все тесты выполняются на соответствующим образом инициализирован­ном объекте. Например, при выполнении тестов на удаленном сервере код вспомо­гательного объекта может использоваться для подключения к серверу. После этого тесты можно прогонять для всех методов данного сервера.

Более подробную информацию по вспомогательным объектам можно найти на Web-сайте по адресу Www. junit. org.

Тестовые наборы

После создания тестов для методов классов Framel и StringBox У нас получи­лось два тестовых случая, первый из которых называется TestFramel, А второй — TeststringBox. Тестовый набор позволяет писать код, который одновременно бу­дет запускать оба тестовых случая. Полученный результат можно увидеть на рис. 30.8, в показанной на нем панели сообщений.

В редакции JBuilder Enterprise создание тестовых наборов представляет собой достаточно простой процесс. Тестовый набор легко создается вручную. В среде JBuilder в меню выберите пункт File ∣ New. Перейдите на страницу Test диалогового окна Object Gallery и выберите мастер создания тестовых наборов Test Suite Wizard. На первой странице мастера для помещения в тестовый набор классов TestFramel И TestStringBox Воспользуйтесь кнопкой Add, как показано на рис. 30.9. Перейди­те на следующую страницу и убедитесь, что в поле Package установлено unittesting. C
подобным вы уже сталкивались при создании класса TestStringBox, поэтому про­сто следуйте процедуре, описанной выше в этой главе.

Для закрытия мастера Test Suite Wizard щелкните на кнопке Finish. Генерируемый код будет выглядеть так, как показано в листинге 30.5.

Листинг 30.5. Простой тестовый набор JUnit

Package uni ttes ting;

Import ]unit. framework.*;

Public class AllTests extends TestCase

{

Public AllTests(String s)

{

Super(s) ;

J

Public static Test suite() {

TestSuite suite = new TestSuite();

Suite addTβ8tSuite(unittesting. TestFramel. class); suite. addTestSuite(unittesting. TestStringBox. class); return suite;

}

}

JBuilder 7 — G:/Sre Java∕jbbook∕DebugΛJnitTesting∕test∕unl..

File Edit Search View Project Run Team Wizards Tools Window Help

О β ’ ft⅛ ∙ ⅛> ∙θ * « F~ T ~~

^3 ⅜* %» % ' ⅛s ’ й 1⅛ Γ ∙⅜s ζ⅝⅝kr⅛ strtngbox i xisrteetrametрис. 30.8. прогон тестов для framel и stringbox вовлекает в действие иерархию, которая включает в себя два набора тестов

cl iunlt franneworktestsuitegjsefaia b © unittesling testframei
stestadd te stmultipiy
f⅛ © unittesting teststringbox
, qtestgetfirslword
,) teslgetflrstword3 i teetgetfιrstword4 i iestinciudecr i ieslinciudetraiiingdeiimiter ► teetlntostrpado ) testlnttostrpado i teεtreverse i iestshorten ' ieststhpfirstword i teststripfirstword2 * teststripfirstword3 iieststripfirslworda,' test suite wizard - step 1 of 3,rawmπwππιmι,x .uftt-k x .⅛teβtι
x airtests _x aiites
 в j∏cħedtool - visual suck ton
,рис. 30.9. для добавления в создаваемый вами тестовый набор тестовых случаев пользуйтесь кнопкой add,teststririgboxjava
itestframetjava
,мей»,select the test cases te include
tlils wlzardwill generate a test 8uile that calls the classes listed below.. when a package is listed, this wizard makes a test suite invoking the test cases contained m the package.
,addrecursive..,remove,finish,cancel,∣, ^heip i

M JprnHnfpause" — JMlJt Jtft.⅜t Tl IinDTwtannк»

примечаниеНесложно заметить, что в методе suite класса создается объект TestSuite. Вы­зовы метода addτestsuite объекта suite регистрируют в JUnit предварительно со­зданные тестовые случаи. Как результат, все тесты, содержащиеся в классах TestFramel и TeststringBox, в приведенном тестовом наборе автоматически вызы­ваются, как показано на рис. 30.8.

В книге уже не раз описывались достоинства написания простых клас­сов, удобных в использовании. Проект JUnit является примером удачной структуриза­Ции достаточно сложного набора классов.

Прогон JUnit-тестов в режиме командной строки

примечаниеВ этой главе вы научитесь прогонять тестовые наборы в режиме командной стро­ки. Именно в этом разделе главы разработчики, пользующиеся редакцией JBuilder Personal, узнают, каким образом можно запускать JUnit-тесты. Как уже говорилось, возможность автоматизации прогона тестов в командной строке делает этот метод одним из наиболее предпочтительных. Таким образом, вы практически ничего не теряется из-за отсутствия средств тестирования, встроенных в JBuilder.

Как упоминалось ранее, код, приведенный в листинге 30.5, представляет собой стандартный JUnit-код, используемый всеми пользователями этого проекта. Сре­да JBuiIder позволяет генерировать его автоматически, тем не менее, он все равно оста­ется всего лишь стандартным кодом, предназначенным для использования вместе с JUnit. Таким образом, можно создать стандартный JBuilder-πpoeκτ, как было указано в начале этой главы, и затем поместить в файл методы add и multiply, коды которых приведе­ны выше. После этого потребуется ввести коды, показанные в листингах 30.2, 30.4 и 30.5, или же просто воспользоваться сопровождающими книгу материалами. Сохраните JUnit-код в том же каталоге, в котором находится файл Framel. java. Он будет исполь­Зоваться в соответствии с указаниями, содержащимися в оставшихся разделах главы.

примечаниеКод проекта JUnit хранится в файле junit. jar. Этот JAR-файл поставляется вместе с JBuilder и расположен в каталоге ∕JBuilder∕lib. Последнюю версию JAR — файла можно найти на Web-сайте по адресу Www. junit. org. На этом сайте находит­ся открытый код, поэтому вы можете его совершенно бесплатно выгрузить.

Исходный код проекта JUnit распространяется в соответствие с оп­ределенной лицензией, но, тем не менее, в ней нет особо жестких ограничении. Код. предназначен для ежедневного использования. Код проекта JUnit распространяется по лицензии Common Public License Version 0.5 компании IBM. Заинтересованные люди мо­гут найти эту лицензию по адресу Http://oss. software. ibm. com/developerworks/ oss∕licensecpl. html. Вот краткая выдержка из этой лицензии: "В соответствии с ус­ловиями данного Соглашения, каждый Участник настоящим предоставляет Получателю неэксклюзивную, глобальную, свободную от уплаты авторских отчислений лицензию на воспроизведение, подготовку производных работ, открытое представление, распростра­нение своих работ, а также сублицензию на вклады такого Участника и такие производ­ные работы Участника, как исходный код и код объектов". Трудно понять, что все это Значит, но выглядит достаточно многообещающе.

JAR-файл проекта JUnit Распространяется в версии с графическим интерфейсом пользователя и в версии для командной строки. Графический интерфейс пользова­теля хорош для прогона тестов в интерактивном режиме, а версию для командной строки лучше использовать при необходимости интеграции тестов в процесс ком­поновки. Результат работы версии JUnit С графическим интерфейсом показан на рис. 30.10.

При запуске тестов с использованием JUnit с графическим интерфейсом необхо­димо убедиться, что файлы Codebox.Jar и junit. jar находятся в каталоге, кото­рый находится в пути классов. Как вы помните, файл Codeboχ.jar Входит в состав сопровождающих книгу материалов. Кроме того, его можно найти на Web-сайтах Www. elvenware. com. Перейдите В корневой каталог проекта UnitTesting, Который был создан в этой главе. После этого выполните следующую команду:

Java -ср .;%CLASSPATH%/classes junit. swingui. TestRunner unittesting. AllTests

Следующий код, хотя он и менее эффективен, все-таки более наглядно показы­вает, что происходит при выполнении предыдущего вызова:

Java — cρ .;g:/utils/classes/codebox. jar, g:/jb/lib/junit. jar, classes junit. swingui. TestRunner unittesting. AllTests

Переменная %classpath% во время выполнения выдает путь к файлам классов. На самом деле переменная %classpath% может содержать более сложное значение, чем приведенное во втором примере, тем не менее, оно сокращено, чтобы были видны основные части вызова.

рис. 30.10. успешный прогон 16 тестов для класса stringbox, который разрабатывался ранее в этой книге, а также для класса framel, разработанного ранее в этой главе

Прогон JUnit-τecτoB в текстовом режиме

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

Java — ср. ,∙%CLASSPATH%,-classes junit. textui. TestRunner unittesting. AllTests

Приведенная выше команда практически идентична команде запуска версии JUnit с графическим интерфейсом. Тем не менее, в последнем случае вызывается класс junit. textui. TestRunner, а не junit. swingui. TestRunner. Те ИЗ вас, КТО Хочет пользоваться устаревшим Java-кодом, должны запускать класс junit. awtui. TestRunner.

Ниже приведены результаты запуска текстовой версии JUnit:

[g:∖srcjava∖jbbook∖debug∖unittesting]гUnTextTests. bat

Java — ср.;д:∕utils∕classes∕jaxp. jar;д:∕utils∕classes∕codebox. jar;д:/ jb∕lib∕dx.

Jar;д:∕jb∕lib∕dbswing. jar;д:∕jb∕lib∕jbcl. jar;д:∕jb∕lib∕junit. jar;д:/ utils∕cla

Sses∕mm. mysql-2.0.11-bin. jar;д:/Compilers/interbase∕InterClient∕ interclient. jar;

Classes junit. textui. TestRunner unittesting. AllTests

…GetFirstWord: OneWord

.GetFirstWord:

.GetFirstWord: Two

.GetFirstWord: A

…Data

Call: Ol

Call: OOl

IntToStrPadO: OOl

.Data

Time: 0.5

OK (16 tests)

B первой строке вы видите вызов пакетного файла, в котором хранятся команды, приведенные в начале этого раздела. Следующий фрагмент кода просто выводит на экран выполняемую команду. В частности, вы видите полный путь к файлам клас­сов, за которым следует вызов класса junit. textui. TestRunner. И, наконец, в ре­зультатах содержится имя класса, в котором находятся запускаемые тесты: unittesting. AllTests.

Ссылки на GetFirstword, IntToStrPadO и так далее являются результатом вы­полнения содержащихся в коде вызовов метода System. out. printin. Предпослед­няя строка содержит время выполнения тестов, а последняя — их количество (16).

JUnit и Ant

Между проектом с открытым исходным кодом JUnit и проектом Ant образова­лось довольно-таки тесное сотрудничество. Проект Apache Jakarta Ant представ­ляет собой Java-редакцию утилиты make. Утилита Ant гораздо удобнее в использова­нии, нежели make, и, по крайней мере, для Java-проектов, она обладает гораздо бо-

Лее широкими возможностями. В частности, функциональные возможности Ant До­пускают расширение.

Утилита Ant позволяет автоматизировать процесс компоновки приложений. Связь между Ant и JUnit основана на том, что утилиту Ant можно использовать для автоматического запуска тестовых сценариев, создаваемых в JUnit. Так, например, в процесс компоновки приложения можно включить запуск тестовых наборов JUnit.

Разработчики компании Borland отмечают, что утилиты Ant и JUnit Внесли су­щественный вклад в процесс разработки. Как результат, обе утилиты встроены в ин­тегрированную среду JBuilder.

Утилиты Ant и JUnit В JBuilder считаются средствами разработки уровня пред­приятия. Тем не менее, они доступны во всех редакциях среды JBuilder. В частно­сти, существуют проекты с открытым кодом, предназначенные для интеграции ути­литы Ant Даже в редакцию JBuilder Personal. Одним из таких проектов является AntRunner. Его МОЖНО Найти ПО Адресу Http://antrunner. sourceforge. net/.

После интеграции утилиты Ant В среду JBuilder с помошью Ant-сценариев в про­цесс разработки можно вовлечь и утилиту JUnit. Либо при желании посетите сайт Codecentral. borland. com И выгрузите из него это средство тестирования блоков. Оно доступно на странице ПО адресу Http://codecentral. borland. com/ codecentral∕ccweb. e×e∕listing7id=17168.

Более подробное описание утилит Ant И JUnit можно найти в книге "Java Tools for Extreme Programming" Хайтауэра (Hightower) и Лесики (Lesiecki), изданной John Wiley & Sons. K сожалению, основное внимание а ней уделено разработке программ в J2EE, тем не менее, она очень хорошо написана и содержит немало полезной ин­формации.

Резюме

В этой главе была кратко рассмотрена концепция тестирования блоков с помо­щью инструментальных средств JUnit Было показано, что эта утилита встроена в интегрированную среду разработки JBuilder. Тем не менее, ее можно легко исполь­зовать и в режиме командной строки.

Если вы пользуетесь редакциями JBuilder SE или Personal, посетите сайт Www. junit. org. На этом сайте можно найти множество советов по использованию JUnit. Там же содержатся средства, которые дают возможность автоматически гене­рировать тестовые случаи с помощью инструментов, аналогичных инструментам, входящим в состав редакции JBuiIder Enterprise. Кроме того, на сайте можно найти уникальные инструменты, позволяющие тестировать фрагменты приложений, кото­рые относятся к графическим интерфейсам пользователя.

Марджи Калверт

Глава 31

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *