Руководство: Тестирование библиотеки классов .NET с помощью .NET и Visual Studio
В этом руководстве показано, как автоматизировать модульное тестирование путем добавления тестового проекта в решение.
Необходимые условия
- В этом руководстве используется решение, которое вы создаёте в процессе создания библиотеки классов .NET с помощью Visual Studio.
Создание проекта модульного теста
Модульные тесты обеспечивают автоматическое тестирование программного обеспечения во время разработки и публикации. MSTest является одной из трех платформ тестирования, которые можно выбрать. Другие — xUnit и nUnit.
Запустите Visual Studio.
Откройте решение
ClassLibraryProjects
, созданное в создание библиотеки классов .NET с помощью Visual Studio.Добавьте в решение новый проект модульного теста с именем StringLibraryTest.
Щелкните правой кнопкой мыши решение в обозревателе решений и выберите Добавить>новый проект.
На странице Добавление нового проекта введите mstest в поле поиска. Выберите C# или Visual Basic в списке языков, а затем выберите Все платформы из списка платформ.
Выберите шаблон проекта тестирования MSTest , а затем выберите Далее.
На странице
Настройка нового проекта введитеStringLibraryTest в поле имени проекта. Затем выберите Далее. На странице Дополнительные сведения выберите .NET 8 в поле Framework. Затем выберите Создать.
Visual Studio создает проект и открывает файл класса в окне кода со следующим кодом. Если язык, который вы хотите использовать, не отображается, измените селектор языка в верхней части страницы.
namespace StringLibraryTest; [TestClass] public class UnitTest1 { [TestMethod] public void TestMethod1() { } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Sub TestSub() End Sub End Class End Namespace
Исходный код, созданный шаблоном модульного теста, выполняет следующие действия:
- Он импортирует пространство имен Microsoft.VisualStudio.TestTools.UnitTesting, содержащее типы, используемые для модульного тестирования. В C# пространство имен импортируется с помощью директивы
global using
в GlobalUsings.cs. - Он применяет атрибут TestClassAttribute к классу
UnitTest1
. - Он применяет атрибут TestMethodAttribute для определения
TestMethod1
в C# илиTestSub
в Visual Basic.
Каждый метод, помеченный [TestMethod], в тестовом классе, помеченном [TestClass], выполняется автоматически при запуске модульного теста.
- Он импортирует пространство имен Microsoft.VisualStudio.TestTools.UnitTesting, содержащее типы, используемые для модульного тестирования. В C# пространство имен импортируется с помощью директивы
Добавление ссылки на проект
Чтобы тестовый проект работал с классом StringLibrary
, добавьте ссылку в проект StringLibraryTest в проект StringLibrary
.
В обозревателе решений щелкните правой кнопкой мыши на узле зависимостей проекта StringLibraryTest и выберите пункт Добавить ссылку на проект в контекстном меню.
В диалоговом окне Диспетчера ссылок разверните узел Проекты и выберите поле рядом с StringLibrary. Добавление ссылки на сборку
StringLibrary
позволяет компилятору найти методы StringLibrary при компиляции проекта StringLibraryTest.Выберите ОК.
Добавление и запуск методов модульного теста
При запуске модульного теста Visual Studio выполняет каждый метод, помеченный атрибутом TestMethodAttribute в классе, помеченном атрибутом TestClassAttribute. Метод теста заканчивается, когда обнаружен первый сбой или когда все тесты, содержащиеся в методе, успешно выполнены.
Наиболее распространенные тесты вызывают функции из класса Assert. Многие методы утверждения включают по крайней мере два параметра, один из которых является ожидаемым результатом теста, а другой — фактическим результатом теста. Некоторые из наиболее часто вызываемых методов класса Assert
показаны в следующей таблице:
Методы Assert | Функция |
---|---|
Assert.AreEqual |
Проверяет, равны ли два значения или объекты. Утверждение завершается ошибкой, если значения или объекты не равны. |
Assert.AreSame |
Проверяет, что две переменные объекта ссылаются на один и тот же объект. Утверждение завершается ошибкой, если переменные ссылаются на разные объекты. |
Assert.IsFalse |
Проверяет, что условие соответствует false . Утверждение завершается ошибкой, если условие true . |
Assert.IsNotNull |
Проверяет, что объект не является null . Утверждение завершается ошибкой, если объект null . |
Вы также можете использовать метод Assert.ThrowsException (или Assert.Throws
и Assert.ThrowsExactly
при использовании метода тестирования MSTest 3.8 и более поздних версий), чтобы указать тип исключения, который он должен вызвать. Тест завершается ошибкой, если указанное исключение не возникает.
При тестировании метода StringLibrary.StartsWithUpper
необходимо указать ряд строк, начинающихся с верхнего регистра. Вы ожидаете, что метод возвращает true
в этих случаях, поэтому можно вызвать метод Assert.IsTrue. Аналогичным образом необходимо указать ряд строк, которые начинаются с символа, отличного от символа верхнего регистра. Вы ожидаете, что метод возвращает false
в этих случаях, поэтому можно вызвать метод Assert.IsFalse.
Так как метод библиотеки обрабатывает строки, вы также хотите убедиться, что он успешно обрабатывает пустую строку (String.Empty
), допустимую строку, которая не имеет символов и Length равно 0, и строка null
, которая не была инициализирована. Вы можете вызывать StartsWithUpper
напрямую как статический метод и передавать один аргумент String. Или вы можете вызвать StartsWithUpper
как метод расширения для переменной string
, назначенной null
.
Вы определите три метода, каждый из которых вызывает метод Assert для каждого элемента в массиве строк. Вы вызовете перегрузку метода, которая позволяет указать сообщение об ошибке, отображаемое в случае сбоя теста. Сообщение определяет строку, которая вызвала сбой.
Чтобы создать методы тестирования, выполните следующие действия.
В окне кода UnitTest1.cs или UnitTest1.vb замените код следующим кодом:
using UtilityLibraries; namespace StringLibraryTest { [TestClass] public class UnitTest1 { [TestMethod] public void TestStartsWithUpper() { // Tests that we expect to return true. string[] words = { "Alphabet", "Zebra", "ABC", "Αθήνα", "Москва" }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsTrue(result, string.Format("Expected for '{0}': true; Actual: {1}", word, result)); } } [TestMethod] public void TestDoesNotStartWithUpper() { // Tests that we expect to return false. string[] words = { "alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }; foreach (var word in words) { bool result = word.StartsWithUpper(); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word, result)); } } [TestMethod] public void DirectCallWithNullOrEmpty() { // Tests that we expect to return false. string?[] words = { string.Empty, null }; foreach (var word in words) { bool result = StringLibrary.StartsWithUpper(word); Assert.IsFalse(result, string.Format("Expected for '{0}': false; Actual: {1}", word == null ? "<null>" : word, result)); } } } }
Imports Microsoft.VisualStudio.TestTools.UnitTesting Imports UtilityLibraries Namespace StringLibraryTest <TestClass> Public Class UnitTest1 <TestMethod> Public Sub TestStartsWithUpper() ' Tests that we expect to return true. Dim words() As String = {"Alphabet", "Zebra", "ABC", "Αθήνα", "Москва"} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsTrue(result, $"Expected for '{word}': true; Actual: {result}") Next End Sub <TestMethod> Public Sub TestDoesNotStartWithUpper() ' Tests that we expect to return false. Dim words() As String = {"alphabet", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " "} For Each word In words Dim result As Boolean = word.StartsWithUpper() Assert.IsFalse(result, $"Expected for '{word}': false; Actual: {result}") Next End Sub <TestMethod> Public Sub DirectCallWithNullOrEmpty() ' Tests that we expect to return false. Dim words() As String = {String.Empty, Nothing} For Each word In words Dim result As Boolean = StringLibrary.StartsWithUpper(word) Assert.IsFalse(result, $"Expected for '{If(word Is Nothing, "<null>", word)}': false; Actual: {result}") Next End Sub End Class End Namespace
Тест прописных символов в методе
TestStartsWithUpper
включает греческую заглавную букву альфа (U+0391) и кириллическую заглавную букву ЭМ (U+041C). Тест маленьких символов в методеTestDoesNotStartWithUpper
включает в себя греческую маленькую букву альфа (U+03B1) и маленькую кириллическую букву г (U+0433).В строке меню выберите Файл>Сохранить UnitTest1.cs как или файл>сохранить UnitTest1.vb как. В диалоговом окне Сохранить файл как щелкните стрелку рядом с кнопкой Сохранить и нажмите кнопку Сохранить с помощью кодировки.
В диалоговом окне Подтвердить сохранение как выберите кнопку Да для сохранения файла.
В диалоговом окне "Дополнительные параметры сохранения" выберите Юникод (UTF-8 с подписью) — Codepage 65001 в раскрывающемся списке кодировки и нажмите кнопку ОК.
диалоговое окно "Дополнительные параметры сохранения"
Visual Studio Если не удается сохранить исходный код в виде файла в кодировке UTF8, Visual Studio может сохранить его в виде ФАЙЛА ASCII. В этом случае среда выполнения не декодирует символы UTF8 за пределами диапазона ASCII, а результаты теста не будут правильными.
В строке меню выберите Тест>Выполнить все тесты. Если окно обозревателя тестов
не открыто, откройте его, выбрав Обозреватель тестов . Три теста перечислены в разделе Пройденные тесты, а раздел Сводка сообщает результат выполнения тестов.окно обозревателя тестов
Управление сбоями тестов
Если вы выполняете разработку на основе тестов (TDD), сначала напишите тесты, и они завершаются сбоем при первом запуске. Затем вы добавите код в приложение, которое делает тест успешным. В этом руководстве вы создали тест после написания кода приложения, который он проверяет, поэтому вы не видели, чтобы тест проваливался. Чтобы убедиться, что тест завершается ошибкой, когда это ожидается, добавьте недопустимое значение в входные данные теста.
Измените массив
words
в методеTestDoesNotStartWithUpper
, чтобы включить строку "Error". Не нужно сохранять файл, так как Visual Studio автоматически сохраняет открытые файлы при создании решения для выполнения тестов.string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " };
Dim words() As String = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство", "1234", ".", ";", " " }
Запустите тест, выбрав тест>запустить все тесты в строке меню. В окне обозревателя тестов
указано, что два теста успешно выполнены, а один завершился сбоем. окно обозревателя тестов
Выберите неудачный тест,
TestDoesNotStartWith
.В окне обозревателя тестов
отображается сообщение, созданное выражением assert: "Assert.IsFalse завершилось сбоем. Ожидалось значение для 'Error': false; фактическое: True. Из-за сбоя строки в массиве после "Ошибка" не были проверены. окно обозревателя тестов
Удалите строку "Ошибка", добавленную на шаге 1. Повторно запустите тест, и тесты проходят.
Тестирование релизной версии библиотеки
Теперь, когда все тесты прошли при запуске отладочной сборки библиотеки, запустите тесты ещё раз для релизной сборки библиотеки. Некоторые факторы, включая оптимизации компилятора, иногда могут приводить к различному поведению между сборками Debug и Release.
Чтобы протестировать релизную сборку, выполните следующие действия.
На панели инструментов Visual Studio измените конфигурацию сборки с Debug на Release.
В обозревателе решений
щелкните правой кнопкой мыши проект StringLibrary и выберитеСборка в контекстном меню, чтобы перекомпилировать библиотеку.контекстное меню
Запустите модульные тесты, выбрав из строки меню Тест>Выполнить все тесты. Тесты успешно пройдены.
Отладка тестов
Если вы используете Visual Studio в качестве интегрированной среды разработки, вы можете использовать тот же процесс, описанный в учебнике "Отладка консольного приложения .NET с помощью Visual Studio", чтобы отладить код, используя ваш проект модульного тестирования. Вместо запуска приложения ShowCase, щелкните правой кнопкой мыши проект StringLibraryTests и выберите пункт Отладка тестов в контекстном меню.
Visual Studio запускает тестовый проект с присоединенным отладчиком. Выполнение остановится в любой точке останова, которую вы добавили в тестовый проект или код базовой библиотеки.
Дополнительные ресурсы
- Основы модульного тестирования — Visual Studio
- модульное тестирование в .NET
Дальнейшие действия
В этом руководстве вы провели модульное тестирование библиотеки классов. Вы можете сделать библиотеку доступной для других пользователей, публикуя ее в NuGet в виде пакета. Чтобы узнать, как это сделать, следуйте инструкциям по NuGet.
Если вы публикуете библиотеку в виде пакета NuGet, другие пользователи могут установить и использовать ее. Чтобы узнать, как это сделать, следуйте инструкциям по NuGet.
Библиотеку не нужно распространять как пакет. Его можно объединить с консольным приложением, использующим его. Чтобы узнать, как опубликовать консольное приложение, ознакомьтесь с предыдущим руководством в этой серии: