XUnit - InvalidOperationException: корень решения не может быть найден с использованием корня приложения
У меня есть проект Web-API .NET Core 2.2, и я пытаюсь провести интеграционные тесты на нем.
Я следовал руководству от Microsoft. Тесты проходят при запуске их из тестового прогона и из командной строки, они должны быть правильно настроены, я могу вызывать контроллеры через WebApplicationFactory - HTTP-клиент. Я отключил теневое копирование через xunit.runner.json Пока все хорошо.
Я пытаюсь использовать Azure DevOps для развертывания моего проекта, и на этапе выпуска я добавил шаг теста, который берет артефакт сборки, загружает его и запускает тест. В основном, реплицируется на локальном компьютере, это будет переводиться в:
dotnet publish testProject.csproj <path_on_disk>
cd <path_on_disk>
vstest.console.exe testProject.dll
При запуске тестов из опубликованной папки я получаю следующую ошибку
Failed wInvoiceIntegrationTests.Controllers.Authentication.AuthenticationControllerTests.AuthenticationController_Register_InputDoesNotRespectsModel_DoesNotRegistersUser(email: "abcd@@.com", password: "Abcdefgh1")
Error Message:
System.InvalidOperationException : Solution root could not be located using application root C:\Users\mihai\Desktop\publish\.
Stack Trace:
at Microsoft.AspNetCore.TestHost.WebHostBuilderExtensions.UseSolutionRelativeContentRoot(IWebHostBuilder builder, String solutionRelativePath, String applicationBasePath, String solutionName)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.SetContentRoot(IWebHostBuilder builder)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.EnsureServer()
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateDefaultClient(DelegatingHandler[] handlers)
at Microsoft.AspNetCore.Mvc.Testing.WebApplicationFactory`1.CreateClient(WebApplicationFactoryClientOptions options)
У меня нет статических файлов, которые мне нужно обслуживать и которые я не хочу, я просто пытаюсь протестировать контроллер. Путь правильный, там находятся тестовые библиотеки и проектные библиотеки.
Тем временем мне удалось запустить тесты на Azure, на этапе сборки через
ls *Tests*/*.csproj | xargs -L1 dotnet test --logger:trx
Любые идеи о том, как преодолеть это и запустить тесты из папки публикации?
Редактировать: в основном запуск тестов из командной строки в выходном каталоге и из проводника тестов VS в порядке, но запуск из каталога публикации не в порядке.
3 ответа
См. Эту часть статьи https://docs.microsoft.com/en-us/aspnet/core/test/integration-tests?view=aspnetcore-2.2
Как видите, классу WebApplicationFactory необходимо определить корневой путь содержимого. WebApplicationFactory находит путь из WebApplicationFactoryContentRootAttribute, если он определен. Если этот атрибут не найден, выполняется поиск файла решения (.sln), папка, содержащая файл решения, устанавливается в качестве корневого пути содержимого. Похоже, что ни вы не определяете WebApplicationFactoryContentRootAttribute в своем тестовом проекте, ни родительский каталог каталога, содержащего опубликованные библиотеки DLL (testProject.dll), не содержит файла .sln.
В качестве обходного пути непосредственно перед запуском тестов я скопировал файл sln из своего проекта в родительскую папку папки "publish". Я думаю, что просто создание фиктивного файла sln также может помочь. Я запускаю свою тестовую команду из родительского каталога следующим образом:
dotnet test ./<publish folder>/testProject.dll
Примечание./ - это родительский каталог, в который копируется файл sln, а "папка публикации" - это "путь_на_диске" в вашем примере
В моем случае после этого появились дополнительные ошибки, показывающие отсутствующий каталог. Я только что создал пустой каталог с точным именем в родительском каталоге и исправил ошибки. Надеюсь, это тоже поможет вам.
Я получал ту же ошибку в моем тестовом проекте интеграции при использовании .NET Core 5.0. Это решение устранило для меня проблему: https://anthonygiretti.com/2021/04/16/testserver-asp-net-core-5-fix-system-invalidoperationexception-solution-root-could-not-be-located- с использованием-корневого-приложения-с-настраиваемым-запускающим-файлом /.
Конечно, сначала вам придется обновить свой проект до .NET Core 5.0.
Мы столкнулись с этой проблемой и потратили несколько часов на ее сборку. Оказывается, решения Джахана Афшари и Намика Гаджиева актуальны. Я хочу попытаться собрать их решения в одно целое.
Во-первых, ознакомьтесь со статьей, на которую ссылается Джахан, и убедитесь, что она имеет отношение к вам. Если вы используете .NET 5+, вам обязательно нужно убедиться, что ваш код инициализирует вещи так, как описано в этой статье.
Однако, если этого окажется недостаточно для решения вашей проблемы, вам нужно убедиться, что у вас все настроено так же, как это сделал Namig.
Однако оказывается, что его теория о простом создании фиктивного файла .sln неверна. Архитектура тестирования .NET не просто ищет наличие файла .sln. На самом деле он использует данные в этом файле, чтобы найти путь к проекту, содержащему код SUT за создаваемым интерфейсом имитации веб-службы.
Я загрузил и прошел код сборки .NET. Он начинается с рабочего каталога и поднимается вверх по дереву каталогов по одному родительскому каталогу, пока не найдет каталог с одним или несколькими файлами .sln. Затем он просматривает каждый из этих файлов в поисках пути к проекту с кодом SUT.
Кроме того, хотя природа кода .NET, казалось бы, указывает на то, что файл .sln просто должен находиться в пути к каталогу тестового проекта, который вы пытаетесь запустить, на самом деле он должен находиться в непосредственном родительском каталоге тестового проекта. Если он находится дальше по цепочке, вы столкнетесь с другой ошибкой, в которой он попытается сослаться на тестовый проект, как если бы он был на один каталог ниже файла решения.
Итак, суть: чтобы заставить тестовую инфраструктуру веб-службы .NET работать, ваш тестовый проект, создающий фиктивную веб-службу, должен иметь решение в своем родительском каталоге, содержащее ссылки как на тестовый проект, так и на проект SUT с кодом. позади Mock Web Service.
Чтобы убедиться, что это сработает, вы должны открыть любое другое решение, содержащее все проекты, от которых может зависеть ваш проект SUT, запустить Очистить все, затем закрыть это решение, открыть решение в родительском каталоге вашего тестового проекта и запустить Построить все из этого решения. Это гарантирует, что ваша сборка не будет успешной, потому что другие сборки, от которых она зависит, просто оказались предварительно собранными и находятся в каталоге сборки вашего тестового проекта.
Как только это решение будет готово, вы сможете создать и запустить свой тестовый проект из любого другого решения, которое вам нравится. Просто имейте в виду, что сам код тестового проекта нуждается в этом решении в своем родительском каталоге, чтобы найти и использовать код SUT.