如何测试生成文件的脚本
我正在创建一个 Rubygem,它可以让我生成 jekyll post 文件。我开发这个项目的原因之一是学习 TDD。这个 gem 在命令行上严格起作用,它必须进行一系列检查以确保它找到 _posts
目录。这取决于两件事:
- 是否传递了
location
选项- 该位置选项有效吗?
- 未传递位置选项
- posts 目录是否在当前目录中?
- posts 目录是当前工作目录吗?
那时,我真的很难测试应用程序的这一部分。所以我有两个问题:
- 跳过对应用程序的一小部分(如上述部分)的测试是否可以接受/可以?
- 如果没有,如何使用 minitest 测试 ruby 中的文件操作?
I am creating a Rubygem that will let me generate jekyll post files. One of the reasons I am developing this project is to learn TDD. This gem is strictly functional on the command line, and it has to make a series of checks to make sure that it finds the _posts
directory. This depends on two things:
- Wether or not a
location
option was passed- Is that location option valid?
- A location option was not passed
- Is the posts dir in the current directory?
- Is the posts dir the current working directory?
At that point, I am really having a hard time testing that part of the application. So I have two questions:
- is it acceptable/okay to skip tests for small parts of the application like the one described above?
- If not, how do you test file manipulation in ruby using minitest?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我见过的一些项目将其命令行工具实现为 Command 对象(例如: Rubygems 和 我的换行宝石)。这些对象使用 ARGV 进行初始化,只需调用或执行方法即可启动整个过程。这使得这些项目能够将其命令行应用程序放入虚拟环境中。例如,它们可以将输入和输出流对象保存在命令对象的实例变量中,以使应用程序独立于使用 STDOUT/STDIN。因此,可以测试命令行应用程序的输入/输出。就像我想象的那样,您可以将当前工作目录保存在实例变量中,以使命令行应用程序独立于实际工作目录。然后,您可以为每个测试创建一个临时目录,并将其设置为 Command 对象的工作目录。
现在是一些代码:
现在在测试的设置和拆卸方法中,您可以执行以下操作:(
在示例中,我使用 Pathname,这是来自 Ruby 标准库和 StringIO 的一个非常好的面向对象文件系统 API,对于模拟非常有用STDOUT,因为它是一个 IO 对象,流入一个简单的字符串)
在实际测试中,您现在可以使用 @working_dir 变量来测试文件是否存在或内容:
Some projects I've seen implement their command line tools as Command objects (for example: Rubygems and my linebreak gem). These objects are initialized with the ARGV simply have a call or execute method which then starts the whole process. This enables these projects to put their command line applications into a virtual environment. They could, for example hold the input and output stream objects in instance variables of the command object to make the application independant of using STDOUT/STDIN. And thus, making it possible to test the input/output of the command line application. In the same way I imagine, you could hold your current working directory in an instance variable to make your command line application independent of your real working directory. You could then create a temporary directory for each test and set this one as the working directory for your Command object.
And now some code:
Now in your test's setup and teardown methods you could do:
(In the example I'm using Pathname, which is a really nice object oriented file system API from Ruby's standard library and StringIO, which is useful for for mocking STDOUT as it's an IO object which streams into a simple String)
In the acutal test you could now use the @working_dir variable to test for existence or content of files:
根据我的经验(因此这是非常主观的),我认为有时在某些难以测试的领域跳过单元测试是可以的。您需要弄清楚您会得到什么回报以及是否进行测试的成本。我的经验法则是,不测试某个类的决定应该是非常不寻常的(大约 300 个类中不到 1 个)
如果您尝试测试的内容非常困难,因为与文件系统的依赖性,我认为您可以尝试提取与文件系统交互的所有位。
From my experience (and thus this is VERY subjective), I think it's ok sometimes to skip unit testing in some areas which are difficult to test. You need to find out what you get in return and the cost for testing or not. My rule of thumb is that the decision to not test a class should be very unusual (around less than 1 in 300 classes)
If what you're trying to test is very difficult, because of the dependencies with the file system, I think you could try to extract all the bits that interact with the file system.