netlib.narod.ru< Назад | Оглавление | Далее >

Тестирование модулей в XNA

Перед тем, как перейти к детальному изучению вспомогательных классов для последующих проектов этой книги, поговорим немного о тестировании модулей. В предыдущей главе вы уже изучили статические тесты модулей. Статические тестовые модули замечательно подходят для быстрой проверки визуальных результатов, тестирования физики и управления и быстрого построения вашей игры. Но вспомогательные классы и компоненты, не требующие пользовательского ввода, могут заставить задуматься о взаимодействии с ними. Это не имеет смысла, поскольку тестирование модулей призвано улучшить эксплутационную надежность вашего приложения и гарантировать, что все заработает с минимально возможным количеством ошибок. Например, проверить, работает ли класс Log, вы можете с помощью следующих строк кода:

FileHelper.DeleteFile(Log.LogFilename);
Log.Write("New log entry");

 

СОВЕТ
Этот код может быть выполнен только изнутри класса Log, поскольку член Log.LogFilename закрытый.

Теперь вы можете зайти в каталог приложения и проверить, существует ли там файл журнала и есть ли в нем строка с текстом «New log entry». Но самостоятельно проверять файл снова и снова быстро надоест. Вместо регистрации каждой ошибки вы должны помещать в журнал только предупреждения (например, что пользователь не подключен к Интернету), а при возникновении серьезных ошибок (например, отсутствии текстуры или недоступности шейдера) генерировать исключения. Это особенно верно, если задачи становятся больше, тесты усложняются и приводят к очень длительному процессу проверки. Вы можете избежать самостоятельного отслеживания ошибок, позволив этим тестам самим проверять себя и разрешив их автоматическое выполнение, вместо того, чтобы самому вызывать их из класса Program, как в случае статических тестов.

NUnit и TestDriven.Net

Для автоматизации тестирования вы можете воспользоваться популярным модулем NUnit Framework, который можно скачать с http://www.nunit.org/.

В качестве альтернативного варианта, если вы работаете с Visual Studio 2005 Professional, можно воспользоваться TestDriven .NET с http://www.testdriven.net/. Он поддерживает множество замечательных возможностей и вы можете запускать тесты напрямую с помощью горячих клавиш или выпадающего меню, что на самом деле здорово и просто. TestDriven .NET не работает в Visual C# Express или XNA Studio Express (несколько лет назад работал, но разработчики исключили из подключаемого модуля поддержку версий Express, поскольку Microsoft ожидает, что для серьезного программирования разработчики будут использовать Professional Edition). Посмотрите в главе 1, как заставить XNA работать в Visual Studio 2005; используйте проект-заглушку из XNA Studio Express для обработки вашего содержимого, которое нельзя выполнить в Visual Studio 2005.

Независимо от того, какой вариант вы установили, просто добавьте NUnit.Framework.dll из установочной папки к вашему проекту (щелкните правой кнопкой мыши по ссылкам вашего проекта и добавьте новую ссылку; воспользуйтесь кнопкой Browse, если не можете найти библиотеку в глобальном кэше сборок (Global Assembly Cache, GAC), представленном на первой вкладке). Теперь вы можете добавить следующую директиву using:

#if DEBUG
using NUnit.Framework;
#endif

Я обычно добавляю ее на самый верх региона с директивами using, поскольку она используется только в отладочном режиме и все тестовые модули используются только в отладочных вариантах; в итоговой игре не будет ни дополнительной библиотеки NUnit.Framework.dll, ни тестового кода, поскольку все это не нужно.

В качестве примера взгляните на первый тестовый модуль в классе StringHelper, проверяющий, что вспомогательный метод IsInList работает как ожидалось:

[TestFixture]
public class StringHelperTests
{
  /// <summary>
  /// Проверка IsInList
  /// </summary>
  [Test]
  public void TestIsInList()
  {
    Assert.IsTrue(IsInList("whats",
      new string[] { "hi", "whats", "up?" }, false));
    Assert.IsFalse(IsInList("no way",
      new string[]
      { "omg", "no no", "there is no way!" }, false));
  } // TestIsInList()
...

Assert — это вспомогательный класс внутри инфраструктуры NUnit, содержащий методы для проверки соответствия возвращаемого значения ожидаемому. Если значение не соответствует ожидаемому, генерируется исключение, и вы немедленно увидите в какой строке теста произошел сбой. Например, Assert.IsTrue проверяет равно ли возвращаемое IsInList значение true. Если возвращается значение false, генерируется исключение. К счастью, список строк содержит "whats" и тест должен быть пройден. Следующий тест проверяет наличие "no way", такой строки во втором списке нет, следовательно вторая строка теста должна вернуть false, что и проверяется. Обратите внимание: "there is no way!" содержит "no way", но вы для проверки используете не метод Contains, также присутствующий в классе StringHelper. IsInList возвращает true только при обнаружении в списке точного соответствия.

Запуск тестов модулей

В TestDriven .NET вы можете запустить тест, щелкнув правой кнопкой мыши по методу и выбрав команду Run Test (рис. 3.6), или вы можете использовать графический интерфейс программы NUnit, если у вас нет TestDriven .NET или вы не можете его использовать. С помощью TestDriven .NET вы можете так же тестировать статические тестовые модули, но графический интерфейс NUnit статические тестовые модули не поддерживает. Поэтому я добавляю тестовые модули в Program.cs (или в UnitTesting.cs в последующих проектах) для поддержки всех пользователей и XNA Studio Express. TestDriven .NET может использоваться для запуска как динамических, так и статических тестов модулей, но, начиная с версии 2.0 для правильной работы вы должны удалять атрибут [Test] из статических тестовых модулей (впрочем, в этой книге мы вообще не будем использовать атрибут [Test] для статических тестов модулей).


Рис. 3.6

Рис. 3.6


Тест должен быть выполнен без ошибок, но если в коде теста вы замените "whats" на "whats up", то первый тест Assert приведет к сбою и в TestDriven .NET вы увидите следующие результаты:

TestCase 'M:XnaBreakout.Helpers.StringHelper.StringHelperTests.TestIsInList' failed:
  NUnit.Framework.AssertionException
  at NUnit.Framework.Assert.DoAssert(IAsserter asserter)
  at NUnit.Framework.Assert.IsTrue(Boolean condition, String message, Object[] args)
  at NUnit.Framework.Assert.IsTrue(Boolean condition)
  C:\code\XnaRacer\Helpers\StringHelper.cs(1387,0): at
    XnaBreakout.Helpers.StringHelper.StringHelperTests.TestIsInList()

0 passed, 1 failed, 0 skipped,  took 0,48 seconds.

Здесь вам сказано, куда надо смотреть (вы даже можете два раза щелкнуть по описанию ошибки и сразу перейти к строке 1387) и что вы должны изменить. Сообщение об ошибке более наглядно при использовании графического интерфейса NUnit (рис. 3.7).


Рис. 3.7

Рис. 3.7


Графический интерфейс NUnit — это хороший инструмент для одновременного запуска нескольких тестовых модулей, быстрого обнаружения тех из них, которые не отработали должным образом и дальнейших исследований в исходном коде. Вы можете выбрать команду Load в меню File или просто перетащить любой .exe или .dll файл .NET в окно программы NUnit. Затем вы увидите все тесты в сборке и сможете проверить их, щелкнув по кнопке Run. Программа замечательная, но я обычно предпочитаю при кодировании и тестировании не выходить из среды программирования, и поэтому мне больше нравится TestDriven .NET, которую я всегда использую. Для исправления ошибки просто замените строку «whats up» обратно на «whats», все ваши тесты будут выполнены и вам будет дан зеленый свет.

Золотые правила

Я не слишком много разглагольствовал здесь о написании тестовых модулей, поскольку в главе 2 уже обсуждались основные правила, которые, конечно, применимы и для динамических тестов модулей. держите в уме следующие руководства, когда начнете писать свои первые тестовые модули:


netlib.narod.ru< Назад | Оглавление | Далее >

Сайт управляется системой uCoz