有人能指出为什么我的测试在测试文件创建/ ActiveStorage时是不稳定的(本地的,在circleCI上的)吗?
在开发过程中,这段代码工作正常,但我怀疑测试中有一些奇怪的竞争条件或其他东西。
我正在测试下面的create_my_file
方法作为模型测试和控制器测试(不同的地方),当我检查新文件是否已经附加到我的模型时,它经常失败。
如下所示,我每次都使用MyFileGenerator
在tmp文件夹中创建文件,然后使用该文件附加并上传到S3。然后,当我们创建另一个文件时,我们首先删除tmp文件夹并重新创建,以避免文件堆积。
def create_my_file
if my_file.attached?
my_file.purge
end
MyFileGenerator.new.create(my_file_data, id)
my_file.attach(
io: File.open(
"#{Rails.root}/tmp/my_file/my_file_#{id}.docx"
),
filename: "my_file_#{id}_#{Time.now.to_i}.docx",
content_type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
)
end
MyFileGenerator.new.create
def create(data, meeting_id)
doc = Docx::Document.open("#{Rails.root}/app/lib/docx/docx_templates/my_file).docx")
populate_document(doc, data)
# Save the new file
make_tmp_directory
doc.save("#{Rails.root}/tmp/my_file/my_file_#{meeting_id}.docx")
end
private
def make_tmp_directory
# We need to store the file somewhere before uploading to S3
dir = "#{Rails.root}/tmp/my_file/"
# Clear existing files if exists, then make new dir
FileUtils.remove_dir(dir, true) if File.exist?(dir)
Dir.mkdir(dir)
end
任何改善这一点的建议,或者关于问题可能在哪里的指针都会很好。
1条答案
按热度按时间qcuzuvrc1#
在本地和隔离状态下失败的测试之所以会这样做,是因为在测试运行之间,它们的环境发生了一些变化。这通常是由于测试依赖于系统的不确定部分:系统时钟、随机数或网络连接。解决方案是总是模拟那些不确定的依赖关系。(我回答了一个类似的问题,详细得多,here。)
在您的特定情况下,写入磁盘可能需要不确定的时间。因此,当您的测试Assert文件已附加时,文件可能尚未完全持久化。如果是这种情况,那么这就意味着有一些线程正在发生(否则测试将被文件I/O阻塞)。因此,如果可能的话,我会寻找一种方法来关闭线程并强制同步写入文件,以防止I/O和测试执行之间的竞争条件。
为了确认发生了什么,我将尝试在Assert文件已附加之前在磁盘上定位该文件。然后,您可以等待文件出现(这不是我的偏好),或者您可以强制I/O同步(如果可能的话)。
快速编辑
Ruby中的文件I/O在默认情况下是异步的。这是文件