Поделиться через


Руководство. Тестирование библиотеки классов .NET с помощью Visual Studio Code

В этом руководстве показано, как автоматизировать модульное тестирование путем добавления тестового проекта в решение.

Необходимые компоненты

Создание проекта модульного теста

Модульные тесты обеспечивают автоматическое тестирование программного обеспечения во время разработки и публикации. В этом руководстве используется платформа тестирования MSTest. MSTest — это одна из трех доступных для выбора платформ тестирования. Другими являются xUnit и nUnit.

  1. Запустите Visual Studio Code.

  2. Откройте решениеClassLibraryProjects, созданное при работе со статьей Создание библиотеки классов .NET в Visual Studio Code.

  3. Создайте проект модульного теста с именем StringLibraryTest.

    dotnet new mstest -o StringLibraryTest
    

    Шаблон проекта создает файл UnitTest1.cs со следующим кодом:

    namespace StringLibraryTest;
    
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
        }
    }
    

    Исходный код, созданный шаблоном модульного теста, выполняет следующие действия.

    • Он применяет атрибут TestClassAttribute к классу UnitTest1.
    • Он применяет атрибут TestMethodAttribute для определения TestMethod1.
    • Он импортирует пространство имен Microsoft.VisualStudio.TestTools.UnitTesting, которое содержит типы, используемые для модульного тестирования. Пространство имен импортируется с помощью директивы global using в GlobalUsings.cs.

    При вызове модульного теста автоматически выполняются все методы теста, помеченные атрибутом [TestMethod], в тестовом классе, помеченном атрибутом [TestClass].

  4. Добавьте тестовый проект в решение.

    dotnet sln add StringLibraryTest/StringLibraryTest.csproj
    

Добавление ссылки на проект

Чтобы тестовый проект работал с классом StringLibrary, добавьте в проект StringLibraryTest ссылку на проект StringLibrary.

  1. Выполните следующую команду:

    dotnet add StringLibraryTest/StringLibraryTest.csproj reference StringLibrary/StringLibrary.csproj
    

Добавление и выполнение методов модульного теста

При вызове модульного теста Visual Studio запускает каждый метод, помеченный TestMethodAttribute атрибутом в классе, помеченном атрибутом TestClassAttribute . Метод теста завершается, когда происходит первый сбой или когда все тесты, содержащиеся в методе, будут успешно выполнены.

В самых распространенных тестах вызываются члены класса Assert. Многие методы утверждения (Assert) принимают по крайней мере два параметра, из которых один представляет ожидаемый результат теста, а второй — фактический результат теста. Наиболее популярные из этих методов класса Assert перечислены в следующей таблице:

Методы утверждения Функция
Assert.AreEqual Проверяет равенство двух значений или объектов. Утверждение не выполняется, если значения или объекты не равны.
Assert.AreSame Проверяет, что две объектные переменные ссылаются на один и тот же объект. Утверждение не выполняется, если переменные ссылаются на разные объекты.
Assert.IsFalse Проверяет, что условие имеет значение false. Утверждение не выполняется, если условие имеет значение true.
Assert.IsNotNull Проверяет, что объект не имеет значение null. Утверждение не выполняется, если объект является null.

Вы можете также использовать метод Assert.ThrowsException в методе теста, чтобы указать тип исключения, которое он должен создавать. Такой тест считается не выполненным, если заявленное исключение не было создано.

Для тестирования метода StringLibrary.StartsWithUpper необходимо предоставить несколько строк, которые начинаются с символов верхнего регистра. Предполагается, что в этих случаях метод возвратит true, поэтому можно вызвать метод Assert.IsTrue. Представьте также несколько строк, которые не начинаются с символов верхнего регистра. Предполагается, что в этих случаях метод возвратит false, поэтому можно вызвать метод Assert.IsFalse.

Так как метод библиотеки обрабатывает строки, необходимо также убедиться, что он обрабатывает пустую строку (String.Empty), а также строку null. Пустая строка не содержит символов, а ее свойство Length равно 0. Строка null является неинициализированной строкой. Метод StartsWithUpper можно вызвать напрямую как статический метод и передать ему один аргумент типа String. Или метод StartsWithUpper можно вызвать как метод расширения для переменной string, которой назначено значение null.

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

