Тестирование модулей: как получить доступ к текстовому файлу?
Я использую Visual Studio 2008 с инструментами тестирования Microsoft. Мне нужно получить доступ к текстовому файлу из unit test.
Я уже настроил файл с действием сборки, установленным в "Контент", и скопировал в выходной каталог "Копировать всегда", но файл не копируется в выходной каталог, который согласно System.Environment.CurrentDirectory
равен
'{project_path}\TestResults\Pablo_COMPU 2009-11-26 15_01_23\Out'
Эта папка содержит все DLL-зависимости проекта, но текстового файла там нет.
Каков правильный способ доступа к текстовому файлу из unit test?
Ответы
Ответ 1
Вы должны добавить атрибут DeploymentItem
к вашему тестовому классу. С помощью этого атрибута вы указываете файлы, которые скопированы в каталог out для тестового прогона.
Например:
[TestMethod]
[DeploymentItem(@"myfile.txt", "optionalOutFolder")]
public void MyTest()
{
...
}
Смотрите также: http://msdn.microsoft.com/en-us/library/ms182475.aspx.
Ответ 2
Альтернативно, если вы установите все текстовые файлы в "Копировать для сборки каталога", вы можете ссылаться на свой путь в своих тестах, делая это
var directory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
var path = string.Format("{0}\\{1}",directory,"myFile.txt");
Ответ 3
Я не могу ответить на ваш вопрос, поскольку я не использую MSTest. Тем не менее, я бы подумал, правильно ли делать доступ к файловой системе в unit test. Если вы введете зависимость от файловой системы, тест станет медленнее и менее надежным (теперь вы зависите от того, что может не быть/доступно/и т.д.). Именно по этим причинам многие люди скажут "это не unit test, если он попадает в файловую систему".
Хотя это не сложное правило, его всегда стоит рассмотреть. Каждый раз, когда мне приходится прикасаться к файловой системе в тестах, я стараюсь избегать этого, потому что я считаю, что тесты, которые полагаются на файлы, сложнее поддерживать и, как правило, менее согласованы.
Я бы рассмотрел абстрагирование файловых операций в некоторой степени. Здесь вы можете делать множество вещей: от изменения стратегии внутренней загрузки (через Dependency Injection) до - даже лучше - отделяя загрузку/использование файла, чтобы потребителю содержимого файла даже не приходилось о стратегии загрузки.
Ответ 4
Когда мне нужен фрагмент текста как часть unit test, и это больше, чем строка или две, я использую внедренный ресурс. Это не загромождает ваш тестовый код, потому что это отдельный текстовый файл в исходном коде. Он компилируется прямо в сборку, поэтому вам не придется беспокоиться о копировании вокруг отдельного файла после компиляции. Ваш тестируемый объект может принять TextReader, и вы передаете StreamReader, который вы получаете от загрузки встроенного ресурса.
Ответ 5
Как вы проводите тесты?
Мы используем (TestDriven.net → Run Tests).
По моему опыту, некоторые тестовые ролики (например, Junit в Netbeans) не будут автоматически копировать любые дополнительные текстовые файлы, которые могут потребоваться для тестирования. Поэтому в вашем случае вам, возможно, придется выполнить полную сборку, а затем попробуйте снова запустить тесты.
И правильный способ доступа к текстовым файлам из тестов - это то, как вы пытаетесь это сделать. (Настройка файлов на "копировать всегда" и "содержимое" и доступ к ним из скомпилированного каталога).
Кроме того, не уверен, что люди получают идею о том, что тесты, основанные на файлах, являются плохими. Это не так.
Если что-либо, имея отдельные тестовые файлы, только очистит ваши тесты и сделает их более читаемыми. Рассмотрим некоторый метод синтаксического анализа xml, который возвращает большую строку:
String expectedOutput = fileOperator.ReadStringFromFile("expectedFileContents.xml");
String result = systemUnderTest.Parse(somethingtoparse);
Assert.Equals(expectedOutput, result);
Представьте, если выход был длиной 30 строк, вы бы загромождали свой тестовый код одной гигантской строкой? или просто прочитать его из файла.