Resharper запускает UnitTest из другого места
Когда я запускаю модульные тесты с Visual Studio, он работает нормально, потому что он запускается из каталога проекта, где находятся все сборки. Но когда я запускаю его с Resharper, он идет с ошибкой на
var services = Assembly.Load("SomeAssembly");
с ошибкой
Не удалось загрузить файл или сборку SomeAssembly или одну из ее зависимостей. Система не может найти указанный файл..
Итак, я попробовал
var path = Assembly.GetExecutingAssembly().Location;
и это не проект один. Это
C:\Users\*UserName*\AppData\Local\Temp\TestResults\...\Out\
и нет "SomeAssembly". Как правильно настроить resharper или собрать все сборки, как это делает Visual Studio?
Это происходит с юнит-тестами, но не с NUnit, есть идеи?
10 ответов
Resharper теневые копии сборок для тестирования по умолчанию. Если вы отключите теневое копирование, оно будет запущено в папке bin, и тест должен пройти. Вот несколько инструкций по его выключению.
В документации по настройкам NUnit's Gui Test Runner есть следующее примечание о Shadow Copy
Примечание. Если вы склонны отключить теневое копирование, чтобы получить доступ к файлам в том же каталоге, что и ваша сборка, вы должны знать, что есть альтернативы. Попробуйте использовать свойство Assembly.Codebase, а не Assembly.Location.
Вот пример использования свойства Assembly.Codebase
private string AssemblyLocation()
{
var assembly = Assembly.GetExecutingAssembly();
var codebase = new Uri(assembly.CodeBase);
var path = codebase.LocalPath;
return path;
}
У меня возникла та же проблема, программа-тестировщик resharper была в C:\, тогда как фактически собранные dll и решение были на другом диске. Решение состояло в том, чтобы убрать галочку "Использовать Legacy Runner" на странице настроек MSTest в опциях перекомпоновки.
Попробуйте создать файл testsettings и настроить правила развертывания для ваших тестов.
В старых версиях resharper, похоже, есть некоторые ошибки при обработке развертывания папок, я думаю, что это исправлено в последней версии resharper 7.
Попробуйте этот код для загрузки (см. Ниже). Это будет искать сборки независимо от тестового бегуна.
private static string[] assemblyLookupPath = new[]
{
AppDomain.CurrentDomain.BaseDirectory,
Environment.CurrentDirectory,
Assembly.GetExecutingAssembly().Location
}.Distinct().ToArray();
public static void Assembly Load(string fileName)
{
var filePath = assemblyLookupPath
.Select(f=>Path.Combine(f, fileName))
.Where(File.Exists)
.FirstOrDefault();
/*do here null checks and raise errors, write logs, etc*/
return Assembly.LoadFrom(filePath )
}
Вы загружаете свои сборки динамически, используя Assembly.Load()
, Возможно, вам не хватает ссылки на сборку для загрузки. В противном случае теневое копирование может пропустить несвязанные сборки.
Если вы не хотите ссылаться на эти сборки, обязательно включите их в свой проект и скопируйте их в выходной каталог. Это можно сделать, установив свойство "Копировать в выходной каталог" или создав пользовательский шаг после сборки.
Просто чтобы завершить очень полезный ответ от mcdon
, с помощью assembly.Location
дает правильный ответ в соответствии с объяснением MSFT:
CodeBase - это URL-адрес места, где был найден файл, а Location - это путь, с которого он был фактически загружен. Например, если сборка была загружена из Интернета, ее CodeBase может начинаться с "http://", а ее местоположение может начинаться с "C:\". Если файл был скопирован теневым копированием, в качестве местоположения будет указан путь к копии файла в каталоге теневого копирования.
Также полезно знать, что CodeBase не гарантированно будет установлен для сборок в GAC. Однако для всегда загружаемых с диска сборок всегда будет указано местоположение.
Поэтому я бы использовал следующее:
public static DirectoryInfo GetAssemblyDirectory()
{
var assembly = Assembly.GetExecutingAssembly();
return new DirectoryInfo(Path.GetDirectoryName(assembly.Location));
}
Просто измените текущий каталог
var dir = Path.GetDirectoryName(typeof(MySetUpClass).Assembly.Location);
Environment.CurrentDirectory = dir;
// or
Directory.SetCurrentDirectory(dir);
Если у вас возникли проблемы с запуском и сборкой после отключения "теневой сборки", вы должны сначала выбрать "Очистить все" из опции "Сборка", а после этого построить свой проект при "теневой сборке" отключить.
Для меня это решило установить для свойства "Копировать локальное" значение true для ссылки nunit.framework.dll в тестовом проекте.