Создание методов теста:

  1. Откройте файл StringLibraryTest/UnitTest1.cs и замените все его содержимое следующим кодом:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    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));
            }
        }
    }
    

    Тест на символы верхнего регистра в методе TestStartsWithUpper включает заглавную греческую букву "альфа" (U+0391) и заглавную кириллическую букву "М" (U+041C). Тест на символы нижнего регистра в методе TestDoesNotStartWithUpper включает строчную греческую букву "альфа" (U+03B1) и строчную кириллическую букву "г" (U+0433).

  2. Сохранение изменений.

  3. Запустите тесты.

    dotnet test StringLibraryTest/StringLibraryTest.csproj
    

    В выходных данных терминала показано, что все тесты пройдены.

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
    
    Passed!  - Failed:     0, Passed:     3, Skipped:     0, Total:     3, Duration: 3 ms - StringLibraryTest.dll (net8.0)
    

Обработка сбоев теста

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

  1. Измените массив words в методе TestDoesNotStartWithUpper, включив в него строку "Error".

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
  2. Запустите тесты.

    dotnet test StringLibraryTest/StringLibraryTest.csproj
    

    Выходные данные терминала показывают, что один тест завершается ошибкой, и он предоставляет сообщение об ошибке для неудачного теста: "Assert.IsFalse не удалось. Expected for 'Error': false; actual: True". Из-за этого сбоя строки в массиве, расположенные после слова "Error", не проверялись.

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
      Failed TestDoesNotStartWithUpper [28 ms]
      Error Message:
       Assert.IsFalse failed. Expected for 'Error': false; Actual: True
      Stack Trace:
         at StringLibraryTest.UnitTest1.TestDoesNotStartWithUpper() in C:\ClassLibraryProjects\StringLibraryTest\UnitTest1.cs:line 33
    
    Failed!  - Failed:     1, Passed:     2, Skipped:     0, Total:     3, Duration: 31 ms - StringLibraryTest.dll (net5.0)
    
  3. Удалите строку "Error", которую вы добавили на шаге 1. Еще раз запустите тест. Теперь тесты будут пройдены.

Тестирование версии выпуска для библиотеки

Теперь, когда все тесты пройдены при выполнении сборки в режиме отладки, следует запустить все тесты еще раз, теперь уже для сборки библиотеки в режиме выпуска. Некоторые факторы, например оптимизации компилятора, иногда могут вызывать разное поведение сборки в режимах отладки и выпуска.

  1. Запустите тесты с конфигурацией сборки "Выпуск".

    dotnet test StringLibraryTest/StringLibraryTest.csproj --configuration Release
    

    Все тесты будут пройдены.

Отладка тестов

Если в качестве IDE вы используете Visual Studio Code, то можете следовать инструкциям из руководства по отладке консольного приложения .NET с помощью Visual Studio Code, чтобы выполнить отладку кода с применением проекта модульного теста. Вместо запуска проекта приложения ShowCase откройте StringLibraryTest/UnitTest1.cs и выберите Debug All Tests (Выполнить отладку всех тестов) между строками 7 и 8. Если вы не можете найти его, нажмите клавиши CTRL+SHIFT+P, чтобы открыть палитру команд, и введите команду перезагрузки окна.

Visual Studio Code запускает тестовый проект с присоединенным отладчиком. Выполнение будет прервано в любой точке останова, добавленной в тестовый проект или базовый код библиотеки.

Дополнительные ресурсы

Следующие шаги

В этом руководстве вы выполнили модульное тестирование библиотеки классов. Чтобы сделать библиотеку доступной другим пользователям, опубликуйте ее в NuGet в качестве пакета. Чтобы узнать, как это делать, следуйте указаниям в руководстве по NuGet:

Если библиотека опубликована как пакет NuGet, ее могут устанавливать и использовать другие пользователи. Чтобы узнать, как это делать, следуйте указаниям в руководстве по NuGet:

Библиотеку не нужно распространять как пакет. Ее можно объединить с консольным приложением, где она используется. Чтобы узнать, как опубликовать консольное приложение, ознакомьтесь с предыдущим руководством в этой серии:

Пакет средств разработки для расширения Visual Studio Code C# предоставляет дополнительные средства для разработки приложений и библиотек C#:

