使用 minitest 检查文件创建时的不稳定测试

问题描述 投票:0回答:1

有人能指出为什么我的测试在测试文件创建/ActiveStorage 时不稳定(在本地和 circleCI 上)吗?

在开发中,这段代码工作正常,但我怀疑测试中存在一些奇怪的竞争条件或其他东西。

我正在测试下面的

create_my_file
方法作为模型测试和控制器测试(各个地方),当我检查新文件是否已附加到我的模型时它经常失败。

如下所示,我每次都在我们的tmp文件夹中使用

MyFileGenerator
创建文件,然后我们使用这个文件附加并上传到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

任何改进这个的建议,或者关于问题可能出在哪里的指示都会很好。

ruby-on-rails minitest rails-activestorage
1个回答
0
投票

在本地和孤立地失败的测试之所以如此,是因为它们的环境在测试运行之间发生了某些变化。这通常是由于测试依赖于系统的不确定部分:系统时钟、随机数或网络连接。解决方案是始终模拟那些不确定的依赖项。 (我更详细地回答了类似的问题,here。)

在您的特定情况下,写入磁盘可能需要不确定的时间。因此,当您的测试断言文件已附加时,文件可能尚未完全保留。如果是这种情况,那么这就意味着发生了一些线程(否则测试将被文件 I/O 阻塞)。所以,如果可能的话,我会寻找一种方法来关闭线程并强制同步写入文件,以防止 I/O 和测试执行之间的竞争条件。

为了确认发生了什么,我会尝试在断言它已附加之前在磁盘上找到该文件。然后你可以等待文件出现(不是我的偏好),或者你可以强制 I/O 同步(如果可能的话)。

快速编辑

Ruby 中的文件 I/O 似乎默认是异步的。这是docs.

© www.soinside.com 2019 - 2024. All rights reserved.