Главная » C# » Тестирование связанного списка приложения управления освещением в Visual C# (Sharp)

0

Базовый класс BaseLinkedList применяется для предоставления вспомогательных сервисов. Поэтому данный класс можно объявлять в ядре или в сборке  опредений.  Так как это базовый  класс, то его необходимо подвергнуть всестороннему

тестированию, чтобы удостовериться  в том, что он не содержит никаких ошибок. В этом разделе мы рассмотрим один тест, который демонстрирует, что и как нужно тестировать в базовом классе.

Так как класс BaseLinkedList объявлен абстрактным, для него требуется реализия. Целью реализации является предоставить нам достаточно информации о стоянии и контексте объекта. В таком случае нам нужно определить объект, котый сможет протестировать каждую составляющую класса BaseLinkedList. Тестовый класс можно сравнить с манекеном для тестирования автомобилей на прочность при авариях, с прикрепленными к нему кучей датчиков и идущих от них проводников. Далее приводится простая реализация класса в проекте TestLightingSystem. Не забудьте вставить ссылку на LibLightingSystem (щелкне правой кнопкой по пункту References в проекте TestLightingSystem и выберите последовательность команд Add Reference | Projects | LibLightingSystem).

using LibLightingSystem; namespace TestLightingSystem

{

class Linkedltem : BaseLinkedList { private string _identifier;

public Linkedltem(string identifier) {

_identifier = identifier;

}

public string Identifier { get {

return _identifier;

}

}

public override string ToStringO { string buffer;

buffer = "this(" + ..identifier + ")"; if (Next != null) {

buffer += " next(" + ((Linkedltem)Next).Identifier + ")";

}

else {

buffer += " next(null)";

}

if (Prev != null) {

buffer += " prev(" + ((Linkedltem)Prev).Identifier + ")";

}

else {

buffer += " prev(null)";

}

return buffer;

}

}

}

В классе Linkedltem объявлен ТОЛЬКО ОДИН член данных, ..identifier, который используется для идентификации экземпляра. Тестовый код вызывает  методы insert () и Remove (), после чего генерирует наглядное представление связанного списка. В случае если что-то не так, наглядное представление применяется для пска источника проблемы. Мы  не будем  писать тесты для  наглядного представлия, т. к. это слишком усложнит тестирование.

Для создания наглядного представления объекта используется перегрузка метода Tostring (). По умолчанию все объекты имеют реализацию Tostr ing (), вся работа которой заключается в предоставлении идентификатора ссылки объекта. Чтобы заставить  метод  Tostring о   делать  что-либо  полезное,  его  нужно  перегрузить. В примере метод Tostring о создает буфер, содержащий идентификатор объекта BaseLinkedList и идентификаторы следующего и предыдущего объектов. Эти три идентификатора предоставляют информацию о структуре связанного списка.

Следующим шагом является написание теста в файле Program.cs проекта TestLightingSystem, КОТОрЫЙ проверяет, работает ЛИ метод Inserto, как требуея. Данный тест выглядит таким образом:

namespace TestLightingSystem

{

class Program

{

static void Main(string[] args)

{

Testlnsert();

}

public static void Testlnsert() { Console.WriteLine("**************"); Console.WriteLine("Testlnsert: Start"); Linkedltem iteml = new Linkedltem("iteml"); Linkedltem item2 = new Linkedltem("item2"); Linkedltem item3 = new Linkedltem("item3"); string tostring = iteml.Tostring(); Console.WriteLine(tostring);

if (iteml.Next !=null || iteml.Prev !=null) { throw new Exception(

"Testlnsert: Empty structure is incorrect");

}

iteml.Insert(item2); toString = iteml.ToStringO; Console.WriteLine(toString);

if (!(iteml.Next == item2 && iteml.Prev == null)) { throw new Exception(

"Testlnsert: Iteml->Item2 structure is incorrect");

}

toString = item2.ToString(); Console.WriteLine(toString);

if (!(item2.Next == null && item2.Prev == iteml)) { throw new Exception(

"Testlnsert: Item2->Iteml structure is incorrect");

}

item2.Insert(items); toString = item2.ToString(); Console.WriteLine(toString);

if (!(item2.Prev == iteml && item2.Next == items)) { throw new Exception(

"Testlnsert: Item2->Iteml, Item3 structure is incorrect");

}

toString = items. ToStringO; Console.WriteLine(toString);

if (!(items.Prev == item2 && items.Next == null)) { throw new Exception(

"Testlnsert: Item3->Item2, structure is incorrect");

}

toString = iteml.ToString(); Console.WriteLine(toString);  toString = item2.ToString(); Console.WriteLine(toString);  toString = item3.ToString(); Console.WriteLine(toString); Console.WriteLine("Testlnsert: End");

}

}

}

