The short question is: How can I get iPhone (objective-c) file operations to work correctly from a command line Unit Test?

The long question, with explanation: This will eventually become a script to perform automated building/testing for my iPhone build, via a Hudson instance. Following makdad's link on this SO question has allowed me to run Unit tests from the command line (semi) successfully.

However, one of my tests fails. The test would call a Caching Service class to save a file, then try and retrieve it. however, file I/O appears to not work when running the tests from the command line :(.

For Reference, running the Unit tests via the Xcode GUI results in no such errors.

I am using NSFileHandle method calls to get handles for writing. if they return nil, the file is created using

I thought it may have to do with the spaces in the path to the simulator's cache directory. am I on the right track? if so, how would i rectify this?

Note also that the simulator needs to be NOT running already in order for this to work, the simulator is started programmatically and does not display a GUI. if it is running, the command line build fails.

Is the file created? Is it throwing an error? Generally, spaces shouldn't be a problem in the NSString, since there's nothing else processing it, they will be taken literally. One thing we had to be careful with when running tests from the command line was any environment variables that were set by Xcode, but not by our script.
–
gaigeOct 20 '11 at 0:44

Unfortunately I haven't had a chance to look into this for a while, having moved on to another project, and I can't remember if the file was being created or not. however you're right its possible I might need to set an environment variable to give the Simulator some disk space to use as 'Internal Memory'. if i get a chance i'll test this out
–
RobotnikOct 26 '11 at 0:07

1 Answer
1

First: 'the simulator needs to be NOT running already in order for this to work'
I have my tests running in the terminal and it doesn't matter if the simulator is on.

Maybe some build settings you have to look at are: TEST_HOST and BUNDLE_LOADER.
I leave them empty in my xcodeproj.Note: I'm using Hudson as well with test reports and code coverage.

Second:
I have experienced failures in tests terminal and application with loading paths. This was related to the Core Data model which is loaded from a resource.
The solution was to load the file from url instead of a path:

[[NSBundle bundleForClass:[self class]] URLForResource:....];

I cannot ensure this relates to the same problem your encountering with the NSFileManager, but i can only imagine that NSBundle makes use of the NSFileManager. (So this can be related)

Third:
Do not make your tests dependent on I/O.
I find that that is not the purpose of a Unit Test. Such test may not rely on a filesystem, database, network connection, etc.

Make an file system abstraction class that you mock while running your tests.
This way your implementation is only at one place relying on the actual file system, which you can replace during testing.

You only need one test to check that abstraction.

Summary

The first will improve your test setup.

The second will hopefully solve your test problem.

The third will reduce the occurrence of the problem and improve your code.