C# для чайников
.pdf
Большинство библиотечных классов, которые вы указываете в директивах us - i n g (или в полностью квалифицированных именах в своем исходном тексте наподобие S y s t e m . Windows . Forms . Form), являются частью библиотеки базовых классов (Base Class Library — BCL) платформы .NET Framework. Дан ные классы — это файлы . DLL, которые уже сохранены в глобальном кэше сборок (Global Assembly Cache — GAC), центральном хранилище в каталоге Windows. Компилятор может найти эти классы на основе ссылки, просто по имени файла . DLL наподобие S y s t e m . Windows . Forms . d l l .
Но иногда необходимо использовать классы, определенные в библиотеках классов сторонних производителей или в библиотеках классов, созданных вами самостоятельно. Например, чтобы применить инструмент тестирования NUnit с вашим проверяемым ко дом, понадобится директива u s i n g N U n i t . F r a m e w o r k ; во всех файлах, содержащих тестируемые классы; кроме того, нужна ссылка (/г) на каталог, в котором находится файл n u n i t . f r a m e w o r k . d l l .
Файлы библиотеки инструмента NUnit не хранятся в GAC. Чтобы помочь компилято ру их найти, ссылка должна определить полный путь к файлу . DLL. Именно поэтому в предшествующем примере во втором ключе /г содержится полный путь.
Следует упомянуть еще вот о чем: в файле настройки, как и в командной строке (в поле Parameters для инструмента), необходимо определить ключи, параметры и име на файлов для компиляции в такой последовательности:
ключи |
// |
например: |
/ d e b u g и / o u t |
параметры |
// |
например: |
O r e f s . r s p |
файлы |
// например: |
* . c s |
|
Ознакомьтесь с кратким описанием примера.
/ d e b u g — это ключ. (Его лучше разместить здесь, чем в поле Parameters, если только вы не используете этот файл настройки для обеих компиляций — Debug
и Release).
©debug . r s p — это параметр (но этот параметр должен быть в командной строке).
* . cs — список файлов для компиляции. (Вы можете иногда встретить дополни тельные ключи после имен файлов.)
Большинство из этих элементов могут встречаться как в командной строке, так и в файле параметров.
Размещайте файл параметров в каталоге, на который указывает параметр $ F i l e D i r в редакторе TextPad. Для команд компиляции это каталог, содер жащий исходные файлы . CS.
Во время компиляции компилятор раскрывает командную строку с использованием информации из файла настроек © r e f s . r s p (в командной строке они разделялись бы пробелами).
Компилятор С# всегда использует дополнительный заданный по умолчанию файл настройки, называемый c s c . r s p , для ссылок на все общие сборки, такие как S y s t e m . d l l . Таким образом компилятор знает о них без вашего вмеша тельства. Найдите этот файл в том же месте, где находится компилятор С#, c s c . ехе , и просмотрите его.
544 |
Часть VII. Дополнительные главы |
Работа над ошибками компиляции
Оба инструмента — и Build С# Debug, и Build С# Release — запускают компиля тор. В любом случае, даже при компиляции окончательной версии, вы можете получить от компилятора сообщения об ошибках. При правильной настройке инструментов любые сообщения компилятора об ошибках появляются в окне Command Results редактора TextPad. Типичное сообщение об ошибке выглядит так:
mycode.cs(11,17): error CS0246: The type or namespace name 'joeyTypes' could not be found (are you missing a using directive or an assembly reference?)
Первая часть — это имя файла, в котором произошла ошибка. Числа в круглых скоб ках — номера строки и столбца в этой строке. Остальная часть просто подробнее описы вает ошибку.
Волшебное регулярное выражение, которое вы добавили при настройке инст рументов, предназначено для выделения трех частей информации из этого со общения: имени файла, номера строки и номера столбца. Редактор TextPad пе рехватывает сообщение об ошибке от компилятора, применяет регулярное вы ражение для извлечения этих элементов и помещает их в те "регистры", которые вы настроили как 1, 2 и 3. Вот в чем был весь фокус-покус!
Синтаксис регулярного выражения примерно так же прост, как и общая теория отно сительности. (В действительности он не так уж и плох, если только вы поймете его суть.)
В окне Command Results можно дважды щелкнуть на сообщении об ошибке и перейти к указанным строке и столбцу. Очень полезная возможность!
Конечно же, вы должны разобраться в том, что же именно произошло неправильно, но, естественно, это останется упражнением для самостоятельного изучения.
Настройка остальных инструментов
Теперь добавьте, переименуйте и настройте инструменты для выполнения компили руемой программы, запуска инструмента тестирования NUnit, отладки программы и про смотра документации пакета .NET SDK. В следующих разделах перечислены настройки конфигурации каждого из упомянутых инструментов. Щелкайте на кнопке Apply после внесения изменений в каждую установку.
Два инструмента для запуска вашей программы
После успешной компиляции своей программы вы, как правило, захотите ее запус тить. Поскольку отладочная и финальная компиляции помещают результат в различные каталоги, вам потребуются два инструмента. Чтобы настроить инструменты для запуска вашей программы, используйте настройки из следующего списка.
Program to Run (программа для запуска). При создании инструмента укажите следующую программу для его запуска: Csc. е х е . Чуть позже вы измените на звание программы на другое, не доступное во время создания инструмента. Эта установка одинакова для обоих инструментов запуска, описанных здесь.
Глава 22. С# по дешевке
Menu Name (название меню). Введите Run Debug для одного инструмента и Run Release для другого.
Command (команда). При настройке инструмента замените все, что находится в этом поле, строкой $FileDir\bin\debug\Program. ехе для первого инст румента и $FileDir\bin\release\Program.ехе для второго. (Если вы из менили свои командные строки компиляции в поле Parameters, чтобы использо вать название, отличное от "Program", воспользуйтесь этим названием и здесь). Затем завершите настройку остальных элементов в этом списке.
Parameters (параметры). Оставьте это поле без изменений для обоих инструментов.
Options (опции). Установите флажок Save All Documents First (остальные опции не установлены).
Remaining options (остальные опции). Пропустите.
При использовании своего инструмента Run Debug или Run Release убеди тесь в том, что файл, содержащий функцию M a i n ( ) , находится в редакторе TextPad на переднем плане.
Инструмент для модульного тестирования вашей программы
В процессе программирования можно |
существенно увеличить свою |
уверенность |
в программе путем написания и частого |
выполнения небольших тестов |
для классов |
и методов. Инструмент NUnit, упрощающий такое тестирование, описан далее в этой главе. Для настройки инструмента, запускающего тестирование NUnit, используйте следующие установки.
Program to Run (программа для запуска). При создании инструмента введите название или перейдите к программе C:\Program Files\NUnit 2 . 2\bin\nunit-gui . ехе (хотя, возможно, у вас имеется более свежая версия программы NUnit).
Menu Name (название меню). Введите Run NUnit.
Command (команда). Это поле устанавливается после создания инструмента.
Other options (другие опции). При настройке инструмента оставьте их все без изменений.
Инструмент для отладки вашей программы
После того как вы скомпилировали свою программу с помощью команды Build С# Debug, которую настроили ранее, вам зачастую необходимо запустить программу в отладчи ке для поиска ошибок. Чтобы настроить инструмент для запуска отладчика, добавьте инстру мент Debug .NET Program в редактор TextPad, используя следующие установки.
Program to Run (программа для запуска). При создании инструмента перейдите к папке, в которой установлен пакет .NET Framework SDK, обычно она находится в каталоге C:\Program Files. Затем найдите подкаталог \GuiDebug и от кройте файл DbgCLR. ехе. Обратитесь к разделу "Получение бесплатных компо нентов" выше в этой главе.
Menu Name (название меню). Введите Debug .NET Program.
546 |
Часть VII. Дополнительные главы |
Command (команда). Это поле устанавливается после создания инструмента.
Parameters and Initial folder (параметры и начальный каталог). При настройке инструмента очистите эти поля. Затем завершите настройку остальных элементов этого списка.
Options (опции). Установите флажок Save All Documents First (никаких регу лярных выражений или регистров).
Эта команда работает для любого языка платформы .NET, а не только для С#. Под робнее применение данного отладчика было описано ранее в этой главе. Один и тот же отладчик используется как в TextPad, так и в SharpDevelop.
Инструмент для просмотра документации пакета .NET SDK
Поскольку редактор TextPad ничего не знает о языке С# или библиотеке .NET Frame work (в отличие от SharpDevelop), вы будете вынуждены воспользоваться инструментом для просмотра документации из .NET Framework SDK. Для настройки инструмента, ко-, торый открывает документацию в вашем Web-браузере, добавьте инструмент Browse
.NET Docs, используя следующие настройки.
Program to Run (программа для запуска). При создании инструмента перейдите к папке, в которой установлен ваш Web-браузер. Например, для использования программы Internet Explorer перейдите к программе C:\Program Files\lnternet E x p l o r e r \ I E x p l o r e . е х е .
Menu Name (название меню). Введите Browse .NET Docs.
Command (команда). Это поле устанавливается после создания инструмента. Parameters (параметры). В Windows Explorer найдите папку с пакетом .NET SDK; вероятно, она находится в каталоге C:\Program Files. При настройке инструмента введите путь к этой папке, за которым следует \StartHere . htm.
Other options (другие опции). Пропустите.
Существует еще один отличный инструмент. Программа WinCV позволяет про сматривать пространства имен и классы в библиотеках платформы .NET. Испол няемый файл WinCV. е х е расположен в папке \bin в каталоге пакета .NET SDK. Все, что вам нужно — это указать путь в поле Command в окне Preferences.
Дизассемблер промежуточного языка (Intermediate Language Disassembler) позволит вам получить удобочитаемую версию того, во что скомпилирована ваша программа С#. Постепенно из полной абракадабры она будет превращаться во все более и более понят ный для вас код. Программа I l d a s m . e x e расположена в подкаталоге \bin каталога
.NET SDK. Все, что вам нужно — это указать путь в поле Command. При создании ин струмента можно выбрать опцию Close DOS Window on Exit.
Для получения специальной справки по инструментам SDK дважды щелкните на файле \Docs\CpTools. chm в окне Windows Explorer в каталоге .NET SDK.
Итак, вы завершили настройку редактора TextPad для работы с языком С#. На рис. 22.6 показан окончательный вид меню Tools. Теперь редактор TextPad стал очень полезным инструментом для программирования на С#, а вы узнали, что делают про-
Глава 22. С# по дешевке |
547 |
граммы Visual Studio и SharpDevelop под своим блестящим покрывалом. Далее вы узнае те, как тестировать свои программы.
Рис. 22.6. Простое меню Tools в редакторе TextPad— вашей новой среде программирования на С#
Выше объяснялось, как настроить инструмент для запуска NUnit. Эта программа дос тупна на Web-сайте по адресу w w w . n u n i t . o r g и на прилагаемом компакт-диске. Это — программное обеспечение с открытым исходным кодом, поэтому вы можете сво бодно использовать его, придерживаясь лицензии.
Данный раздел применим как к работе в Visual Studio, так и к работе в TextPad или SharpDevelop.
Запуск программы NUnit
Чтобы можно было запускать программу NUnit из какой-нибудь рассматриваемой в этой главе среды разработки, вы должны сначала настроить ее в меню Tools. Озна комьтесь с командами для запуска программы NUnit.
Для запуска программы NUnit из пакета Visual Studio выберите команду меню
Tools'^Ваше название.
Для запуска программы NUnit из редактора TextPad выберите команду меню
Tools^Run NUnit.
Для запуска программы NUnit из SharpDevelop выберите команду меню Tools^NUnit.
548 |
Часть VII. Дополнительные главы |
Программу NUnit также можно запустить из меню Start в Windows, из Windows Explorer или из командной строки.
Конечно, сначала необходимо кое-что подготовить. Программа NUnit проста в ис пользовании, но вы должны ознакомиться с ее соглашениями и методами.
На рис. 22.7 показана программа NUnit с частично успешным тестовым запуском, ко торый только что завершился.
Рис. 22.7. Тестирование в NUnit и простое, и мощное
Тестирование
Эта книга о программировании на языке С#, поэтому вы можете удивиться, почему в ней говорится о тестировании, и к тому же — зачем вы должны этим заниматься.
Если вы ожидаете пользы от программы, то требуется некоторая гарантия, что она действительно делает то, для чего предназначена. Без соответствующей проверки у вас не будет уверенности даже для самостоятельного использования программы, не говоря уж о ее распространении среди других пользователей. Попрограммируйте некоторое время, и вы поймете, что имеется в виду.
Но, может, кто-то другой несет ответственность за тестирование? Да, в больших про граммных проектах обычно имеется отдельная группа тестировщиков, которая проверяет программное обеспечение. Но если вы работаете в одиночку, то вы и есть эта группа в полном составе. Но даже если вы работаете в команде, вы все равно несете ответствен ность за тестирование программы, которую пишете.
Тестирование, осуществляемое в NUnit, относится к типу модульного тестиро вания. "Модули", которые вы проверяете, обычно являются отдельными клас сами и их методами. Чтобы убедиться в том, что класс BankAccount не будет обманывать вашего работодателя (банк) или его клиентов, вы должны выпол нить множество вводов информации для его методов и удостовериться в кор ректности получаемых результатов.
Глава 22. С# по дешевке |
549 |
Модульное тестирование выполняет две задачи. Первая заключается в провер ке правильности поведения программы. Вторая состоит в поиске ошибок. Если они в программе есть (а это неизбежно), вы должны обнаружить их и искоре нить. Пишите свои тесты так, чтобы вы могли найти ошибки.
Типичный класс тестирования в NUnit содержит значительное количество — обыч но небольших — методов тестирования. Каждый метод тестирования проверяет один из методов вашего класса. Может потребоваться несколько или даже множество мето дов тестирования, чтобы охватить все основные компоненты для метода, который вы проверяете: правильный ввод, плюс различные виды неверного ввода, включая ввод вне допустимого диапазона, пустой ввод, опасный ввод, глупый ввод, никогда не случаю щийся ввод и т.д. Люди, которые фактически используют вашу программу, будут оче редными Эйнштейнами в поиске способов "наступить на грабли" в ней и будут давать знать о себе обычно в самое неподходящее время.
Что касается времени, когда следует проводить тестирование, то лучшим будет время написания программы. Если исходить из опыта, то при создании метода следует всегда потратить несколько минут на написание одного или нескольких тестов для него. После того как вы приобретете некоторый опыт, обычно на все это уже не потребуется много времени, и затем вы сможете легко запускать тесты — некоторые из них или все — сно ва и снова, так что количество правильных выполнений вашей программы будет возрас тать, а вы будете знать, что новый код не нарушит старый. Старайтесь не уклоняться от этого принципа — позже это окупается сэкономленным на отладке программ временем.
Написание тестов NUnit
Для работы в программе NUnit добавьте один или несколько классов тестирова ния — они могут быть в любом проекте решения программы, хотя зачастую в целях дос тупности их легче поместить в тот же проект, в котором находится тестируемая про грамма. (Если поместить эти классы в отдельный проект, то методы, которые тестируют ся, должны быть объявлены как public, чего обычно делать не следует. Общим правилом должно являться сохранение методов скрытыми, когда это только возможно).
Класс тестирования NUnit может иметь следующий вид:
using |
System; |
|
using |
NUnit.Framework; |
// Эта директива необходима |
namespace NUnitTestExample
{
// Элементы в скобках [] называются "атрибутами"
[TestFixture] |
// |
Атрибут: это термин NUnit для класса |
|
// |
тестирования |
public class MyTestClass
{
//Здесь размещаются все данные, необходимые для
//большинства или всех тестов, в виде переменных-
//членов, а также конструктор(ы) (если они
//необходимы)
public MyTestClass() { }
//Метод настройки — вызывается перед каждым методом
//тестирования; используется для установки одинаковых
550 |
Часть VII. Дополнительные главы |
//начальных условий для тестов, так что ни один тест не
//влияет на результаты последующих тестов
[SetUp] |
// Атрибут SetUp (обратите внимание на |
|
// правильное написание) |
public void |
MySetupO |
{ |
|
//Здесь выполняется настройка, необходимая для всех
//методов тестирования
}
//Здесь вы пишете методы тестирования
//Методы тестирования имеют "атрибут" [Test] и всегда
//объявлены как public void, без аргументов
[Test] |
|
|
|
public |
void |
StringLengthsGoodTest() |
|
{ |
|
|
|
} |
|
|
|
[Test] |
|
|
|
public |
void |
CountSpacesTest() |
|
{ |
|
|
|
} |
|
|
|
// |
Вспомогательный метод для тестов, но не сам тест (нет |
||
// |
атрибута |
[Test]) |
|
private |
int |
CountSpaces(string s) |
|
{
}
// другие тесты...
Вы можете найти законченный пример реального класса тестирования NUnit NUnitTestExample на прилагаемом компакт-диске. На рис. 22.8 показан пример класса тестирования NUnit в редакторе TextPad. Этот же класс тес тирования прекрасно работает в Visual Studio и SharpDevelop (в последнем вы можете запускать тесты прямо в среде SharpDevelop с поддержкой про граммы NUnit).
Изучение класса тестирования программы NUnit
Вот что необходимо знать о классах тестирования.
Директива u s i n g и ссылка. Вам необходима директива using для NUnit. Framework, а также ссылка (ключ /г) на файл nunit. framework. dll в подката логе \bin в папке программы NUnit на вашей машине; вероятно, это С:\Program Files\NUnit.
Приспособление для теста и тесты. Программа содержит класс тестирования, или "приспособление для теста" (test fixture), который состоит из методов тести рования и, возможно, дополнительных методов поддержки. Скоро вы познакоми тесь с методами тестирования, а на компакт-диске в демонстрационной программе NUnitTestExample представлено несколько их разновидностей.
Демонстрационная программа представляет собой простую программу, основан ную на методе TrimAndPad () в демонстрационной программе AlignOutput
ie главы |
Глава 22. С# по дешевке |
551 |
из главы 9, "Работа со строками в С#". Полный текст программы N U n i t T e s t E x - a m p l e здесь приводиться не будет.
Рис. 22.8. Класс тестирования, загруженный в редактор TextPad, выглядит так же, как и в Visual Studio
Атрибуты. Атрибуты — это возможность языка С#, которая больше нигде не рассматривается в данной книге. Они своего рода "украшение", которое можно одеть на классы, методы и другие объекты языка С# для различных целей. Класс тестирования украшен атрибутом [TestFixture], а методы тестирования — атрибутом [Test].
NUnit определяет разные атрибуты, используемые этой программой, чтобы про браться в ваш скомпилированный файл .ЕХЕ или .DLL посредством методики, называемой отражением (эта тема также выходит за рамки данной книги). С по мощью "включения отражения" сборки .NET программа NUnit может определить все классы (по атрибуту [TestFixture] !) и все методы (по атрибуту [Test]) тестирования. Затем она может просто вызывать только те методы, которые вы полняют ваши тесты (без реального запуска всей программы).
Вы увидите несколько других атрибутов в этой главе и в примере NUnitTestEx ample на компакт-диске.
Установка и очистка. Кроме методов тестирования, можно при желании опреде лить по одному методу с атрибутами [Setup], [TearDown], [FixtureSetUp]
и [FixtureTearDown].
Методы тестирования должны быть разработаны так, чтобы ни один тест не влиял на любой другой тест. Каждый метод тестирования получает новую песочницу для игр.
Программа NUnit вызывает метод, который вы украсили атрибутом [ S e t u p ] , вся кий раз перед запуском каждого метода тестирования. Это дает возможность обес печить любые необходимые действия настройки. Например, вы можете использо вать этот метод для открытия соединения с базой данных, создания необходимого
552 |
Часть VII. Дополнительные главы |
объекта, инициализации массива с некоторыми тестовыми вводами и так далее. Аналогичным методу [ S e t u p ] является метод [TearDown]. Ваш метод [TearDown], который вы должны выбрать, вызывается прямо после запуска каж дого метода тестирования. Используйте его для очистки после тестирования, уста новки ссылок объектов в null, отключения от базы данных или сети и так далее.
Программа NUnit вызывает аналогичные методы [FixtureSetUp] и [FixtureTearDown], если вы их предоставляете, один раз для каждого полного выполнения испытаний. Метод [FixtureSetUp] запускается перед запуском любого теста, а ме тод [FixtureTearDown] после завершения работы всех тестов. Иногда можно локализовать действия установки и очистки так, чтобы они не повторялись для каждого метода тестирования, устраняя дублирование.
Написание тестовой программы NUnit
Методы тестирования программы NUnit имеют достаточно стандартную структуру, хотя можно, конечно, проявить творческий подход и использовать их для проверки чегонибудь значительно большего. (Например, существует программа, которая проверяет, был ли установлен определенный пиксель на экране!) Вот метод тестирования из про граммы NUnitTestExample, находящейся на компакт-диске.
//StringLengthsGoodTest — проверяет корректный ввод (в
//противоположность ошибочному вводу)
//Методы тестирования начинаются с "атрибута" [Test] [Test]
public void StringLengthsGoodTest() // |
всегда public void, |
// |
без аргументов |
{
Console.WriteLine("StringLengthsGoodTest:");
//Здесь выполняется настройка ввода и тому подобного
//(если вы еще не сделали этого в методе S e t u p )
stringsln = new string[] {"Joe |
", "Rumpelstiltskin", |
"Vanderbilt" };
//Вызов тестируемого метода
//Генерируются измененные строки stringsOut = Program.TrimAndPad(stringsln);
//Сравнение фактических результатов вызова с ожидаемыми
// В этом тесте мы ожидаем, что все строки будут длиной 16
//символов. NUnit.Framework предоставляет класс Assert с
//несколькими методами, включая IsTrue, IsFalse и
//AreEqual — все они проверяют выполнение логических
//условий. Первый параметр метода IsTrue является
//проверяемым логическим условием, вторым параметром
//является сообщение, которое выводится NUnit, если
//логическое условие ложно Assert.IsTrue(stringsOut[0].Length == 16,
"строкаО имеет неверную длину"); Assert.IsTrue(stringsOut[1].Length == 16,
"строка1 имеет неверную длину"); Assert.IsTrue(stringsOut[2].Length == 16,
"строка2 имеет неверную длину");
}
Глава 22. |
С# по дешевке |
553 |
