Flexunit: Просто о параметризации тестирования
Все началось с того что я решил подтянуть мат часть, и начать писать хороший код.
А как известно хороший код всегда ассоциируется с TDD и хорошим unit тестированием. Хочу рассказать о своем увлекательном опыте работы с flexunit4.
Всем кто хочет писать на flex лучше — под кат.
Задача которую я поставил себе — реализация алгоритмов сортировок. Bubble, Selection, QSort.
Начал как это принято с создания интерфейса
Все классы которые реализуют сортировку должны реализовывать этот интерфейс. Например реализация пузырьковой сортировки:
Реализацию QSort и SelectionSort можно глянуть в моем репозитории: bitbucket.org/helland/algotest/
По началу я решил задачу просто в лоб. Написал много много тестов такого вида
Как видите эти 3 теста делают одно и то же, но для разных реализаций сортировщика. В момент написания таких тестов, я постоянно думал, ну не может такого быть что бы нужно было столько всего копипастить. Все классы имеют один и тот же интерфейс. Ну неужели, вот так?
Все окозалось достаточно просто. Благо есть Parameterized который дает возможность параметризировать запуск тест кейса, и передавать ему обьект типа ISort при запуске. Вот как это выглядит на практике.
Вот как бы и все. Один тест решает все сходные задачи.
А как известно хороший код всегда ассоциируется с TDD и хорошим unit тестированием. Хочу рассказать о своем увлекательном опыте работы с flexunit4.
Всем кто хочет писать на flex лучше — под кат.
Описание задачи
Задача которую я поставил себе — реализация алгоритмов сортировок. Bubble, Selection, QSort.
Начал как это принято с создания интерфейса
public interface ISorter
{
/**
* Main function of the ISorter interface. Takes unordered array and returns ordered array.
* Must be implemeted
*/
function sort(executedArray:Array):Array;
}
Все классы которые реализуют сортировку должны реализовывать этот интерфейс. Например реализация пузырьковой сортировки:
public class BubbleSorter implements ISorter
{
/* INTERFACE com.bgh.sorting.ISorter */
/**
* Implements bubble sorting.
* Starts at the begining of the sorting list and compares all items one by one
* compares 2 firts elements and if 1 is greater then 2 it swaps them.
* a[i] ---> temp
* a[i] ---> a[j]
* a[j] <--- temp
*/
public function sort(executedArray:Array):Array
{
var counter:int = 0;
for (var i:int = 0; i <= executedArray.length; i++ )
{
for (var j:int = 0; j <= executedArray.length; j++ )
{
if (executedArray[i] < executedArray[j])
{
var temp:int = executedArray[i];
executedArray[i] = executedArray[j];
executedArray[j] = temp;
}
counter += 1;
}
}
return executedArray;
}
}
Реализацию QSort и SelectionSort можно глянуть в моем репозитории: bitbucket.org/helland/algotest/
Теперь непосредственно о тестировании
По началу я решил задачу просто в лоб. Написал много много тестов такого вида
public class SortingTestCases
{
[Test( description = "Basic positive check of bubble sorting" )]
public function bubbleSorterPositive():void
{
var bubbleSorter:ISorter = new BubbleSorter();
assertEquals( [1,2,3].toString() , bubbleSorter.sort( [2,1,3] ).toString() );
}
[Test (description = "Checks selection sorting. Positive test")]
public function selectionTestPositiveSort():void
{
var selectionSorter:ISorter = new SelectionSorter();
assertEquals( [1,2,3].toString() , selectionSorter.sort( [2,1,3] ).toString() );
}
[Test (description = "Checks QSort. Positive test case")]
public function QSortPositive():void
{
var qsort:ISorter = new QSort();
assertEquals( [1,2,3].toString() , qsort.sort( [2,1,3] ).toString() );
}
}
Как видите эти 3 теста делают одно и то же, но для разных реализаций сортировщика. В момент написания таких тестов, я постоянно думал, ну не может такого быть что бы нужно было столько всего копипастить. Все классы имеют один и тот же интерфейс. Ну неужели, вот так?
Решение
Все окозалось достаточно просто. Благо есть Parameterized который дает возможность параметризировать запуск тест кейса, и передавать ему обьект типа ISort при запуске. Вот как это выглядит на практике.
[RunWith("org.flexunit.runners.Parameterized")]
public class SortingTestCases
{
private var foo:Parameterized;
[Parameters]
public static function Sorters():Array
{
return [ [new BubbleSorter()], [new SelectionSorter()], [new QSort()] ] ;
}
[Test (description = "Checks how positive integers are sorted with provided sorters")]
public function positiveIntegersArray():void
{
assertEquals([1, 2, 3, 12, 100, 110, 200].toString() , _sorter.sort( [1, 2, 3, 100, 200, 110, 12] ).toString() );
}
Вот как бы и все. Один тест решает все сходные задачи.
0 комментариев