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

3okqufwl  于 2023-05-02  发布在  Ruby
关注(0)|答案(1)|浏览(93)

有人能指出为什么我的测试在测试文件创建/ 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

任何改善这一点的建议,或者关于问题可能在哪里的指针都会很好。

qcuzuvrc

qcuzuvrc1#

在本地和隔离状态下失败的测试之所以会这样做,是因为在测试运行之间,它们的环境发生了一些变化。这通常是由于测试依赖于系统的不确定部分:系统时钟、随机数或网络连接。解决方案是总是模拟那些不确定的依赖关系。(我回答了一个类似的问题,详细得多,here。)
在您的特定情况下,写入磁盘可能需要不确定的时间。因此,当您的测试Assert文件已附加时,文件可能尚未完全持久化。如果是这种情况,那么这就意味着有一些线程正在发生(否则测试将被文件I/O阻塞)。因此,如果可能的话,我会寻找一种方法来关闭线程并强制同步写入文件,以防止I/O和测试执行之间的竞争条件。
为了确认发生了什么,我将尝试在Assert文件已附加之前在磁盘上定位该文件。然后,您可以等待文件出现(这不是我的偏好),或者您可以强制I/O同步(如果可能的话)。

快速编辑

Ruby中的文件I/O在默认情况下是异步的。这是文件

相关问题