Модульные тесты Visual Studio и клиент-серверные программы

#c# #visual-studio #unit-testing #client-server

#c# #visual-studio #модульное тестирование #клиент-сервер

Вопрос:

У меня есть решение, которое является клиент-сервером. Клиент и сервер — это проекты в одном решении.

Я хочу провести модульное тестирование клиента, для чего, очевидно, требуется, чтобы сервер был запущен. Есть ли какой-либо способ указать в проекте модульного тестирования, что серверный проект должен быть запущен перед выполнением определенного модульного теста? Полагаю, я мог бы явно запустить программу, но я предпочел бы, чтобы инфраструктура тестирования сделала это за меня.

Я полагаю, что это довольно распространенное требование. Как люди обычно подходят к этому? (VS2010, C #, если это имеет значение.)

Комментарии:

1. Как писал maple_shaft: это, вероятно, не лучший способ модульного тестирования. Если вы ищете интеграционный тест, вы можете использовать атрибут TestInitialize для каждого запуска сервера / клиента в «нейтральное» состояние тестирования.

Ответ №1:

Точка зрения педанта: если сервер необходим, это не модульный тест — это интеграционный тест. Однако это не отменяет реальной необходимости это делать 🙂

Когда мне это нужно, я проектирую сервер как нечто, что я могу развернуть из нескольких классов где угодно (чем проще, тем лучше); затем вы можете запустить сервер в нескольких классах из набора тестов (и завершить работу). Тогда серверное «приложение» — это просто тонкая оболочка вокруг того же набора классов.

Конечно, это зависит от того, что вы делаете.

Ответ №2:

Лучший подход к этому — фактически написать РЕАЛЬНЫЕ модульные тесты. То, что вы запускаете сейчас, считается интеграционным тестом.

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

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

Комментарии:

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

2. Хорошая мысль, Марк, на этой заметке я, вероятно, недостаточно эффективно ответил на вопрос OP.

Ответ №3:

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

Запуск / остановка TestRun

В MSTest вы можете выполнить обычную инициализацию установки перед запуском любого теста, используя атрибут AssemblyInitializeAttribute. Обратите внимание, что методы должны быть статическими.

 [TestClass]
public class AssemblyTestHarness
{
    [AssemblyInitialize]
    public static void InitializeAssembly(TestContext context)
    {
        // start process here
    }

    [AssemblyCleanup]
    public static void CleanupAssembly(TestContext context)
    {
        // clean-up process here
    }
}
  

Запуск / остановка тестового устройства

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

 [TestClass]
public class MyTestFixture
{
    [ClassInitialize]
    public static void InitializeFixture(TestContext context)
    {
        // start process here
    }

    [ClassCleanup]
    public static void CleanupFixture(TestContext context)
    {
        // clean-up process here
    }
}
  

Ответ №4:

Не обязательно, чтобы сервер был запущен. На самом деле, вероятно, лучше НЕ запускать его (в конечном итоге вы будете тестировать сеть, а также свое приложение).

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

Ответ №5:

нет. это не модульное тестирование. вы не должны тестировать клиент-сервер с помощью модульных тестов. Для этого вам нужно смоделировать то, что сервер возвращает в ваших модульных тестах. Это способ «модульного тестирования» вашего клиент-серверного кода.

Ответ №6:

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