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 appe开发者_StackOverflow社区ars 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
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];
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.
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.
Hope this was helpful.
精彩评论