Я только что написал пост в блоге о зависимостях файлов и тестировании здесь.
http://tsells.wordpress.com/2012/03/06/how-to-run-integration-tests-with-file-dependencies/
Тесты, которые вы выполняете, являются интеграционными тестами, так как вы переходите в файловую систему. Я хотел бы использовать пример для каждого класса метода в посте для того, что вы пытаетесь достичь.
Содержание сообщения
Ответственность
Во многих случаях тест разработчика должен выполняться с определенным файлом / набором файлов, которые должны находиться в файловой системе. Многие «пуристы» думают, что это плохая идея, и вы должны «издеваться» над своей системой так, чтобы это не требовалось. В некоторых случаях это может быть правдой - но я «реалист» и понимаю, что требования к сложности, связанные с такими действиями, могут и во многих случаях значительно перевешивают преимущества простого использования файловой системы для теста. Это, однако, переводит тест из истинного «модульного» теста в «интеграционный» тест. Я доволен этим, так как считаю, что интеграционные тесты дают больше преимуществ, чем модульные. Если настройка и запуск выполняются правильно - этот тест можно запустить локально в Visual Studio, через сборку MS и командную строку или на сервере сборки, на котором работают агенты сборки, такие как Team City.
Вы можете скачать исходный код здесь: TestClass.zip
Требования для этого теста
Test Runner (мне нравится использовать TestDriven.Net, поскольку он позволяет выполнять как в строке, так и в режиме отладки)
Класс файла, который обёртывает некоторые функции system.IO и позволяет реализовать IDisposable. Это полезно для создания «песочницы», которая когда-то выходит из области видимости - и она удаляет все временные файлы, которые используются, поэтому очистка выполняется автоматически (в примере приведен пример класса).
NUnit или MSTest. Я все еще предпочитаю NUnit.
Варианты использования
Требования к использованию тестовых файлов будут определять, как и когда их устанавливать и очищать (удалять).
Per Test - файлы регенерируются для каждого запуска теста
Для каждого тестового класса - файлы генерируются один раз для каждого тестового класса.
В обоих случаях класс FileSandBox используется для создания временного расположения для файлов, которые будут жить, а затем будут удалены после завершения теста (ов).
за использование класса
[TestFixture]
открытый класс PerClass
{
приватный FileSandbox _sandbox;
приватная строка _tempFileLocation;
public PerClass() {}
/// <summary>
/// Setup class - runs once per class
/// </summary>
[TestFixtureSetUp]
public void SetupClass()
{
_sandbox = new FileSandbox();
// Getting Temp file name to use
_tempFileLocation = _sandbox.GetTempFileName("txt");
// Get the current executing assembly (in this case it's the test dll)
Assembly myassembly = Assembly.GetExecutingAssembly();
// Get the stream (embedded resource) - be sure to wrap in a using block
using (Stream stream = myassembly.GetManifestResourceStream("TestClass.TestFiles.TextFile1.txt"))
{
// In this case using an external method to write the stream to the file system
_tempFileLocation = TestHelper.StreamToFile(stream, _tempFileLocation);
}
}
/// <summary>
/// Tear down class (cleanup)
/// </summary>
[TestFixtureTearDown]
public void TearDownClass()
{
_sandbox.Dispose();
}
[Test, Description("Testing doing something with files on the filesystem")]
public void MyFileSystemTest()
{
string[] lines = File.ReadAllLines(_tempFileLocation);
Assert.IsTrue(lines.Length > 0);
}
}
за тестовое использование (вариант 1)
[TestFixture]
public class PerTest
{
public PerTest(){}
/// <summary>
/// Setup class - runs once per class
/// </summary>
[TestFixtureSetUp]
public void SetupClass()
{
// NOOP
}
/// <summary>
/// Tear down class (cleanup)
/// </summary>
[TestFixtureTearDown]
public void TearDownClass()
{
// NOOP
}
[Test, Description("Testing doing something with files on the filesystem")]
public void MyFileSystemTest()
{
using (FileSandbox sandbox = new FileSandbox())
{
// Getting Temp file name to use
string tempfile = sandbox.GetTempFileName("txt");
// Get the current executing assembly (in this case it's the test dll)
Assembly myassembly = Assembly.GetExecutingAssembly();
// Get the stream (embedded resource) - be sure to wrap in a using block
using (Stream stream = myassembly.GetManifestResourceStream("TestClass.TestFiles.TextFile1.txt"))
{
// In this case using an external method to write the stream to the file system
tempfile = TestHelper.StreamToFile(stream, tempfile);
string[] lines = File.ReadAllLines(tempfile);
Assert.IsTrue(lines.Length > 0);
}
}
}
}
За тестовое использование (вариант 2)
[TestFixture]
открытый класс PerEachTest
{
приватный FileSandbox _sandbox;
приватная строка _tempFileLocation;
public PerEachTest() { }
/// <summary>
/// Setup class - runs once per class
/// </summary>
[TestFixtureSetUp]
public void SetupClass()
{
// NOOP
}
/// <summary>
/// Tear down class (cleanup)
/// </summary>
[TestFixtureTearDown]
public void TearDownClass()
{
// NOOP
}
[SetUp]
public void Setup()
{
_sandbox = new FileSandbox();
// Getting Temp file name to use
_tempFileLocation = _sandbox.GetTempFileName("txt");
// Get the current executing assembly (in this case it's the test dll)
Assembly myassembly = Assembly.GetExecutingAssembly();
// Get the stream (embedded resource) - be sure to wrap in a using block
using (Stream stream = myassembly.GetManifestResourceStream("TestClass.TestFiles.TextFile1.txt"))
{
// In this case using an external method to write the stream to the file system
_tempFileLocation = TestHelper.StreamToFile(stream, _tempFileLocation);
}
}
[TearDown]
public void Teardown()
{
_sandbox.Dispose();
}
[Test, Description("Testing doing something with files on the filesystem")]
public void MyFileSystemTest()
{
string[] lines = File.ReadAllLines(_tempFileLocation);
Assert.IsTrue(lines.Length > 0);
}
}
Вы можете скачать исходный код здесь: Исходный код