Обзор Microsoft IntelliTest
IntelliTest позволяет находить ошибки на раннем этапе и уменьшает затраты на обслуживание тестирования. Благодаря автоматизированному и прозрачному подходу к тестированию инструмент IntelliTest позволяет сформировать набор кандидатов на тесты для кода .NET. Создание набора тестов можно дополнительно настроить с помощью задаваемых вами свойств правильности. IntelliTest даже будет автоматически модифицировать набор тестов по мере модификации тестируемого кода.
Примечание.
Инструмент IntelliTest доступен только в выпуске Enterprise. Он поддерживается только для кода C#, предназначенного для .NET Framework. Для поддержки .NET 6 в IntelliTest установите предварительную версию Visual Studio Enterprise и просмотрите объявление .
Характеристические тесты. IntelliTest позволяет определить поведение кода в рамках набора традиционных модульных тестов. Подобный набор тестов можно использовать в качестве набора регрессии, чтобы сформировать основу для преодоления сложностей, связанных с рефакторингом незнакомого кода или кода прежних версий.
Управляемое создание входных данных для теста. Инструмент IntelliTest использует открытый подход к анализу кода и поиску решений для ограничений, чтобы автоматически создавать точные входные значения для тестов, при этом вмешательство пользователя обычно не требуется. Для сложных типов объектов он автоматически создает фабрики. Вы можете управлять созданием входных данных для теста, расширяя и настраивая фабрики в соответствии с вашими требованиями. Свойства правильности, указанные как утверждения в коде, используются автоматически для дальнейшего создания входных данных теста.
Интеграция со средой IDE. Инструмент IntelliTest полностью интегрирован в среду IDE Visual Studio. Все данные, собранные во время создания набора тестов (например, автоматически созданные входные данные, выходные данные кода, созданные тестовые случаи и состояние их выполнения), отображаются в интегрированной среде разработки Visual Studio. Вы можете легко переключаться между правкой кода и повторным выполнением IntelliTest, не выходя из среды IDE Visual Studio. Тесты можно сохранить в решении в качестве проекта модульного теста и автоматически обнаруживаться после этого с помощью Visual Studio Test Обозреватель.
Дополнение существующих методик тестирования. Используйте IntelliTest в дополнение к уже имеющимся методикам тестирования.
Если вы хотите тестировать:
- Алгоритмы по примитивным данным или массивам примитивных данных:
- напишите параметризованные модульные тесты;
- Алгоритмы по сложным данным, например компилятору:
- сначала позвольте IntelliTest создать абстрактное представление данных, а затем передайте его в алгоритм;
- позвольте IntelliTest собрать экземпляры с помощью создания настраиваемых объектов и инвариантов данных, а затем вызовите этот алгоритм.
- Контейнеры данных:
- напишите параметризованные модульные тесты;
- позвольте IntelliTest собрать экземпляры с помощью создания настраиваемых объектов и инвариантов данных, а затем вызовите метод контейнера и перепроверьте инварианты;
- напишите параметризованные модульные тесты, вызывающие разные методы реализации в зависимости от значений параметров.
- Существующая база кода:
- используйте мастер IntelliTest в Visual Studio, чтобы для начала создать набор параметризованных модульных тестов (PUT).
Основы IntelliTest
Инструмент IntelliTest находит входные данные, относящиеся к тестируемой программе, поэтому его можно использовать для создания всем известной строки Hello World. Здесь предполагается, что вы создали проект тестов C# на основе MSTest и добавили ссылку на Microsoft.Pex.Framework. Если вы используете другую тестовую платформу, создайте библиотеку классов C# и обратитесь к документации по платформе тестирования о настройке проекта.
В следующем примере создаются два ограничения для именованного параметра , чтобы IntelliTest создал требуемую строку:
using System;
using Microsoft.Pex.Framework;
using Microsoft.VisualStudio.TestTools.UnitTesting;
[TestClass]
public partial class HelloWorldTest {
[PexMethod]
public void HelloWorld([PexAssumeNotNull]string value) {
if (value.StartsWith("Hello")
&& value.EndsWith("World!")
&& value.Contains(" "))
throw new Exception("found it!");
}
}
После компиляции и выполнения IntelliTest создает набор тестов, например следующего вида:
- ""
- "\0\0\0\0\0"
- "Здравствуйте"
- "\0\0\0\0\0\0"
- "Hello\0"
- "Hello\0\0"
- "Hello\0World!"
- "Hello World!"
Примечание.
При возникновении проблем со сборкой попробуйте заменить ссылки на Microsoft.VisualStudio.TestPlatform.TestFramework и Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions ссылками на Microsoft.VisualStudio.QualityTools.UnitTestFramework.
Сведения о сохранении созданных тестов см. в статье Создание модульных тестов для кода с помощью IntelliTest. Созданный тестовый код должен содержать следующий код:
[TestMethod]
[PexGeneratedBy(typeof(global::HelloWorldTest))]
[PexRaisedException(typeof(Exception))]
public void HelloWorldThrowsException167()
{
this.HelloWorld("Hello World!");
}
Все просто!
Дополнительные ресурсы:
- прочитайте этот обзор в журнале MSDN
Важные атрибуты
- PexClass помечает тип, содержащий PUT.
- PexMethod помечает PUT.
- PexAssumeNotNull помечает параметр, отличный от NULL.
using Microsoft.Pex.Framework;
[..., PexClass(typeof(Foo))]
public partial class FooTest {
[PexMethod]
public void Bar([PexAssumeNotNull]Foo target, int i) {
target.Bar(i);
}
}
- PexAssemblyUnderTest привязывает тестовый проект к проекту.
- PexInstrumentAssembly указывает сборку для инструментирования.
[assembly: PexAssemblyUnderTest("MyAssembly")] // also instruments "MyAssembly"
[assembly: PexInstrumentAssembly("Lib")]
Важные статические вспомогательные классы
- PexAssume вычисляет предположения (фильтрация ввода).
- PexAssert вычисляет утверждения.
- PexChoose создает новые варианты (дополнительные входные данные).
- PexObserve регистрирует динамические значения для созданных тестов.
[PexMethod]
void StaticHelpers(Foo target) {
PexAssume.IsNotNull(target);
int i = PexChoose.Value<int>("i");
string result = target.Bar(i);
PexObserve.ValueForViewing<string>("result", result);
PexAssert.IsNotNull(result);
}
Ограничения
Этот раздел описывает ограничения инструмента IntelliTest:
- Недетерминированность
- Параллелизм
- Машинный код .NET
- Платформа
- Язык
- Символьная аналитика
- Трассировки стека
Недетерминированность
IntelliTest предполагает, что анализируемая программа является детерминированной. Если это не так, IntelliTest циклирует, пока не достигнет границы исследования.
IntelliTest считает программу неустранимой, если она полагается на входные данные, которые IntelliTest не может контролировать.
IntelliTest управляет входными данными для параметризованных модульных тестов, полученными из PexChoose. В этом смысле результаты вызовов неуправляемого или неуправляемого кода также считаются "входными данными" в инструментированную программу, но IntelliTest не может контролировать их. Если поток управления программы зависит от определенных значений, поступающих из этих внешних источников, IntelliTest не может "управлять" программой в направлении ранее обнаруженных областей.
Кроме того, программа считается недетерминированной, если значения из внешних источников изменяются при повторном запуске программы. В таких случаях IntelliTest утрачивает контроль над выполнением программы, и поиск становится неэффективным.
Иногда это не очевидно, когда это происходит. Рассмотрим следующие примеры:
- Результат метода GetHashCode() предоставляется неуправляемым кодом и не предсказуем.
- Класс System.Random использует текущее системное время для предоставления действительно случайных значений.
- Класс System.DateTime предоставляет текущее время, которое не находится под контролем IntelliTest.
Параллелизм
IntelliTest не обрабатывает многопоточные программы.
Машинный код
IntelliTest не понимает машинный код, например инструкции x86, называемые P /Invoke. Он не способен преобразовывать такие вызовы в ограничения, которые можно передать в поиск решений для ограничений. Даже для кода .NET он способен анализировать лишь тот код, который сам инструментирует. IntelliTest не может инструментирование определенных частей mscorlib, включая библиотеку отражения. DynamicMethod нельзя инструментировать.
Предлагаемый обходной путь заключается в использовании тестового режима, при котором такие методы находятся в типах в динамической сборке. Однако даже если некоторые методы ненадежны, IntelliTest пытается покрыть максимальное количество инструментированного кода.
Платформа
IntelliTest поддерживается только на 32-разрядной платформе .NET Framework (x86).
Язык
По сути, IntelliTest способен анализировать произвольные программы .NET, написанные на любом языке .NET. Однако в Visual Studio поддерживается только C#.
Символьная аналитика
IntelliTest использует автоматический поиск решений для ограничений, чтобы определить релевантные значения для теста и тестируемой программы. Однако возможности поиска решений для ограничений были и всегда будут довольно ограничены.
Неправильные трассировки стека
Так как IntelliTest перехватывает и "повторно выполняет" исключения в каждом инструментированного метода, номера строк в трассировках стека не будут правильными. Такое ограничение изначально заложено в инструкцию повторного создания.