В этом руководстве показано, как автоматизировать модульное тестирование путем добавления тестового проекта в решение.

Необходимые компоненты

Создание проекта модульного теста

Модульные тесты обеспечивают автоматическое тестирование программного обеспечения во время разработки и публикации. В этом руководстве используется платформа тестирования MSTest. MSTest — это одна из трех доступных для выбора платформ тестирования. Другими являются xUnit и nUnit.

  1. Запустите Visual Studio Code.

  2. Откройте решениеClassLibraryProjects, созданное при работе со статьей Создание библиотеки классов .NET в Visual Studio Code.

  3. Создайте проект модульного теста с именем StringLibraryTest.

    dotnet new mstest -o StringLibraryTest
    

    Шаблон проекта создает файл UnitTest1.cs со следующим кодом:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
            }
        }
    }
    

    Исходный код, созданный шаблоном модульного теста, выполняет следующие действия.

    • Он импортирует пространство имен Microsoft.VisualStudio.TestTools.UnitTesting, которое содержит типы, используемые для модульного тестирования.
    • Он применяет атрибут TestClassAttribute к классу UnitTest1.
    • Он применяет атрибут TestMethodAttribute для определения TestMethod1.

    При вызове модульного теста автоматически выполняются все методы теста, помеченные атрибутом [TestMethod], в тестовом классе, помеченном атрибутом [TestClass].

  4. Добавьте тестовый проект в решение.

    dotnet sln add StringLibraryTest/StringLibraryTest.csproj
    

Добавление ссылки на проект

Чтобы тестовый проект работал с классом StringLibrary, добавьте в проект StringLibraryTest ссылку на проект StringLibrary.

  1. Выполните следующую команду:

    dotnet add StringLibraryTest/StringLibraryTest.csproj reference StringLibrary/StringLibrary.csproj
    

Добавление и выполнение методов модульного теста

При вызове модульного теста Visual Studio запускает каждый метод, помеченный TestMethodAttribute атрибутом в классе, помеченном атрибутом TestClassAttribute . Метод теста завершается, когда происходит первый сбой или когда все тесты, содержащиеся в методе, будут успешно выполнены.

В самых распространенных тестах вызываются члены класса Assert. Многие методы утверждения (Assert) принимают по крайней мере два параметра, из которых один представляет ожидаемый результат теста, а второй — фактический результат теста. Наиболее популярные из этих методов класса Assert перечислены в следующей таблице:

Методы утверждения Функция
Assert.AreEqual Проверяет равенство двух значений или объектов. Утверждение не выполняется, если значения или объекты не равны.
Assert.AreSame Проверяет, что две объектные переменные ссылаются на один и тот же объект. Утверждение не выполняется, если переменные ссылаются на разные объекты.
Assert.IsFalse Проверяет, что условие имеет значение false. Утверждение не выполняется, если условие имеет значение true.
Assert.IsNotNull Проверяет, что объект не имеет значение null. Утверждение не выполняется, если объект является null.

Вы можете также использовать метод Assert.ThrowsException в методе теста, чтобы указать тип исключения, которое он должен создавать. Такой тест считается не выполненным, если заявленное исключение не было создано.

Для тестирования метода StringLibrary.StartsWithUpper необходимо предоставить несколько строк, которые начинаются с символов верхнего регистра. Предполагается, что в этих случаях метод возвратит true, поэтому можно вызвать метод Assert.IsTrue. Представьте также несколько строк, которые не начинаются с символов верхнего регистра. Предполагается, что в этих случаях метод возвратит false, поэтому можно вызвать метод Assert.IsFalse.

Так как метод библиотеки обрабатывает строки, необходимо также убедиться, что он обрабатывает пустую строку (String.Empty), а также строку null. Пустая строка не содержит символов, а ее свойство Length равно 0. Строка null является неинициализированной строкой. Метод StartsWithUpper можно вызвать напрямую как статический метод и передать ему один аргумент типа String. Или метод StartsWithUpper можно вызвать как метод расширения для переменной string, которой назначено значение null.

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

