iPhone 命令行单元测试(和文件 I/O)

Posted

技术标签:

【中文标题】iPhone 命令行单元测试(和文件 I/O)【英文标题】:iPhone command line Unit Tests (and File I/O) 【发布时间】:2011-09-27 06:49:44 【问题描述】:

简短的问题是:如何让 iPhone (objective-c) 文件操作在命令行单元测试中正常工作?

带解释的长问题:这最终将成为一个脚本,通过 Hudson 实例为我的 iPhone 构建执行自动构建/测试。在this SO question 上关注 makdad 的链接后,我可以成功地从命令行(半)运行单元测试。

但是,我的一项测试失败了。测试将调用缓存服务类来保存文件,然后尝试检索它。但是,从命令行运行测试时,文件 I/O 似乎不起作用:(。

作为参考,通过 Xcode GUI 运行单元测试不会导致此类错误。

我正在使用 NSFileHandle 方法调用来获取写入句柄。如果它们返回 nil,则使用

创建文件
[[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:nil];

我认为这可能与模拟器缓存目录路径中的空格有关。我在正确的轨道上吗?如果是这样,我将如何纠正这个问题?

另请注意,模拟器需要运行才能使其工作,模拟器以编程方式启动并且不显示 GUI。如果它正在运行,则命令行构建失败。

【问题讨论】:

文件创建了吗?它会抛出错误吗?一般来说,空格在 NSString 中不应该是一个问题,因为没有其他处理它,它们将按字面意思理解。从命令行运行测试时我们必须小心的一件事是任何由 Xcode 设置的环境变量,但不是由我们的脚本设置的。 不幸的是,我已经有一段时间没有机会研究这个了,我已经转移到另一个项目,我不记得文件是否正在创建。但是你是对的,我可能需要设置一个环境变量给模拟器一些磁盘空间用作“内部存储器”。如果我有机会我会测试一下 缺少任何中间目录? 【参考方案1】:

首先:“模拟器必须尚未运行才能使其工作” 我的测试在终端中运行,模拟器是否打开并不重要。

也许您必须查看的一些构建设置是:TEST_HOSTBUNDLE_LOADER。 我在我的 xcodeproj 中将它们留空。注意:我正在使用 Hudson 以及测试报告和代码覆盖率。

第二: 我在加载路径的测试终端和应用程序中遇到了失败。这与从资源加载的核心数据模型有关。 解决方案是从 url 而不是路径加载文件:

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

我无法确保这与您在使用 NSFileManager 时遇到的问题有关,但我只能想象 NSBundle 使用了 NSFileManager。 (所以这可能是相关的)

第三: 不要让您的测试依赖于 I/O。 我发现这不是单元测试的目的。此类测试可能不依赖于文件系统、数据库、网络连接等。

创建一个在运行测试时模拟的文件系统抽象类。 这样,您的实现只在一个地方依赖于实际的文件系统,您可以在测试期间替换它。

您只需要一项测试即可检查该抽象。

总结

第一个将改进您的测试设置。 第二个有望解决您的测试问题。 第三个将减少问题的发生并改进您的代码。

希望这对您有所帮助。

【讨论】:

我终于追到了这个,我们最终做的正是你的第二点。谢谢! 很高兴我们缩小了您的问题范围。我认为会帮助很多人。

以上是关于iPhone 命令行单元测试(和文件 I/O)的主要内容,如果未能解决你的问题,请参考以下文章

使用内存磁盘进行 I/O 单元测试

iOS 单元测试通用应用程序

如何从命令行在 iPhone 上启动 OCUnit 测试

go语言系统-从文件操作到单元测试

无法在 iphone 单元测试中从 NSBundle 加载文件

使用 XCode 3 对 iPhone 静态库进行单元测试