Пошаговое руководство. Создание и запуск модульных тестов для приложений UWP
В этой статье объясняется, как выполнять модульное тестирование приложений универсальной платформы Windows (UWP) в Visual Studio. Visual Studio предлагает шаблоны проектов модульных тестов UWP для C#, Visual Basic и C++. Дополнительные сведения см. в статье Начало работы с приложениями UWP.
В этой статье рассматривается пример создания и модульного тестирования класса C# в приложении UWP. В этом примере используется подход разработки на основе тестирования. Он позволяет создавать тесты для проверки конкретного поведения, а затем писать код, успешно проходящий тесты.
Создание и запуск проекта модульного теста
Далее приведены процедуры создания и запуска проектов модульных тестов для приложений UWP.
Создание проекта модульного теста UWP
В начальном окне Visual Studio выберите команду Создать проект.
На странице Создание проекта в поле поиска введите фразу модульный тест. В списке шаблонов выполняется фильтрация по проектам модульного тестирования.
Выберите шаблон Приложение модульного тестирования (универсальное приложение Windows) для C# или Visual Basic, а затем выберите Далее.
При необходимости измените имя и расположение проекта или решения, а затем выберите Создать.
При необходимости измените целевую и минимальную версии платформы, а затем нажмите кнопку OK.
Visual Studio создаст тестовый проект и откроет его в Обозревателе решений Visual Studio.
В начальном окне Visual Studio выберите команду Создать проект.
На странице Создание проекта в поле поиска введите фразу модульный тест. В списке шаблонов выполняется фильтрация по проектам модульного тестирования.
Выберите шаблон Приложение модульного тестирования (универсальное приложение Windows) для C# или Visual Basic, а затем выберите Далее.
При необходимости измените имя и расположение проекта или решения, а затем выберите Создать.
При необходимости измените целевую и минимальную версии платформы, а затем нажмите кнопку OK.
Visual Studio создаст тестовый проект и откроет его в Обозревателе решений Visual Studio.
Изменение манифеста приложения проекта
В Обозревателе решений щелкните правой кнопкой мыши файл Package.appxmanifest и выберите пункт Открыть.
В конструкторе манифеста выберите вкладку Возможности.
В списке Возможности выберите возможности, необходимые для кода и модульного теста. Например, если вашему коду и его модульному тесту требуется доступ к Интернету, установите флажок Интернет.
Выберите только те возможности, которые необходимы для правильной работы модульного теста.
Добавление кода в модульный тест для приложения UWP
В редакторе кода Visual Studio измените файл кода модульного теста, чтобы добавить утверждения и логику, необходимые для тестов. Примеры см. в разделе Модульное тестирование класса C# далее в этой статье.
Запуск модульного теста с помощью Обозревателя тестов
Выполните сборку решения и запустите модульный тест с помощью Обозревателя тестов.
В меню Visual Studio Тест выберите элемент Обозреватель тестов. Откроется окно Обозреватель тестов.
В Обозревателе тестов выберите значок Запустить все. Команда Запустить все используется для обнаружения тестов в проектах UWP.
Выполняется сборка решения и запускается тест. После запуска тест отображается в списке тестов Обозревателя тестов со сведениями о результатах и длительности.
Кроме того, в Обозревателе тестов вы можете выбрать отдельные тесты и щелкнуть правой кнопкой мыши для запуска либо отладки тестов или воспользоваться командой Перейти к тесту, чтобы открыть код теста. В верхнем меню можно группировать тесты, добавлять их в списки воспроизведения или открывать параметры тестов.
Выполните сборку решения и запустите модульный тест с помощью Обозревателя тестов.
В меню Visual Studio Тест выберите элемент Обозреватель тестов. Откроется окно Обозреватель тестов.
В Обозревателе тестов выберите значок Запустить все. Команда Запустить все используется для обнаружения тестов в проектах UWP.
Выполняется сборка решения и запускается тест. После запуска тест отображается в списке тестов Обозревателя тестов со сведениями о результатах и длительности.
Кроме того, в Обозревателе тестов вы можете выбрать отдельные тесты и щелкнуть правой кнопкой мыши для запуска либо отладки тестов или воспользоваться командой Перейти к тесту, чтобы открыть код теста. В верхнем меню можно группировать тесты, добавлять их в списки воспроизведения или открывать для теста раздел Параметры.
Модульное тестирование класса C#
Стабильный набор хороших модульных тестов повышает уверенность в том, что изменение кода не привело к появлению ошибок. В следующем примере рассматривается один из способов создания модульных тестов для класса C# в приложении UWP. В этом примере используется подход разработки на основе тестирования. Он позволяет создавать тесты для проверки конкретного поведения, а затем писать код, успешно проходящий тесты.
В примере проекта кода Maths класс Rooter реализует функцию, которая вычисляет предполагаемый квадратный корень числа. Проект RooterTests выполняет модульное тестирование класса Rooter.
Создание решения и проектов
Создание проекта приложения UWP:
- В Visual Studio в меню Файл выберите элемент Новый проект.
- На странице Создание проекта в поле поиска введите фразу пустое приложение, а затем выберите шаблон проекта C# Пустое приложение (универсальное приложение для Windows).
- На странице Настроить новый проект укажите имя проекта Maths. Затем выберите команду Создать.
- При необходимости измените целевую и минимальную версии платформы, а затем нажмите кнопку OK. Visual Studio создаст проект и откроет его в Обозревателе решений.
Создание проекта модульного теста:
- В Обозревателе решений щелкните решение Maths правой кнопкой мыши и выберите пункты Добавить>Новый проект.
- На странице Добавление нового проекта в поле поиска введите фразу модульный тест, а затем выберите шаблон проекта C# Приложение модульного тестирования (универсальное приложение Windows).
- Задайте для тестового проекта имя RooterTests и выберите команду Создать.
- При необходимости измените целевую и минимальную версии платформы, а затем нажмите кнопку OK. Проект с именем RooterTests появится под решением Maths в Обозревателе решений.
Проверка с помощью Обозревателя тестов, что тесты запускаются
Класс Assert содержит несколько статических методов, которые можно использовать для проверки результатов в тестовых методах.
В Обозревателе решений выберите файл UnitTest.cs в проекте RooterTests.
Вставьте в
TestMethod1
следующий код:[TestMethod] public void TestMethod1() { Assert.AreEqual(0, 0); }
В разделе Обозреватель тестов выберите команду Запустить все тесты.
Будет выполнена сборка и запуск тестового проекта, и тест появится в разделе Пройденные тесты. В области Сводка по группе справа содержатся сведения о тесте.
Добавление класса в проект приложения
В Обозревателе решений щелкните правой кнопкой мыши проект Maths и выберите элементы Добавить>Класс.
Присвойте файлу класса имя Rooter.cs, а затем нажмите кнопку Добавить.
В редакторе кода добавьте следующий код в класс
Rooter
в файле Rooter.cs:public Rooter() { } // estimate the square root of a number public double SquareRoot(double x) { return 0.0; }
Класс
Rooter
объявляет конструктор и метод оценкиSquareRoot
. МетодSquareRoot
— это минимальная реализация для проверки базовой настройки тестирования.Измените ключевое слово
internal
вpublic
в объявлении классаRooter
, чтобы код теста мог получить к нему доступ.public class Rooter
В Обозревателе решений щелкните правой кнопкой мыши проект Maths и выберите элементы Добавить>Класс.
Присвойте файлу класса имя Rooter.cs, а затем нажмите кнопку Добавить.
В редакторе кода добавьте следующий код в класс
Rooter
в файле Rooter.cs:public Rooter() { } // estimate the square root of a number public double SquareRoot(double x) { return 0.0; }
Класс
Rooter
объявляет конструктор и метод оценкиSquareRoot
. МетодSquareRoot
— это минимальная реализация для проверки базовой настройки тестирования.Добавьте ключевое слово
public
в объявление классаRooter
, чтобы код теста мог получить к нему доступ.public class Rooter
Добавление ссылки из тестового проекта в проект приложения
В Обозревателе решений щелкните правой кнопкой мыши проект RooterTests и выберите элементы Добавить>Ссылка.
В диалоговом окне Диспетчер ссылок — RooterTests разверните узел Проекты и выберите проект Maths.
Нажмите ОК.
Добавьте следующую инструкцию
using
в UnitTest.cs после строкиusing Microsoft.VisualStudio.TestTools.UnitTesting;
:using Maths;
В Обозревателе решений щелкните правой кнопкой мыши проект RooterTests и выберите элементы Добавить>Ссылка.
В диалоговом окне Диспетчер ссылок — RooterTests разверните узел Проекты и выберите проект Maths.
Нажмите ОК.
Добавьте следующую инструкцию
using
в UnitTest.cs после строкиusing Microsoft.VisualStudio.TestTools.UnitTesting;
:using Maths;
Добавление теста, использующего функцию приложения
Добавьте в UnitTest.cs следующий метод теста:
[TestMethod] public void BasicTest() { Maths.Rooter rooter = new Rooter(); double expected = 0.0; double actual = rooter.SquareRoot(expected * expected); double tolerance = .001; Assert.AreEqual(expected, actual, tolerance); }
В Обозревателе решений в узле Незапускавшиеся тесты в Обозревателе тестов появится новый тест.
Чтобы избежать ошибки, когда полезная нагрузка содержит два или больше файлов с одним и тем же путем назначения, в Обозревателе решений разверните узел Свойства в проекте Maths и удалите файл Default.rd.xml.
Сохраните все файлы.
Запуск тестов
В Обозревателе тестов выберите значок Запустить все тесты. Будет выполнена сборка решения, а также запущены и успешно пройдены тесты.
В Обозревателе тестов выберите значок Запустить все тесты. Будет выполнена сборка решения, а также запущены и успешно пройдены тесты.
Если при запуске теста возникает ошибка повторяющейся сущности, удалите файл директив среды выполнения из Properties\Default.rd.xml
тестового проекта и повторите попытку.
Вы настроили проекты тестов и приложений и убедились, что можно выполнять тесты, вызывающие функции в проекте приложения. Теперь вы можете писать реальные тесты и код.
Добавление тестов и их передача
Не рекомендуется изменять пройденные тесты. Вместо этого добавьте новые тесты. Пишите код, добавляя тесты по одному, и после каждой итерации проверяйте, пройдены ли все тесты.
Добавьте в UnitTest.cs новый тест с именем
RangeTest
:[TestMethod] public void RangeTest() { Rooter rooter = new Rooter(); for (double v = 1e-6; v < 1e6; v = v * 3.2) { double expected = v; double actual = rooter.SquareRoot(v*v); double tolerance = expected/1000; Assert.AreEqual(expected, actual, tolerance); } }
Запустите тест RangeTest и убедитесь, что он завершается сбоем.
Совет
При разработке на основе тестов тест запускается сразу же после его написания. Такой подход поможет избежать распространенной ошибки, заключающейся в написании теста, который никогда не завершается сбоем.
Исправьте код приложения, чтобы новый тест был успешно пройден. В файле Rooter.cs измените функцию
SquareRoot
следующим образом:public double SquareRoot(double x) { double estimate = x; double diff = x; while (diff > estimate / 1000) { double previousEstimate = estimate; estimate = estimate - (estimate * estimate - x) / (2 * estimate); diff = Math.Abs(previousEstimate - estimate); } return estimate; }
В Обозревателе тестов выберите значок Запустить все тесты. Теперь все три теста проходятся.
Добавьте в UnitTest.cs новый тест с именем
RangeTest
:[TestMethod] public void RangeTest() { Rooter rooter = new Rooter(); for (double v = 1e-6; v < 1e6; v = v * 3.2) { double expected = v; double actual = rooter.SquareRoot(v*v); double tolerance = expected/1000; Assert.AreEqual(expected, actual, tolerance); } }
Запустите тест RangeTest и убедитесь, что он завершается сбоем.
Совет
При разработке на основе тестов тест запускается сразу же после его написания. Такой подход поможет избежать распространенной ошибки, заключающейся в написании теста, который никогда не завершается сбоем.
Исправьте код приложения, чтобы новый тест был успешно пройден. В файле Rooter.cs измените функцию
SquareRoot
следующим образом:public double SquareRoot(double x) { double estimate = x; double diff = x; while (diff > estimate / 1000) { double previousEstimate = estimate; estimate = estimate - (estimate * estimate - x) / (2 * estimate); diff = Math.Abs(previousEstimate - estimate); } return estimate; }
В Обозревателе тестов выберите значок Запустить все тесты. Теперь все три теста проходятся.
Рефакторинг кода
В этом разделе вы выполните рефакторинг кода приложения и теста, а затем повторно запустите тесты, чтобы убедиться, что они выполняются успешно.
Упрощение оценки квадратного корня
В Rooter.cs упростите центральное вычисление в функции
SquareRoot
. Для этого измените следующую строку:estimate = estimate - (estimate * estimate - x) / (2 * estimate);
По
estimate = (estimate + x/estimate) / 2.0;
Запустите все тесты, чтобы убедиться, что не введена регрессия. Все тесты должны пройти успешно.
Удаление дублирующегося кода теста
В методе RangeTest
жестко задан знаменатель переменной tolerance
, которая передается в метод Assert. Если вы планируете добавлять другие тесты, которые используют такой же расчет отклонения, использование жестко запрограммированных значений в нескольких местах может усложнить работу с кодом. Вместо этого вы можете добавить в класс UnitTest1
закрытый вспомогательный метод для вычисления значения отклонения, а затем вызвать этот метод из RangeTest
.
Чтобы добавить вспомогательный метод, в UnitTest.cs сделайте следующее:
Добавьте приведенный ниже метод в класс
UnitTest1
:private double ToleranceHelper(double expected) { return expected / 1000; }
В
RangeTest
измените следующую строку:double tolerance = expected/1000;
По
double tolerance = ToleranceHelper(expected);
Запустите тест RangeTest, чтобы убедиться, что он все еще успешно выполняется.
Совет
Если вы добавляете вспомогательный метод в тестовый класс и не хотите, чтобы этот метод отображался в Обозревателе тестов, не добавляйте к методу атрибут TestMethodAttribute.
Следующие шаги
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по