views:

73

answers:

2

I'm working on implementing a reasonably simple XML serializer/deserializer (log file parser) application in C# .NET with VS 2008. I have about 50 unit tests right now for various parts of the code (mostly for the various serialization operations), and some of them seem to be failing mostly at random when they deal with file I/O.

The way the tests are structured is that in the test setup method, I create a new empty file at a certain predetermined location, and close the stream I get back. Then I run some basic tests on the file (varying by what exactly is under test). In the cleanup method, I delete the file again.

A large portion (usually 30 or more, though the number varies run to run) of my unit tests will fail at the initialize method, claiming they can't access the file I'm trying to create. I can't pin down the exact reason, since a test that will work one run fails the next; they all succeed when run individually.

What's the problem here? Why can't I access this file across multiple unit tests?

Relevant methods for a unit test that will fail some of the time:

[TestInitialize()]
public void LogFileTestInitialize()
{
    this.testFolder = 
        System.Environment.GetFolderPath(
            System.Environment.SpecialFolder.LocalApplicationData
        );
    this.testPath = this.testFolder + "\\empty.lfp";
    System.IO.File.Create(this.testPath).Close();
}

[TestMethod()]
public void LogFileConstructorTest()
{
    string filePath = this.testPath;
    LogFile target = new LogFile(filePath);
    Assert.AreNotEqual(null, target);
    Assert.AreEqual(this.testPath, target.filePath);
    Assert.AreEqual("empty.lfp", target.fileName);
    Assert.AreEqual(this.testFolder + "\\empty.lfp.lfpdat", target.metaPath);
}

[TestCleanup()]
public void LogFileTestCleanup()
{
    System.IO.File.Delete(this.testPath);
}

And the LogFile() constructor:

public LogFile(String filePath)
{
    this.entries = new List<Entry>();
    this.filePath = filePath;
    this.metaPath = filePath + ".lfpdat";
    this.fileName = filePath.Substring(filePath.LastIndexOf("\\") + 1);
}

The precise error message:

Initialization method LogFileParserTester.LogFileTest.LogFileTestInitialize threw exception. System.IO.IOException: System.IO.IOException: The process cannot access the file 'C:\Users\<user>\AppData\Local\empty.lfp' because it is being used by another process..

A: 

Sounds like some of the tests are being run at the same time. Do the individual tests write to the file, or just read it? If they're read only, I'm sure we can make a minor change to enable them to run concurrently. More details?

sblom
You tell me - does VS2008 run tests concurrently? I thought about that, but Google seemed to indicate that only VS2010 supports multiple simultaneous tests.
Tim
+1  A: 

You should be mocking the file system access, and not actually reading/writing files in your unit tests.

thekaido