Flexunit: просто о параметризации тестирования

19 Авг
2011

Все началось с того что я решил подтянуть мат часть, и начать писать хороший код.
А как известно хороший код всегда ассоциируется с TDD и хорошим unit тестированием. Хочу рассказать о своем увлекательном опыте работы с flexunit4.
Всем кто хочет писать на flex лучше — под кат.

Описание задачи


Задача которую я поставил себе — реализация алгоритмов сортировок. Bubble, Selection, QSort.
Начал как это принято с создания интерфейса
 public interface ISorter<br>
 {<br>
 /**<br>
 * Main function of the ISorter interface. Takes unordered array and returns ordered array.<br>
 * Must be implemeted<br>
 */<br>
 function sort(executedArray:Array):Array;<br>
 }<br>

Все классы которые реализуют сортировку должны реализовывать этот интерфейс. Например реализация пузырьковой сортировки:
 public class BubbleSorter implements ISorter<br>
 {<br>
 /* INTERFACE com.bgh.sorting.ISorter */<br>
 /**<br>
 * Implements bubble sorting.<br>
 * Starts at the begining of the sorting list and compares all items one by one<br>
 * compares 2 firts elements and if 1 is greater then 2 it swaps them.<br>
 * a[i] ---> temp<br>
 * a[i] ---> a[j]<br>
 * a[j] <--- temp<br>
 */<br>
 public function sort(executedArray:Array):Array<br>
 {<br>
 var counter:int = 0;<br>
 for (var i:int = 0; i <= executedArray.length; i++ )<br>
 {<br>
 for (var j:int = 0; j <= executedArray.length; j++ )<br>
 {<br>
 if (executedArray[i] < executedArray[j])<br>
 {<br>
 var temp:int = executedArray[i];<br>
 executedArray[i] = executedArray[j];<br>
 executedArray[j] = temp;<br>
 }<br>
 counter += 1; <br>
 }<br>
 }<br>
 return executedArray;<br>
 }<br>
 }<br>

Реализацию QSort и SelectionSort можно глянуть в моем репозитории: bitbucket.org/helland/algotest/

Теперь непосредственно о тестировании


По началу я решил задачу просто в лоб. Написал много много тестов такого вида
 public class SortingTestCases<br>
 { <br>
[Test( description = "Basic positive check of bubble sorting" )]<br>
 public function bubbleSorterPositive():void<br>
 {<br>
 var bubbleSorter:ISorter = new BubbleSorter();<br>
 assertEquals( [1,2,3].toString() , bubbleSorter.sort( [2,1,3] ).toString() );<br>
 }<br><br>
 [Test (description = "Checks selection sorting. Positive test")]<br>
 public function selectionTestPositiveSort():void<br>
 {<br>
 var selectionSorter:ISorter = new SelectionSorter();<br>
 assertEquals( [1,2,3].toString() , selectionSorter.sort( [2,1,3] ).toString() );<br>
 }<br>
 [Test (description = "Checks QSort. Positive test case")]<br>
 public function QSortPositive():void<br>
 {<br>
 var qsort:ISorter = new QSort();<br>
 assertEquals( [1,2,3].toString() , qsort.sort( [2,1,3] ).toString() );<br>
 } <br>
 }<br>

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

Решение


Все окозалось достаточно просто. Благо есть Parameterized который дает возможность параметризировать запуск тест кейса, и передавать ему обьект типа ISort при запуске. Вот как это выглядит на практике.
[RunWith("org.flexunit.runners.Parameterized")]<br>
 public class SortingTestCases<br>
 { <br>
 private var foo:Parameterized;<br><br>
[Parameters]<br>
 public static function Sorters():Array<br>
 {<br>
 return [ [new BubbleSorter()], [new SelectionSorter()], [new QSort()] ] ;<br>
 }<br><br>
 [Test (description = "Checks how positive integers are sorted with provided sorters")]<br>
 public function positiveIntegersArray():void<br>
 {<br>
 assertEquals([1, 2, 3, 12, 100, 110, 200].toString() , _sorter.sort( [1, 2, 3, 100, 200, 110, 12] ).toString() );<br>
 }<br>

Вот как бы и все. Один тест решает все сходные задачи.
По материалам Хабрахабр.



загрузка...

Комментарии:

Наверх