Создание методов теста:

  1. Откройте файл StringLibraryTest/UnitTest1.cs и замените все его содержимое следующим кодом:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    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));
            }
        }
    }
    

    Тест на символы верхнего регистра в методе TestStartsWithUpper включает заглавную греческую букву "альфа" (U+0391) и заглавную кириллическую букву "М" (U+041C). Тест на символы нижнего регистра в методе TestDoesNotStartWithUpper включает строчную греческую букву "альфа" (U+03B1) и строчную кириллическую букву "г" (U+0433).

  2. Сохранение изменений.

  3. Запустите тесты.

    dotnet test StringLibraryTest/StringLibraryTest.csproj
    

    В выходных данных терминала показано, что все тесты пройдены.

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
    
    Passed!  - Failed:     0, Passed:     3, Skipped:     0, Total:     3, Duration: 3 ms - StringLibraryTest.dll (net7.0)
    

Обработка сбоев теста

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

  1. Измените массив words в методе TestDoesNotStartWithUpper, включив в него строку "Error".

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
  2. Запустите тесты.

    dotnet test StringLibraryTest/StringLibraryTest.csproj
    

    Выходные данные терминала показывают, что один тест завершается ошибкой, и он предоставляет сообщение об ошибке для неудачного теста: "Assert.IsFalse не удалось. Expected for 'Error': false; actual: True". Из-за этого сбоя строки в массиве, расположенные после слова "Error", не проверялись.

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
      Failed TestDoesNotStartWithUpper [28 ms]
      Error Message:
       Assert.IsFalse failed. Expected for 'Error': false; Actual: True
      Stack Trace:
         at StringLibraryTest.UnitTest1.TestDoesNotStartWithUpper() in C:\ClassLibraryProjects\StringLibraryTest\UnitTest1.cs:line 33
    
    Failed!  - Failed:     1, Passed:     2, Skipped:     0, Total:     3, Duration: 31 ms - StringLibraryTest.dll (net5.0)
    
  3. Удалите строку "Error", которую вы добавили на шаге 1. Еще раз запустите тест. Теперь тесты будут пройдены.

Тестирование версии выпуска для библиотеки

Теперь, когда все тесты пройдены при выполнении сборки в режиме отладки, следует запустить все тесты еще раз, теперь уже для сборки библиотеки в режиме выпуска. Некоторые факторы, например оптимизации компилятора, иногда могут вызывать разное поведение сборки в режимах отладки и выпуска.

  1. Запустите тесты с конфигурацией сборки "Выпуск".

    dotnet test StringLibraryTest/StringLibraryTest.csproj --configuration Release
    

    Все тесты будут пройдены.

Отладка тестов

Если в качестве IDE вы используете Visual Studio Code, то можете следовать инструкциям из руководства по отладке консольного приложения .NET с помощью Visual Studio Code, чтобы выполнить отладку кода с применением проекта модульного теста. Вместо запуска проекта приложения ShowCase откройте StringLibraryTest/UnitTest1.cs и выберите Debug All Tests (Выполнить отладку всех тестов) между строками 7 и 8. Если вы не можете найти его, нажмите клавиши CTRL+SHIFT+P, чтобы открыть палитру команд, и введите команду перезагрузки окна.

Visual Studio Code запускает тестовый проект с присоединенным отладчиком. Выполнение будет прервано в любой точке останова, добавленной в тестовый проект или базовый код библиотеки.

Дополнительные ресурсы

Следующие шаги

В этом руководстве вы выполнили модульное тестирование библиотеки классов. Чтобы сделать библиотеку доступной другим пользователям, опубликуйте ее в NuGet в качестве пакета. Чтобы узнать, как это делать, следуйте указаниям в руководстве по NuGet:

Если библиотека опубликована как пакет NuGet, ее могут устанавливать и использовать другие пользователи. Чтобы узнать, как это делать, следуйте указаниям в руководстве по NuGet:

Библиотеку не нужно распространять как пакет. Ее можно объединить с консольным приложением, где она используется. Чтобы узнать, как опубликовать консольное приложение, ознакомьтесь с предыдущим руководством в этой серии:

В этом руководстве показано, как автоматизировать модульное тестирование путем добавления тестового проекта в решение.

Необходимые компоненты

Создание проекта модульного теста

