ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

在 CI 中调试片状测试

2023-07-14 15:20:54  阅读:107  来源: 互联网

标签:CI Minitest GitHub


背景

我们使用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
来源:

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有