Введение в модульное тестирование для c# проектов в среде MonoDevelop

Модульные тесты используются при разработке программного обеспечения. Они могут быть созданы как после написания исходного кода, так и до этого, все зависит от ваших предпочтений и вероисповедания, либо предпочтений вашей компании. Разработка через тестирование(TDD) вызывает довольно спорное впечатление. Кто-то считает, что это довольно бесполезная вещь, однако склонен не согласиться. Бесполезным TDD назвать точно нельзя. Создание теста покрывающего предполагаемое изменение в программе, а затем написание кода который бы позволил пройти этот тест, заметно упрощает разработку. Модульные тесты так же используются для проверки уже созданного функционала. Однако достичь 100% покрытия кода программы модульными тестами практически невозможно.

План:
  1. Создание программы HelloWorld.
  2. Написание модульных тестов для HelloWorld.
  3. Написание исходного кода для прохождения модульных тестов.


Почему был выбран C#? Это довольно легкий в освоении язык программирования. В котором не нужно задумываться над выделением памяти и её очисткой. Широкий выбор различных библиотек .NET позволяет без особого труда реализовать сложные задачи. Помимо этого, программы скомпилированные в одной платформе с использованием CLR можно запустить на другой платформе, в которой присутствует реализация CLR.

Создание программы HelloWorld


  1. Запустите MonoDevelop и создайте новый проект HelloWorld.
  2. Создайте новый класс Goodbyer.
  3. Помимо конструктора без параметров, создайте конструктор со строкой, в качестве параметра. А так же метод, возвращающий строку и позволяющий задавать значение поля _who.

Создание модульных тестов


  1. Создайте новый проект библиотеки тестов NUnit в данном решении.
  2. Добавьте ссылку на проект HelloWorld.
  3. Создайте несколько модульных тестов для конструктора с параметрами и для метода задающего значение поля _who. Картинка 5
  4. На следующем изображении видно, что не все тесты были пройдены. Так как программа не выдает исключения, когда мы задаем поле _who пустым.

Изменение класса Goodbyer для прохождения модульных тестов


  1. Изменим класс Goodbyer так, чтобы он выдавал исключения, когда в поле _who записывается пустая строка.
  2. На вышестоящем изображении видно, что все тесты были пройдены.


На этом все. Если вы проделали все шаги, то вас можно поздравить с освоением простейших принципов модульного тестирования.

Ссылки


Using NUnit with MonoDevelop: www.dijksterhuis.org/using-nunit-with-monodevelop — Туториал по созданию модульных тестов в NUnit c MonoDevelop.

C# Unit Test Tutorial: www.rhyous.com/programming-development/csharp-unit-test-tutorial — Туториал по модульному тестированию.
Share post

Similar posts

Comments 10

    0
    Продолжение будет?
      0
      Если вы желаете, что-нибудь спросить, то спрашивайте, не стесняйтесь. Если потребуется дать довольно емкий ответ, то конечно будет написано продолжение.
      +3
      Самое неприятное, что в MonoDevelop оснастка для Unit-тестирования гвоздями приколочена к NUnit и по сути является всего лишь интерфейсом к нему. Какое-либо API, позволяющее использовать иные системы просто напросто отсутствует. В результате интеграция того же xUnit, являющегося существенно более продвинутым, видится делом весьма трудозатратным.
      Это крайне печалит, ибо NUnit все тесты из конкретного кейса выполняет используя один и тот же экземпляр класса, в результате, если не позаботиться о том, чтобы в начале работы каждого из них было «чистое» состояние, то можно получить несколько странные результаты.
        0
        Самое неприятное, что в MonoDevelop нет Resharper'a.
          +1
          Ну они тащат из него часть фич, хотя это больше заслуга NRefactory.
          0
          Абсолютно с вами согласен. Если не следить за созданием новых объектов, то можно случайно обнаружить нежелательно созданные объекты и подобные вещи.
            0
            Mike Kruger в твиттере отмечал необходимость XUnit addin'a. Так же он сказал, что было бы не плохо, если комьюнити поможет реализовать поддержку XUnit.

            Я даже проводил небольшое исследование по MD, XUnit, NUnit фреймворкам. Задача не тревиальная. А текущий NUnit addin действительно тихий ужас. Только немножко разобрать и прокомментировать код этого дополнения стоило мне много времени.

            А насчет одного экземпляра на множество кейсов — разве не должно быть так? По-моему, NUnit так и работает? XUnit, да, этот точно создает по экземпляру на тест.
              0
              А насчет одного экземпляра на множество кейсов — разве не должно быть так? По-моему, NUnit так и работает? XUnit, да, этот точно создает по экземпляру на тест.
              Да, NUnit так и работает, что вызывает ряд проблем. Например, у вас во всех тестах используется общий код инициализации, который достаточно «толст», чтобы его вынести в конструктор и занести нужные данные в поля класса. Если тест меняет состояние объектов, то данный подход становится неприменим в случае одного экземпляра на все тесты.

              Относительно единого AddIn-а: что у NUnit, что у xUnit есть режимы работы для TeamCity, обеспечивающие некоторый унифицированный вывод на stdout. Вполне возможно, что имеет смысл использовать консольные runner-ы и сделать унифицированный GUI с нуля.
                0
                Поигрался с консольным runner-ом. Есть загвоздка: непонятно как остановить выполнение (например, по требованию пользователя). Можно, конечно, делать Process.Kill() для Runner-a. Только будет ли это корректным, на середине выполнения теста убивать процесс? Еще один недостаток: результат выполнения будет для всех тестов разом (т. е. синхронно подсветить результат красным или зеленым не получится).

                Есть вариант создать своими силами простенькое консольное приложение. В нем реализовать IRunnerLogger и по мере выполнения тестов выводить на stdout результат «строка за строкой», а в Addin-e синхронно парсить вывод. Однако, не могу придумать, как корректно остановить выполнение.
                  0
                  Убиение процесса является вполне корректным способом остановки, особенно если какой-то тест банально ушёл в бесконечный цикл.

          Only users with full accounts can post comments. Log in, please.