You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rspec测试未按指定范围执行插入,请求排查问题

解决Rspec测试中批量插入数据库的命令丢失问题

问题背景

运行Rspec测试时遇到异常:测试需向C语言实现的数据库db执行批量插入,指定范围为1到1384时可正常完成1384次插入;但指定超过1384的范围时,仅执行1348次插入。已通过检查表数据验证问题,编译C程序时使用-Wall -Wextra -g3参数未发现错误,且C程序本身插入功能正常,推测问题出在测试代码中。

原测试代码:

require 'rspec'
describe 'database' do
    def run_script(commands)
      raw_output = nil
      IO.popen("./db", "r+") do |pipe|
        commands.each do |command|
          pipe.puts command
        end

        pipe.close_write

        # Read entire output
        raw_output = pipe.gets(nil)
      end
      raw_output.split("\n")
    end

    it 'prints error message when table is full' do
      script = (1..1384).map do |i|
        "insert #{i} user#{i} person#{i}@example\n"
      end
      script << ".exit"
      result = run_script(script) 
      expect(result[-2]).to eq("db > Error: Table full.")
    end
  end

问题原因

原测试代码中使用IO.popen批量写入所有命令后再一次性读取输出,这种方式存在管道缓冲区溢出或命令未被完整处理的风险:

  • 快速写入大量命令时,管道缓冲区可能被填满,导致部分命令无法被数据库进程及时读取
  • 数据库进程处理命令需要时间,测试代码未等待每条命令处理完成就关闭写入端,导致后续命令丢失

修复方案

修改run_script方法,改为逐行写入命令并同步等待处理完成,确保每条命令都被数据库进程接收并处理:

require 'rspec'

describe 'database' do
  def run_script(commands)
    output = []
    IO.popen("./db", "r+") do |pipe|
      commands.each do |command|
        pipe.puts command
        # 等待数据库返回提示符,确认当前命令已处理完成
        loop do
          line = pipe.gets
          break if line.nil? || line.include?("db > ")
          output << line.chomp
        end
      end

      pipe.close_write
      # 读取剩余的输出内容
      while (line = pipe.gets)
        output << line.chomp
      end
    end
    output
  end

  it 'prints error message when table is full' do
    # 测试超过容量的范围,比如1到1385
    script = (1..1385).map do |i|
      "insert #{i} user#{i} person#{i}@example"
    end
    script << ".exit"
    result = run_script(script)
    # 改用包含断言,避免依赖输出行的索引
    expect(result).to include("db > Error: Table full.")
  end
end

关键修改点

  • 移除命令字符串末尾的\n:pipe.puts会自动添加换行符,重复添加可能导致数据库解析错误
  • 同步等待处理结果:每次写入命令后,循环读取输出直到出现db > 提示符,确保当前命令已被数据库处理
  • 优化输出收集逻辑:分阶段读取输出,避免一次性读取导致的内容截断
  • 调整断言方式:从依赖行索引改为检查是否包含目标错误信息,提升测试稳定性

额外排查建议

  • 运行测试时可以打印result内容,查看实际输出是否有异常响应或丢失的命令反馈
  • 确认数据库表的实际容量上限是否为1384条,避免因预期值错误导致的测试偏差

内容的提问来源于stack exchange,提问作者Eugene

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 15:32:10