Модульные тесты обеспечивают автоматическое тестирование программного обеспечения во время разработки и публикации. В этом руководстве используется платформа тестирования MSTest. MSTest — это одна из трех доступных для выбора платформ тестирования. Другими являются xUnit и nUnit.

  1. Запустите Visual Studio Code.

  2. Откройте решениеClassLibraryProjects, созданное при работе со статьей Создание библиотеки классов .NET в Visual Studio Code.

  3. Создайте проект модульного теста с именем StringLibraryTest.

    dotnet new mstest -f net6.0 -o StringLibraryTest
    

    Команда -f net6.0 изменяет целевую платформу по умолчанию на net6.0 версию.

    Команда -o или --output задает расположение для размещения созданных выходных данных.

    Шаблон проекта создает файл UnitTest1.cs со следующим кодом:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    
    namespace StringLibraryTest
    {
        [TestClass]
        public class UnitTest1
        {
            [TestMethod]
            public void TestMethod1()
            {
            }
        }
    }
    

    Исходный код, созданный шаблоном модульного теста, выполняет следующие действия.

    • Он импортирует пространство имен Microsoft.VisualStudio.TestTools.UnitTesting, которое содержит типы, используемые для модульного тестирования.
    • Он применяет атрибут TestClassAttribute к классу UnitTest1.
    • Он применяет атрибут TestMethodAttribute для определения TestMethod1.

    При вызове модульного теста автоматически выполняются все методы теста, помеченные атрибутом [TestMethod], в тестовом классе, помеченном атрибутом [TestClass].

  4. Добавьте тестовый проект в решение.

    dotnet sln add StringLibraryTest/StringLibraryTest.csproj
    

Добавление ссылки на проект

Чтобы тестовый проект работал с классом StringLibrary, добавьте в проект StringLibraryTest ссылку на проект StringLibrary.

  1. Выполните следующую команду:

    dotnet add StringLibraryTest/StringLibraryTest.csproj reference StringLibrary/StringLibrary.csproj
    

Добавление и выполнение методов модульного теста

При вызове модульного теста Visual Studio запускает каждый метод, помеченный TestMethodAttribute атрибутом в классе, помеченном атрибутом TestClassAttribute . Метод теста завершается, когда происходит первый сбой или когда все тесты, содержащиеся в методе, будут успешно выполнены.

В самых распространенных тестах вызываются члены класса Assert. Многие методы утверждения (Assert) принимают по крайней мере два параметра, из которых один представляет ожидаемый результат теста, а второй — фактический результат теста. Наиболее популярные из этих методов класса Assert перечислены в следующей таблице:

Методы утверждения Функция
Assert.AreEqual Проверяет равенство двух значений или объектов. Утверждение не выполняется, если значения или объекты не равны.
Assert.AreSame Проверяет, что две объектные переменные ссылаются на один и тот же объект. Утверждение не выполняется, если переменные ссылаются на разные объекты.
Assert.IsFalse Проверяет, что условие имеет значение false. Утверждение не выполняется, если условие имеет значение true.
Assert.IsNotNull Проверяет, что объект не имеет значение null. Утверждение не выполняется, если объект является null.

Вы можете также использовать метод Assert.ThrowsException в методе теста, чтобы указать тип исключения, которое он должен создавать. Такой тест считается не выполненным, если заявленное исключение не было создано.

Для тестирования метода StringLibrary.StartsWithUpper необходимо предоставить несколько строк, которые начинаются с символов верхнего регистра. Предполагается, что в этих случаях метод возвратит true, поэтому можно вызвать метод Assert.IsTrue. Представьте также несколько строк, которые не начинаются с символов верхнего регистра. Предполагается, что в этих случаях метод возвратит false, поэтому можно вызвать метод Assert.IsFalse.

Так как метод библиотеки обрабатывает строки, необходимо также убедиться, что он обрабатывает пустую строку (String.Empty), а также строку null. Пустая строка не содержит символов, а ее свойство Length равно 0. Строка null является неинициализированной строкой. Метод StartsWithUpper можно вызвать напрямую как статический метод и передать ему один аргумент типа String. Или метод StartsWithUpper можно вызвать как метод расширения для переменной string, которой назначено значение null.

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

