🧪 Что такое тестирование
Тестирование — это процесс проверки, что приложение работает правильно и надёжно. В .NET/C# чаще всего используют фреймворки:
xUnit
— современный и лёгкий (рекомендуется Microsoft)NUnit
— старше, с богатой экосистемойMSTest
— встроен в Visual Studio
🧱 Виды тестирования
Вид | Что проверяет | Примеры |
---|---|---|
✅ Unit-тесты | Маленькие блоки (классы, методы) | MathService.Add(2, 2) → 4 |
🔗 Integration-тесты | Взаимодействие компонентов | UserController + UserService + DB |
🌐 End-to-End (E2E) | Всё приложение от начала до конца | Тест реального HTTP-запроса к API |
🔍 Smoke / Sanity | Базовые проверки, «не упал ли билд» | Проверка, что API отвечает 200 OK |
🧪 UI-тесты | Интерфейс, поведение в браузере | Selenium, Playwright |
🧰 Библиотеки в C# для тестирования
Задача | Инструмент |
---|---|
Тест-фреймворк | xUnit , NUnit , MSTest |
Моки/заглушки | Moq , NSubstitute |
Проверки (assert ) |
FluentAssertions |
Тесты контроллеров | Microsoft.AspNetCore.Mvc.Testing |
Интеграция с Allure | Allure.Commons |
🧪 Пример простого Unit-теста (xUnit
)
public class MathService
{
public int Add(int a, int b) => a + b;
}
public class MathServiceTests
{
[Fact]
public void Add_ReturnsSum()
{
var service = new MathService();
var result = service.Add(2, 3);
Assert.Equal(5, result);
}
}
🧱 Паттерны тестирования
Это структурированные подходы к организации тестов: чтобы они были понятны, надёжны и покрывали важное.
1. AAA — Arrange, Act, Assert
Самый популярный шаблон для юнит-тестов.
[Fact]
public void Subtract_ReturnsCorrectResult()
{
// Arrange
var calc = new Calculator();
// Act
var result = calc.Subtract(10, 4);
// Assert
Assert.Equal(6, result);
}
- Arrange — подготовка (объекты, моки)
- Act — вызов метода
- Assert — проверка результата
2. BDD — Behavior-Driven Development
Фокус на поведение, а не реализацию. Используются библиотеки вроде SpecFlow.
[Theory]
[InlineData(5, true)]
[InlineData(-3, false)]
public void IsPositive_ReturnsCorrectResult(int number, bool expected)
{
var service = new MathService();
var result = service.IsPositive(number);
result.Should().Be(expected); // FluentAssertions
}
BDD: Given
, When
, Then
(можно прямо использовать с Gherkin-сценариями).
3. TDD — Test-Driven Development
Цикл "красный–зелёный–рефакторинг":
- ✍ Написать тест → ❌ (он не скомпилируется или упадёт)
- 🟢 Реализовать минимум, чтобы тест прошёл
- 🧹 Рефакторинг
Пример:
[Fact]
public void ShouldReturnTrueIfEven()
{
var logic = new MathLogic();
Assert.True(logic.IsEven(2));
}
Затем создаём метод IsEven
и пишем реализацию под тест.
4. Fixture / Setup
Позволяет повторно использовать подготовку:
public class MyFixture
{
public MyService Service { get; }
public MyFixture()
{
Service = new MyService();
}
}
public class MyServiceTests : IClassFixture<MyFixture>
{
private readonly MyFixture _fixture;
public MyServiceTests(MyFixture fixture)
{
_fixture = fixture;
}
[Fact]
public void Test()
{
var result = _fixture.Service.DoSomething();
Assert.True(result);
}
}
5. Mocks, Stubs, Fakes
- Stub — возвращает фиксированные данные
- Mock — проверяет, вызывался ли метод (с Moq)
- Fake — простая, но рабочая реализация (в отличие от stub)
Пример с Moq
:
var repo = new Mock<IUserRepository>();
repo.Setup(x => x.GetUser(1)).Returns(new User("Anton"));
var service = new UserService(repo.Object);
var user = service.GetUser(1);
Assert.Equal("Anton", user.Name);
6. Test Pyramid
📶 Правильное распределение тестов:
🧪 E2E (мало, дорогие)
🔗 Интеграционные (средне)
✅ Юнит-тесты (много и быстрые)
7. Code Coverage
Показывает, насколько ваш код покрыт тестами.
Инструменты:
coverlet
+reportgenerator
- Visual Studio встроенный анализ
- JetBrains dotCover
📦 Пример структуры тестов в проекте
MyApp/
└── MyApp.csproj
└── Program.cs
└── Services/
Tests/
└── MyApp.Tests.csproj
└── Services/
└── MathServiceTests.cs
🚀 Советы по тестированию
✅ Пиши тесты сразу (TDD или сразу после написания метода)
✅ Используй паттерн AAA
✅ Делай тесты независимыми
✅ Не бойся моков и фикстур
🚫 Не пиши логику в тестах
🚫 Не тестируй ToString()
или геттеры, если в них нет логики