Результаты теста выглядят таким образом:

**************

Testlnsert: Start

this(iteml) next(null) prev(null) this(iteml) next(item2) prev(null) this(item2) next(null) prev(iteml) this(item2) next(item3) prev(iteml) this(item3) next(null) prev(item2) this(iteml) next(item2) prev(null) this(item2) next(item3) prev(iteml) this(item3) next(null) prev(item2) Testlnsert: End

Хотя выведенный результат и выглядит аккуратно и красиво, его назначением не является подтверждение, что все операции были выполнены должным образом. Просто пространный вывод упрощает отладку в случае ошибки.

В методе Testlnsert () возникает ситуация, когда создаются три экземпляра класса Linkeditem: itemi, item2 и  item3. Первоначальн о  эт и  тр и  элемент а  не  связаны ,  но с помощью метода insert ()  мы связываем их в структуру (рис. 8.4).

Рис. 8.4. Тестируемая структура двунаправленного связанного списка

Но чтобы получить структуру, показанную на рис. 8.4, требуется выполнить несколько промежуточных шагов, которые тестируются в реализации метода Testlnsert (). На каждом шаге выполняется проверка на правильность значений свойств Next и prev каждого элемента. Если некоторые значения не совпадают, то выдается исключение, указывающее неправильную структуру. В  случае исключия приобретает важность генерирование наглядной структуры. Кстати, при разротке алгоритмов для методов insert () и Remove () наглядные структуры помогли мне вычислить источник ошибки.

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

ИНСТРУМЕНТЫ   ДЛЯ     ТЕСТИРОВАНИЯ    И     ОТЛАДКИ

Некоторые могут думать, что для того чтобы вычислить причину неудачного теста, нбходимо применить отладчик. Но если тесты разработаны должным образом, преняются как часть всеохватывающей инфраструктуры тестирования и выдают пообную информацию о результатах тестирования, то надобность в  отладчике уменьшается. Программисты,  исповедующие  разработку  TDD  (Test-Driven  Develop- ment, разработка, управляемая тестами), включая меня, ставят под вопрос пользу, приносимую отладчиком. Согласно статье "Test-Driven Development" в Википедии (http://en.wikipedia.org/wiki/Test-driven_development):     "Программисты,     практикуие чистую разработку TDD, говорят, что они редко испытывают необходимость прегать к отладчику. Совместно с использованием системы управления версиями, при неуспешном  тестировании,  возвращение  к  последней  версии,  успешно  прошедшей все тесты,  почти  всегда более эффективно,  чем отладка".

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

Говоря о создании тестов, как было сказано в главе  6,  их  написание  можно  значельно облегчить, применяя инфраструктуры для тестирования, такие как NUnit (http://www.nunit.org) или Microsoft Visual Studio Team System (http://msdn2.microsoft.com/ en-us/vstudio/default.aspx). При разработке коммерческого кода, вы, скорее  всего, будете использовать одну из таких инфраструктур. Хотя сами по себе эти инфртруктуры не предоставляют прямой помощи в написании тестов, они предоставляют утилиты для генерирования и протоколирования ошибок и отображения  прогресса тестов. Не верьте рекламным заявлениям, утверждающим, что их  инструменты  могут сами создавать тесты. Никакой инструмент не  может создавать тесты,  т. к.  для  этого ему нужно было  бы  понимать  контекст тестируемого  кода.  А так  как таких  инструмеов в данное время не существует, то вам придется создавать собственные тесты.

Источник: Гросс  К. С# 2008:  Пер. с англ. — СПб.:  БХВ-Петербург, 2009. — 576 е.:  ил. — (Самоучитель)

По теме:

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