Создание методов теста:

  1. Откройте файл StringLibraryTest/UnitTest1.cs и замените все его содержимое следующим кодом:

    using Microsoft.VisualStudio.TestTools.UnitTesting;
    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));
            }
        }
    }
    

    Тест на символы верхнего регистра в методе TestStartsWithUpper включает заглавную греческую букву "альфа" (U+0391) и заглавную кириллическую букву "М" (U+041C). Тест на символы нижнего регистра в методе TestDoesNotStartWithUpper включает строчную греческую букву "альфа" (U+03B1) и строчную кириллическую букву "г" (U+0433).

  2. Сохранение изменений.

  3. Запустите тесты.

    dotnet test StringLibraryTest/StringLibraryTest.csproj
    

    В выходных данных терминала показано, что все тесты пройдены.

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
    
    Passed!  - Failed:     0, Passed:     3, Skipped:     0, Total:     3, Duration: 3 ms - StringLibraryTest.dll (net6.0)
    

Обработка сбоев теста

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

  1. Измените массив words в методе TestDoesNotStartWithUpper, включив в него строку "Error".

    string[] words = { "alphabet", "Error", "zebra", "abc", "αυτοκινητοβιομηχανία", "государство",
                       "1234", ".", ";", " " };
    
  2. Запустите тесты.

    dotnet test StringLibraryTest/StringLibraryTest.csproj
    

    Выходные данные терминала показывают, что один тест завершается ошибкой, и он предоставляет сообщение об ошибке для неудачного теста: "Assert.IsFalse не удалось. Expected for 'Error': false; actual: True". Из-за этого сбоя строки в массиве, расположенные после слова "Error", не проверялись.

    Starting test execution, please wait...
    A total of 1 test files matched the specified pattern.
      Failed TestDoesNotStartWithUpper [28 ms]
      Error Message:
       Assert.IsFalse failed. Expected for 'Error': false; Actual: True
      Stack Trace:
         at StringLibraryTest.UnitTest1.TestDoesNotStartWithUpper() in C:\ClassLibraryProjects\StringLibraryTest\UnitTest1.cs:line 33
    
    Failed!  - Failed:     1, Passed:     2, Skipped:     0, Total:     3, Duration: 31 ms - StringLibraryTest.dll (net5.0)
    
  3. Удалите строку "Error", которую вы добавили на шаге 1. Еще раз запустите тест. Теперь тесты будут пройдены.

Тестирование версии выпуска для библиотеки

Теперь, когда все тесты пройдены при выполнении сборки в режиме отладки, следует запустить все тесты еще раз, теперь уже для сборки библиотеки в режиме выпуска. Некоторые факторы, например оптимизации компилятора, иногда могут вызывать разное поведение сборки в режимах отладки и выпуска.

  1. Запустите тесты с конфигурацией сборки "Выпуск".

    dotnet test StringLibraryTest/StringLibraryTest.csproj --configuration Release
    

    Все тесты будут пройдены.

Отладка тестов

Если в качестве IDE вы используете Visual Studio Code, то можете следовать инструкциям из руководства по отладке консольного приложения .NET с помощью Visual Studio Code, чтобы выполнить отладку кода с применением проекта модульного теста. Вместо запуска проекта приложения ShowCase откройте StringLibraryTest/UnitTest1.cs и выберите Debug All Tests (Выполнить отладку всех тестов) между строками 7 и 8. Если вы не можете найти его, нажмите клавиши CTRL+SHIFT+P, чтобы открыть палитру команд, и введите команду перезагрузки окна.

Visual Studio Code запускает тестовый проект с присоединенным отладчиком. Выполнение будет прервано в любой точке останова, добавленной в тестовый проект или базовый код библиотеки.

Дополнительные ресурсы

Следующие шаги

В этом руководстве вы выполнили модульное тестирование библиотеки классов. Чтобы сделать библиотеку доступной другим пользователям, опубликуйте ее в NuGet в качестве пакета. Чтобы узнать, как это делать, следуйте указаниям в руководстве по NuGet:

Если библиотека опубликована как пакет NuGet, ее могут устанавливать и использовать другие пользователи. Чтобы узнать, как это делать, следуйте указаниям в руководстве по NuGet:

Библиотеку не нужно распространять как пакет. Ее можно объединить с консольным приложением, где она используется. Чтобы узнать, как опубликовать консольное приложение, ознакомьтесь с предыдущим руководством в этой серии: