views:

130

answers:

1

I have written a DotUnit test suite for testing some data import functionality in my application. It works by making a backup of some local Microsoft Access Database, let's call it 'Test.mdb', to 'Test.mdb.bak', performing some data import (and subsequent Assert checks) and then restoring the original from the backup.

The SetUp() function creates a backup if one doesn't exist.

The TearDown() function attempts to delete 'Test.mdb' and then copy 'Test.mdb.bak' to 'Test.mdb'.

Intermittently running the tests fail with this error "The process cannot access the file because it is being used by another process".

I've had a look the MSDN on File.Delete and IO permissions but couldn't find what I was after. Does anyone know if there is a .NET feature that will allow me to completely lock the file before attempting to delete it? Or find which process is accessing it at the time of deletion?

+5  A: 

You might reconsider your testing approach. Instead:

  1. Create a temporary copy of the file
  2. Perform the actions that are being tested on the temp file
  3. Release all handles (close all connections) to the temp file
  4. Delete the temp file

Using this pattern, the only process that will be accessing the file will be the thread running the unit test.

Use the function: System.IO.Path.GetTempFileName();

http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx

EDIT: Here is one way to code it:

var tempFile = System.IO.Path.GetTempFileName();
System.IO.File.Copy(@"C:\Test.mdb", tempFile, true);
// 2. Test tempFile
// 3. Release handles to tempFile, use a using statement around any 
//    streams or System.IO API's that are using the file in any way.
System.IO.File.Delete(tempFile);
umbyersw
This is good advice. Much better than my snippy suggestion (not posted) about avoiding the problem by deleting MS Access.
Steven Sudit
Before I posted I actually re-wrote my tests do exactly this. The problem is that it happens very intermittently (maybe 1 in 1000 times) so if my changes don't fix the problem then it might be a while before I find out about it again. Hence why I posted up the old implementation in an attempt to see if there was an easier way to get around it or to address the problem.
sonelliot