编程语言
首页 > 编程语言> > 在 CI 中调试片状测试

在 CI 中调试片状测试

作者:互联网

背景

我们使用Minitest作为Ruby on Rails应用程序的测试框架。我们有简单的 GitHub 操作来运行持续集成 (CI)。我们注意到一些测试在 Minitest 的 CI 运行中偶尔会失败。失败的频率似乎大约是失败的 2/3。每个失败的测试都有一些共同点。它们都是针对我们的 API 控制器的测试,它们都是针对一个操作的,它们都遵循以下一般模式:#create

test "create new resource" do
  assert_difference('Resource.count') do
    post(
      'route',
      params: {
        resource: { **attrs },
        access_token: access_token
      },
      as: :json
    )
  end
end

此处的目标是,当用户使用有效属性和访问令牌 POST 到该路由时,新资源将保存到测试数据库中。通过查找计数是否增加 1 来检查这一点。assert_difference('Resource.count')

失败消息是一个简单的 。"Resource.count" didn't change by 1

过程

调试时我尝试做的主要事情是重新创建产生错误的情况。如果我能保证始终如一地产生错误的情况,我就可以消除噪音并专注于出了什么问题。有时这很简单,但对于 CI 中的问题,情况往往并非如此。

想法 1:提取未通过 CI 测试的种子编号

测试框架通常提供一种以随机顺序运行测试的机制,Minitest 也不例外。这很有用,因为测试没有副作用很重要。如果 TestA 仅在 TestB 之后运行时通过 - 这是一个问题,并且 TestA 没有测试它声称要测试的内容。随机游程有助于检查这些类型的情况。除了随机运行外,Minitest 还将为该测试运行输出“种子”标识符。这允许开发人员根据需要以该特定顺序再次运行测试。

我们的第一个想法是调查失败的 GitHub 操作的日志输出。这些日志将显示测试运行中使用的种子值。如果我们将该种子标识符传递给本地 Minitest,测试是否会在我们的开发环境中失败?

他们继续在开发中通过...继续下一个想法!

想法 2:强制 GitHub 操作每次都以失败的种子运行

因此,我们已经确认该错误仅存在于 CI 环境中。我的同事想到了一个失败的种子号,并将其添加到 GitHub 测试操作的工作流中的 Minitest 命令中:

然后,我们可以检查测试是否每次都在 CI 中失败,而不仅仅是偶尔失败。经过几次运行后,我们确信测试在CI中始终失败。无法在本地重现问题很不方便。但至少我们有一个一致的失败环境。现在我们可以开始检查失败的案例了。
run: bundle exec rails test --seed=${FAILING_SEED_NUMBER}

打印调试

不幸的是,我们无法为在 CI 中运行的测试挂接调试会话。所以我们不得不回到我们的老朋友:打印调试。我们在失败的测试用例中发送了一些垃圾邮件和语句。不同局部变量的值是什么?什么回来了?在我们的方法中配置了哪些实例变量返回?最后,是什么样子的?pputs'Resource.count'setupresponse

我们很快发现,这并不是因为输出和断言不匹配而失败。相反,由于测试期间引发的错误,它失败了:

ActiveRecord::RecordNotUnique (duplicate key value violates unique constraint). Key already exists.

在检查代码后,我们对测试中的FactoryBot方法产生了怀疑:#setup

def setup
  # access_token and user configuration
  @resource = create(:resource, attr1: "attr1", attr2: "attr2", id: '1')
end

在工厂中显式分配了一个 ID。此 id 用于控制器的不同测试用例中的断言。经过一番研究,找到这种事情成为问题的例子并不难(见:这里)。通过直接分配 ID,可以摆脱主键的自然递增。因此,我们决定删除该 id 参数,并更改依赖于 id 来查找的断言。我们对使用此模式的每个测试用例进行了这些更改。@resource.id

然后,我们将代码向上推送,CI 测试命令仍设置为运行失败的种子,它通过了!然后,我们回到运行没有指定种子的 GitHub 操作,因此它将恢复为以随机顺序运行。在连续几次成功运行后,我们有信心解决问题!

标签:CI,Minitest,GitHub
来源: