Никипелов_А.В.md 13 KB

Модульное тестирование с использованием C# и .NET

Модульное тестирование - это процесс проверки корректности отдельных блоков кода, обычно методов или функций, изолированно от остальной системы. Это гарантирует, что каждый модуль работает должным образом, и помогает выявлять потенциальные ошибки или проблемы на ранних стадиях процесса разработки.

Важность модульного тестирования в разработке программного обеспечения

Модульное тестирование - важнейшая практика в современной разработке программного обеспечения. Его важность трудно переоценить, поскольку оно:

  • Обеспечивает функциональность: проверяет, что каждая единица кода работает должным образом, избегая ошибок и других проблем.
  • Повышает удобство сопровождения: хорошо написанные тесты служат страховочной сеткой, позволяя разработчикам уверенно проводить рефакторинг или изменять код.
  • Улучшает качество кода: это поощряет лучшие практики, такие как принципы SOLID, и помогает разработчикам лучше писать более тестируемый код.
  • Ускоряет разработку: раннее и частое тестирование позволяет разработчикам быстрее обнаруживать и устранять проблемы, сокращая общее время, затрачиваемое на отладку.
  • Облегчает совместную работу: общие наборы тестов дают разработчикам общее понимание кода и обеспечивают бесперебойную совместную работу и улучшение коммуникации.

Среда модульного тестирования C# и .NET: фреймворки и инструменты тестирования

Для модульного тестирования на C # и .NET доступно несколько фреймворков и инструментов, но наиболее популярными из них являются:

  • xUnit: современная расширяемая платформа тестирования, ориентированная на простоту и удобство использования. Ее часто считают фактическим выбором для модульного тестирования в .NET Core.
  • NUnit: Широко используемый, хорошо зарекомендовавший себя фреймворк тестирования с богатым набором функций и обширной экосистемой плагинов. Он имеет долгую историю, и его используют многие устаревшие проекты .NET.
  • MSTest: платформа тестирования по умолчанию, предоставляемая пакетом Microsoft Visual Studio Suite, обеспечивающая тесную интеграцию с Visual Studio и поддерживаемая службой поддержки Microsoft.
  • Moq: мощная библиотека макетов, специально разработанная для .NET, позволяющая разработчикам создавать макетные объекты для изолированного тестирования модулей, взаимодействующих с внешними зависимостями.

Начало работы с xUnit: современная платформа тестирования для C

Почему стоит выбрать xUnit вместо других фреймворков тестирования?

xUnit стал предпочтительным выбором в сообществе .NET по нескольким причинам:

  1. Современность: Оно было разработано специально для .NET Core, привнося в таблицу современный подход и новые функции.
  2. Простота: xUnit подчеркивает простоту, что упрощает его изучение и использование даже новичками в модульном тестировании.
  3. Расширяемость: xUnit предоставляет множество возможностей расширения, таких как его атрибуты, утверждения и соглашения, позволяя разработчикам адаптировать его к своим потребностям.
  4. Сильная поддержка сообщества: Благодаря широкому внедрению в .Net xUnit располагает множеством ресурсов, документации и ответов на распространенные вопросы.
  5. Интеграция: Он может похвастаться интеграцией с популярными инструментами, такими как Visual Studio, VSCode, ReSharper и .NET CLI, что упрощает процесс тестирования.

Установка и настройка xUnit на примере Visual Studio

  1. Запустите Visual Studio. В разделе "Get Started" нажмите "Create a new project". Это приведет вас к выбору типа проекта.
  2. В раскрывающихся списках выберите свой язык (C #), свою платформу (All platforms) и тип вашего проекта (Test). При необходимости прокрутите список, пока не найдете пункт с названием "xUnit Test Project (.NET Core)". Выберите его, затем нажмите "Next".
  3. Введите имя в поле "Название проекта" (например, "MyFirstUnitTests"). Нажмите "Create". Через некоторое время Visual Studio запустится с вашим только что созданным проектом.

Модульный тестовый пример C# с xUnit

Для нашего примера, у нас есть следующие реализации Add метод, внутри Calculator класс:

public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }
}

Чтобы написать модульный тест для метода Add , создайте в своем тестовом проекте новый тестовый класс с именем CalculatorTests. Внутри этого класса добавьте метод с именем Add_PositiveNumbers_ReturnsExpectedResult, оформленный атрибутом [Fact] , следующим образом:

using Xunit;
using MyProject;

public class CalculatorTests
{
    [Fact]
    public void Add_PositiveNumbers_ReturnsExpectedResult()
    {
        // Arrange
        var calculator = new Calculator();
        int a = 3;
        int b = 5;
        int expectedResult = 8;

        // Act
        int actualResult = calculator.Add(a, b);

        // Assert
        Assert.Equal(expectedResult, actualResult);
    }
}

Для запуска тестирования воспользуемся окном "Test Explorer" Нажмите крайнюю левую кнопку на панели инструментов Test Explorer (она выглядит как двойная зеленая стрелка)

Написание эффективных и сопровождаемых модульных тестов C Sharp

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

Шаблон хорошо структурированного теста

Хороший модульный тест следует шаблону “Упорядочивать, действовать, утверждать", который делает код простым, понятный и поддерживаемый.

  1. Порядок действий: Настройте тестовую среду и создайте экземпляр тестируемой системы или ее зависимостей. С практической точки зрения это может означать создание макетных объектов, настройку обработчиков исключений или инициализацию состояния.
  2. Действие: Вызовите целевой метод, используя подготовленную среду.
  3. Утверждение: Проверьте, соответствует ли ожидаемый результат фактическому результату. Если нет, тест завершается неудачно. Старайтесь, чтобы количество утверждений равнялось одному для каждого теста.

Применяет принципы SOLID при разработке тестов

Принципы SOLID – это стандарты объектно-ориентированного программирования, которые нужны для построения хорошей архитектуры программы.

Чтобы модульные тесты оставались управляемыми, ремонтопригодными и простыми для понимания, они должны соответствовать принципам SOLID, как и производственный код:

  • Принцип единой ответственности (SRP): Каждый тест должен быть сосредоточен на одном конкретном модуле или поведении. Избегайте смешивания нескольких утверждений в одном тесте, что упрощает понимание и устранение неполадок.
  • Принцип открытости / закрытости (OCP): Убедитесь, что тесты открыты для расширения, это означает, что добавление новых тестовых примеров не требует модификации существующих.
  • Принцип замены Лискова (LSP): При использовании тестового наследования или совместно используемых приспособлений убедитесь, что базовые классы или приспособления заменяются производными типами без ущерба для целостности теста.
  • Принцип разделения интерфейсов (ISP): Если для теста требуется определенный интерфейс, он должен зависеть исключительно от этого интерфейса, а не от более крупного и сложного. Это помогает сузить зависимости и область применения теста.
  • Принцип инверсии зависимостей (DIP): Зависит от абстракций, а не от конкретных реализаций. В тестах это означает использование макетных фреймворков, таких как Moq, для изоляции тестов от реальной реализации зависимостей.

Литература:

https://xunit.net/docs/getting-started/netfx/visual-studio

https://dev.to/bytehide/unit-testing-with-c-and-net-full-guide-5c7p