Модульное тестирование с помощью FlexUnit
WD479 | Апрель 30, 2008
Модульное тестирование с помощью FlexUnit
(Unit Testing with FlexUnit)
Введение
FlexUnit - фрейворк с открытым исходным кодом созданный Adobe для реализации модульного тестирования во Flex’e. Основан на широко используемом фрейворке для тестирования Java-приложений JUnit. FlexUnit предоставляет возможность низкоуровнего тестирования системы - первого уровня обнаружения ошибок в приложении.
Понятие модульного тестирования
Принцип модульного тестирования долгое время являлся частью традиционной модели разработки приложений - Водопада (Waterfall model). Однако, в последнее время, данный принцип приобрел популярность как один из главных принципов экстремального программирования (Extreme Programming). Используя этот стиль программирования сначала создаются тесты для модулей, а потом уже пишется сам код. Так же часто проводится реорганизация кода из-за добавления новых возможностей. Тестирование модулей помогает найти ошибки в реорганизованном коде и может быть использованно как часть регрессионного тестирования чтоб проверить не повлияли ли сделанные изменения на уже существующую функциональность.
Модульное тестирование может быть автоматизированно и включенно отдельным этапом в сборку (build) приложения. Для облегчения автоматической сборки компания Adobe создала специальные задания (tasks) для Ant’a. Используя Ant выможете автоматически компилировать и тестировать ваши Flex приложения.
Модульное тестирование не заменяет собой весь процесс тестирования. Есть много классов ошибок которые не покрываются его возможностями - ошибки интерграции, системные ошибки, и вопросы производительности.
Что такое Модульное тестирование?
Чтобы это понять, сначала надо определиться что такое “модуль”. Модуль - это наименьшая часть кода, которая поддается тестированию. В данном случае не имеется ввиду каждая строчка кода, а часть кода, выполняющая определенное действие - это может быть любая нетривиальная функция или метод. В отличии от многих других форм тестирования, тесты модулей обычно составляются самим разработчиком. Разработчик тестирует код чтоб убедиться, что каждый метод исполняется как надо. В теории, если каждая низкоуровневая функция работает должным образом, то и более высокие уровни интеграционного тестирования должны содержать меньше ошибок.
Предмет тестирования
Перед тем как описывать настройку FlexUnit нам нужен объект тестирования. Как пример, ниже приведен простой класс банковского аккаунта, позволяющий пополнение, снятие со счета, а так же получение информации о балансе счета.
BankAccount.as
{<br />
public class BankAccount<br />
{<br />
var private balance:Number=0;</p>
<p> public function deposit(amount:Number){<br />
balance=balance+amount;<br />
}</p>
<p> public function withdraw(amount:Number){<br />
balance=balance-amount;<br />
}</p>
<p> public function getBalance():Number{<br />
return balance;<br />
}<br />
}<br />
}<br />
Основы FlexUnit’а
Для запуска FlexUnit необходимо:
- 1. Скачать FlexUnit и включить библиотеку;
- 2. Создать тесты для модулей;
- 3. Создать набор тестов;
- 4. Передать набор тестов на выполнение.
Подключение библиотеки FlexUnit.
FlexUnit можно скачать на странице Google Code http://code.google.com/p/as3flexunitlib/. После извлечения файлов из zip-архива в директории bin вы найдете файл библиотеки flexunit.swc, который надо добавить в ваш flex-проект.
Если вы создаете новый проект, вы можете указывать библиотеки в процессе создания. На втором шаге создания проекта есть закладка Library path - нажмите на нее, а затем на кнопку Add SWC. Это откроет диалог открытия файла и вы можете выбрать SWC файл.
Если у вас есть существующий проект, вы можете подключить библиотеку в свойствах проекта. Правой кнопкой кликните на проект, в выпадающем меню выберите Properties. В левой части выберите Flex Build Path, а затем Library path вкладку. Нажмите на кнопку Add SWC чтоб добавить flexunit.swc.
Этот процесс намного проще для пользователей Flex 3. Скачав flexunit.swc, просто поместите его в папку libs вышего проекта.
Создание тестов
Далее переходим к созданию тестов. Они будут находиться в новом классе, который расширяет базовый класс TestCase. Назовем его BankAccountTest. Этот класс будет содержать методы с нашими тестами. Для каждого тестируемого модуля необходимо создать отдельный метод. В нашем примере мы будем тестировать методы deposit и withdraw класса BankAccount, поэтому имена наших тестов будут testDeposit и testWithdraw. Обязательное условие - имена тестовых методов должны начинаться со слова test. Позже, когда мы добавим созданные тесты в наш набор тестов, автоматически будут выбираться имена, начинающиеся со слова test. Если названия ваших методов будут начинаться не с test, то эти методы не будут выполненны.
Любой тест состоит из логических утверждений. Если утверждение верно, тест проходит проверку, если же утверждение ошибочно, то, соответственно, нет.
Существует несколько доступных методов утверждений: assertTrue, assertFalse, assertNull, assertEquals и несколько других. Методы очень схожи - получают необязательное тескстовое сообщение и логический тест. Несмотря на то, что тестовые сообщения не являются обязательными, их можно использовать для более быстрого определения теста, вызвавшего ошибку. Если результат логичесткой проверки принимает значение true, утверждение считается верным, и наоборот. Например: если я создаю банковский счет и кладу на него 50 рублей, тогда мой баланс должен быть равен 50 рублям. Для такого случая тест будет выглядеть так:
bankAccount.deposit(50);<br />
assertTrue("Balance on a new account after 50 deposit is 50", bankAccount.getBalance() == 50);<br />
Этот тест очень простой и легко проходится. Если на моем балансе нет 50р. после того как я положил 50р., значит у меня проблемы с методом deposit, либо getBalance. Для этого примера у нас всего несколько утверждений, но вам следует сделать все возможные проверки чтобы покрыть как можно больше случаев. Так выглядит наш конечный класс с добавленными несколькими тестами:
BankAccountTest.as
import flexunit.framework.TestCase;</p>
<p> public class BankAccountTest extends TestCase {</p>
<p> public function testDeposit():void {<br />
var bankAccount:BankAccount=new BankAccount();<br />
bankAccount.deposit(50);<br />
assertTrue("Balance on a new account after 50 deposit is 50", bankAccount.getBalance() == 50);<br />
bankAccount.deposit(25);<br />
assertEquals("Balance after 50 deposit and another 25 deposit is 75", 75,bankAccount.getBalance());<br />
}</p>
<p> public function testWithdraw():void {<br />
var bankAccount:BankAccount=new BankAccount();<br />
bankAccount.deposit(100);<br />
bankAccount.withdraw(50);<br />
assertTrue("Balance on a new account after 100 deposit and a 50 withdraw is 50", bankAccount.getBalance() == 50);<br />
}<br />
}<br />
}<br />
Создание набора тестов и его запуск.
Теперь, когда у нас есть тесты нам надо создать набор тестов. Мы сделаем это во flex-файле вместо actionScript класса. Для этого сначала создаем простое Flex приложение, содержащее только один компонент - TestRunnerBase, который является частью библиотеки FlexUnit. Убедитесь что вы добавили пространство имен flexunit.flexui.* в ваше приложение чтобы иметь доступ к визуальным объектам библиотеки.
Далее надо добавить функции создания нашего набора тестов и его запуска. Создаем метод createSuite, который будет создавать новый объект TestSuite и добавлять все наши классы тестов, используя метод addTestSuite. Используя отражение (reflection) метод addTestSuite находит все методы в классе, имена которых начинаются с “test” и добавляет их в список тестов. У нас только один класс TestCase (BankAccountTest.as созданный нами ранее), но если вы создали больше - их тоже надо добавить в эту функцию.
В завершение создаем метод onCreationComplete. Он будет вызываться при событии сreationComplete нашего приложения. Эта функция изменяет значение свойства test объекта TestRunnerBase на наш набор тестов (его возвращает метод createSuite).
Теперь можно приступать к тестированию вызвав метод startTest компонента TestRunnerBase. Код будет выглядеть так:
TestRunner.mxml
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"<br />
xmlns:flexunit="flexunit.flexui.*"<br />
creationComplete="onCreationComplete()"></p>
<p> <mx:Script><br />
<![CDATA[<br />
import flexunit.framework.TestSuite;</p>
<p> // Создаем набор тестов и запускаем их<br />
private function onCreationComplete():void<br />
{<br />
testRunner.test = createSuite();<br />
testRunner.startTest();<br />
}</p>
<p> // Создаем набор тестов<br />
private function createSuite():TestSuite {<br />
var testSuite:TestSuite = new TestSuite();<br />
testSuite.addTestSuite( BankAccountTest );<br />
return testSuite;<br />
}<br />
]]><br />
</mx:Script></p>
<p> <!-- FlexUnit GUI Component --><br />
<flexunit:TestRunnerBase id="testRunner" width="100%" height="100%" /><br />
</mx:Application><br />
Теперь мы готовы запустить наши тесты. На этом изображении показан пример интерфейса TestRunner после запуска:

Так как все наши тесты очень простые и быстро выполняются, полоса выполнения сразу же заполнится. Если выполнение теста будет занимать время, то полоса выполнения будет заполняться по мере запуска тестов.
Так же отображаются количетво пройденных тестов и общее их количетво. Если какой либо из тестов не проходит проверку, полоса выполнения станет красной и вы увидите сообщение об ошибке этого теста. По умолчанию отображается список тестов, вызвавших ошибку, но вы также можете нажать на закладку All Tests чтобы увидеть весь список тестов.

Для этой проверки я изменил первый тест для проверки неверного баланса:
assertTrue("Balance on a new account after 50 deposit is 50", bankAccount.getBalance() == 40);<br />
Это заведомо не верное утверждение вызовет ошибку. В правой части можете увидеть сообщение об ошибке:
Error: Balance on a new account after 50 deposit is 50 - expected true but was false
Поскольку в сообщение об ошибке не включаются номера строк, следует такие описания, которые обнозначно будут указывать на ошибку.
Как только какое-либо утверждение в методе не проходит проверку, выполнение остальных проверок данного метода прерывается. Но остальные методы (даже этого же класса) будут выполненны.
Заключение
FlexUnit предоставляет возможность автоматической проверки кода на низком уровне. Он помогает значительно сократить процесс тестирования и выявить ошибки на более ранней стадии. Пример в этой статье показывает основы модельного тестирования во Флексе, а так же открывает путь к такой технике программирования как разработка через тестирование и автоматическое тестирование в процессе билда (например используя ANT).
Допольнительные ресурсы:
FlexUnit on Google Code
http://code.google.com/p/as3flexunitlib/
Extreme Programming
http://www.extremeprogramming.org/
Flex Ant Tasks
http://labs.adobe.com/wiki/index.php/Flex_Ant_Tasks
Источник: Unit Testing with FlexUnit





Отлично!!!
gvaamvgypv ‾
Я тоже иногда такое замечал, как-то не придавал этому значения.
Согласен, что пост получился удачным. Хорошая работа!
Полностью согласна!
На современном этапе, одной из наиболее эффективных методик продвижения сайтов в сети, является написание оригинальных статей. Реклама статьями предоставляет авторам сайтов разными вариантами размещать статью в соответствующей рубрике. Этот каталог подразумевает продолжительное нахождение Вашей статьи на автономной странице, с оригинальными тегами и постоянными способами по ее модифицированию. Все это реально на Аналитические статьи
Отличная статья, спасибо!
Зачет! и ниипет!