专注测试技术的课程订阅站点

测试用例设计中的契诃夫之枪原则

看到一篇跟用例数据准备相关的文章,觉得挺有道理的。我之前在设计用例数据的时候就会犯类似的错误,这篇文章其实说的非常在理。

翻译了一下原文,供大家参考。

编写测试用例更像是讲故事而非纯技术工作,这种观点并不罕见。最近我在 The Bike Shed 播客中听到这个观点,而且在博客文章和会议演讲中也经常能看到类似的讨论。既然测试编写是一种讲故事的艺术,那么我们是否应该借鉴叙事原则来改进我们的测试呢?

谈到讲故事的原则,首先想到的就是契诃夫之枪原则。这个原则是什么?用安东·契诃夫自己的话说(引自大英百科全书):

如果在舞台上放置了一支上膛的步枪,那么它就必须被开火。不要做出你不打算履行的承诺。

大英百科全书还给出了如下定义:

这是一条适用于戏剧、文学和其他叙事形式的原则,它强调故事中引入的每个元素都应该对情节发展必不可少。

那么这个原则如何应用到我们的测试编写中呢?想象一下你正在为电商系统编写测试用例。你有不同类别的产品,这些类别对买家有一些限制条件。最明显的例子就是不能向未满十八岁的人销售酒类产品。在我们的例子中,这类人群不能将这些产品添加到购物车。

让我们看一个测试代码示例(我使用的是 Elixir,但这个原则适用于大多数编程语言):

test "don't allow adding products to cart when age constraint is not met" do
  buyer = %Person{
    name: "John Smith",
    age: 17,
    country: :uk,
    registered_on: ~U[2023-09-16T18:17:22Z]
  }

  category = %Category{
    name: "Alcohol",
    external_id: 3242,
    constraints: [
      %AgeConstraint{min: 18}
    ]
  }

  product = %Product{
    name: "Triple Hazy IPA",
    category: category,
    sku: "TRI-557",
    added_at: ~U[2022-01-01T12:16:54Z]
  }

  cart = Cart.init(buyer)

  assert Cart.add(cart, product, quantity: 2) == {:error, :constraint_violated}
end

这个测试本身并不算糟糕,但它在多处违反了契诃夫之枪原则。在我们测试的"准备"阶段引入的每个标量都是契诃夫意义上的"枪"。它们都被放在了舞台上,读者可能会期待它们都会"开火"。这里我们有 10 个标量,相当于舞台上放了 11 把枪。什么是"开火"?就是当我们把这个值改成其他值时,测试应该失败。让我们检查一下这些标量:

  • name: "John Smith": 无论改成什么,测试都不会失败
  • age: 17: 如果改成 18 或 22,测试会失败
  • country: :uk: 不会失败(除非我们实现了基于国家的限制,但目前没有)
  • registered_on: <date>: 无关紧要
  • name: "Alcohol": 无关紧要
  • external_id: 3242: 这是什么?无关紧要
  • min: 18: 改成 15 会导致测试失败
  • 产品中剩余的 name、sku 和添加日期都不会影响测试
  • quantity: 2: 同样无关紧要

总结一下,我们的 11 个"枪"中只有两个会"开火",约 18%。其余的都是纯粹的干扰,如果读者试图理解测试的动态性,这些都会让他们误入歧途。

测试工程师被解雇后,接下来该怎么办?

写在前面

前几天富途大裁员的消息相信让很多同学都感到压力倍增。

如今互联网领域的裁员潮并没有收敛的趋势,大有人人自危的感觉。

今天正好看到了一篇跟裁员相关的文章,翻译了一下,希望可以给大家提供一些思路。

原文在这里: https://filiphric.com/laid-off-as-a-tester-what-now

正文

如果你在 QA(质量保证)领域工作已经几年了,你可能已经注意到这个行业正在迅速变化。不幸的是,这也意味着裁员浪潮正在席卷整个行业,无论是初级还是高级测试人员都不能幸免。

最近,我遇到了一个在 Reddit 上发帖的测试工程师,他在手动测试岗位上已经工作了 15 年,而他所在的公司正经历一些变革。对未来的担忧已经蔓延,我想和大家分享一些看法,因为说实话,这种情况其实并不罕见。

跳出公司的舒适圈

作为测试人员,我们往往会深入了解公司的专业领域。但当我们不再为这家公司工作时,很难将这些专业知识应用到其他地方。我们常常将自身价值与所在公司绑定,一旦环境改变,就会感到迷茫。然而,事实上我们还是很有价值的!

想想看 - 测试人员通常是全能型人才:

  • 他们负责发布管理
  • 他们能发现 bug
  • 他们拥有技术知识
  • 他们可能懂得编程
  • 他们擅长编写文档

我认为记录下你的知识,并真正理解自己的优势、专长和经验是很重要的。

因为关键在于 - 在不同的公司中,你已有的技能可能会以不同的方式呈现!可能会有一家公司正在寻找你恰好具备的技能,只是他们没有将其称为"测试"岗位。这可能是产品负责人、Scrum 大师、发布经理、技术文档撰写员、开发体验工程师或其他角色。

自动化学习永远不会太晚

如果你一直在做手动测试,还没有接触过测试自动化,但觉得现在是时候开始了 - 我强烈推荐查看 Applitools 的测试自动化大学。那里有大量免费资源,你可以学习各种测试自动化。不要觉得自己错过了机会 - 学习永远不会太晚!

关于人工智能

我知道听到人工智能这个词,一些人可能会翻白眼(相信我,我懂!),因为网上关于这个话题的噪音太多了。要分辨哪些是有价值的信息确实很困难。

尽管所有关于 AI 的讨论可能令人感到无所适从,但现实是:AI 已经来了,而且不会离开。许多公司正在转型,如果你想保持竞争力,就需要至少掌握一些相关知识。

获取 AI 知识并不意味着你必须成为一名"提示工程师"。相反,想想如何运用你现有的专业知识并用 AI 来增强它。例如,在做测试自动化时,你可以:

  • 用 AI 提高工作效率
  • 尝试使测试自动化更加稳定
  • 使用 AI 加速学习

我个人最近几个月一直在使用 Cursor,它大大提升了我的学习效率。当它生成我不理解的代码时,我可以直接选中那段代码并要求解释。

你可以将 AI 视为不会替代你技能,而是帮助你增强技能的工具。

展示你的工作

在当前的就业市场中,让你的工作可见是非常重要的。即使你刚开始接触写代码,我也建议创建一个 GitHub 账号,上传你的代码仓库,展示你正在做的项目。

虽然我已经很久没有面试了,所以请对我的建议保持警惕。但每当我看到一个展示自己工作的 GitHub 账号的候选人,他们都会立即获得加分(需要说明的是,我从未是唯一的决策者)。这不仅让我的工作更轻松,因为我可以清楚地了解候选人的技术水平,更重要的是,这表明他们愿意学习和尝试。

开始写博客

另一个绝佳的职业发展技巧是写博客并分享你的学习经历。正如 Angie Jones 最近提到的,这可能会为你打开很多机会之门。我就是一个活生生的例子。

为什么测试人员找工作越来越难了

最近在招聘,3 个测试岗位,1 个 sre 岗位,进展不是十分顺利。

3 个测试岗位里 2 个是正式编制,1 个是外包岗位,sre 岗位是正编。

招不到人的原因其实并不是因为简历不够,相反简历数据还是很可观的。

核心原因还是因为现在招聘的要求比之前行业红火的时候高了很多。

现在就职的公司大概属于三四流公司的水平,比上不足比下有余的类型,反正跟大厂比差距还是很大的。

但哪怕是这种非头部公司,对新晋人员的要求还是有一定门槛的。

对于正式编制来说,需要满足

  • 40 岁以下
  • 一本学历以上

外包编制相对没有那么严格,只要是正规的全职日本科就好。

对年龄和学历的硬性要求就导致了尽管收到的简历很多,但真正可以通过筛选并进入面试流程的候选人寥寥无几。

相反的,静下心来想一想,从另一方面推测,今年测试人员找工作其实应该非常困难。

原因大概以下几点。

市场不景气

各种公司裁员倒闭的消息层出不穷,市场上真正的需求其实非常疲软,真正放出来的岗位其实非常有限。

企业要求水涨船高

三四流公司都要求一本学历了,这其实是行业从业人员渐进式换血的体现。

之前行业欣欣向荣,英雄不问出处,旺盛的市场需求就造成了很多学历一般专业不对口的候选人可以进入软件测试行业。

但现在市场相对饱和,大浪淘沙加上挤出效应,原先条件一般的从业人员慢慢被市场淘汰,客观上完成了一轮又一轮的洗牌。

测试行业停滞不前

测试行业这么多年来的变化其实相对有限,无论是云计算时期,音视频时期还是 ai 阶段,测试人员的工作性质和范围基本变化不大。

整个行业停滞不前已经很多年了,缺少颠覆性的变化造成了行业本身新需求不足。

另外行业十分稳定也造成了测试人员同质化相对严重,好的背景自然而然就成为了求职的关键。

近期建议

既然寒冬已至,那么还是要有应对的套路的。

  • 有工作的同学相对要保持稳健一些,毕竟跳槽之后新东家忽然一夕之间倒闭关门也是有可能的
  • 没有工作的同学心态平和一些,多锻炼身体,减少不必要的开销,先苟住,静待春暖花开

最后

顺便发个招聘信息。

  • 正编测试,base 重庆/深圳,功能测试为主,希望有一定的工程化能力,20k 左右,oa 或 hr 项目,统招本科,一本,2 人
  • 外包测试,base 深圳,功能测试为主,oa 项目,1 人
  • SRE 工程师,base 深圳,1 人,统招本科,一本

感兴趣的同学麻烦加下面的群哈。

第二春?令人惊喜的selenium项目selenium base

最近发现 github 月热门项目里有个老面孔 selenium base 在短期内获得了比较大的关注。

这个项目存在的时间应该有好多年了,我记得当初似乎也写过文章去介绍。

本以为这就是一个普通的结合 pytest 和 selenium 封装的测试框架,不料几年过去项目的发展似乎渐入佳境。

这次最让我眼前一亮的功能是 selenim base 支持绕过 Cloudflare 的访问校验

新的爬虫利器?

用 selenium 写过爬虫的同学可能都会对 Cloudflare 的访问校验感到头痛。

简单来说,在你访问目标站点的时候,cloudflare 会自动校验此次访问是不是来自不明的 ip 或者设备,如果是用脚本去访问该站点的话,cloudflare 会直接进行拦截,不展示网页的内容。

不过 selenium base 却用几行代码打破了这一桎梏。

from seleniumbase import SB

with SB(uc=True, test=True, locale_code="en") as sb:
    url = "https://gitlab.com/users/sign_in"
    sb.activate_cdp_mode(url)
    sb.uc_gui_click_captcha()
    sb.sleep(2)

用什么工具写爬虫其实无关紧要,爬虫进入深水区的时候往往需要跟反爬策略做各种对抗。

由于 selenium 本身使用了真实的浏览器进行网页访问,自带光环,可以绕过很多的反爬策略。

但是 cloudflare 的前置拦截却一直没有稳定的解决方案,selenium base 提供了绕过校验的便利,看上去非常利好爬虫的发挥。

其他有意思的特性

支持录制

文档在这里。https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md

因为 selenium base 暴露出来的 api 比较有限,所以录制出的代码可用性相对较高。

可以把用例转换成 markdown 的表格模式

这里的路子跟 robot framework 是反着来的。

把代码转成了更容易阅读的表格,对用例评审来说还是很有用的。

https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/case_plans.md

智能等待

selenium base 的 api 很多都是操作类型的,比如 click,type 之类,在进行操作时 selenium base 会进行智能等待,从而提升用例的稳定性。

看起来有点用但实际用处有限的ai测试工具coTestPilot.ai

最近看到一款新发布的 AI 自动化测试工具 coTestPilot.ai,项目主页在这里

这是由 Checkie.AI 的测试专家开发的开源扩展,为自动化测试带来了额外的 AI 功能。该项目旨在通过简单集成现有的 Playwright 和 Selenium 测试,使每个自动化工程师都能享受到 AI 给测试带来的便捷。

什么是 coTestPilot?

coTestPilot 是 checkie.ai 和 testers.ai 上可用的 AI 测试 agent 的轻量级版本。它通过利用 GPT-4 Vision 分析网页,为 Playwright 和 Selenium 扩展了自动化测试和缺陷检测的 AI 能力,以识别潜在问题、不一致和可用性问题。

最棒的是,只需添加一个函数调用,就可以为现有的测试自动化添加 AI 驱动的检查。

主要特点

  • 多样化测试角色:内置多个测试 agent 配置文件,包括 UI/UX 专家、无障碍专家、安全测试人员等
  • 可定制检查:轻松添加自定义测试规则和专门的提示
  • 全面分析:识别视觉错误、内容不一致和功能问题
  • 详细报告:生成包含屏幕截图和详细问题描述的 HTML 报告
  • 速率限制和重试逻辑:内置 API 速率限制保护

为什么使用 AI 测试 agent?

传统的自动化测试擅长检查特定的预定义场景,但常常会忽略人工测试人员会立即发现的意外问题。coTestPilot 通过为自动化测试套件添加一个 AI 驱动的"额外视角"来解决这个问题。 AI agent 可以识别如下问题:

  • 元素错位和视觉缺陷
  • 内容不一致和拼写错误
  • 无障碍问题
  • 基本安全问题
  • 性能预警
  • 用户体验问题

入门指南

以 selenium 的版本为例。

Playwright v1.50.5发布了

Playwright v1.50.0 引入了多项值得关注的功能和改进,旨在提升测试体验。以下是这些新增功能的详细概述,并附有示例以说明其使用方法。

Runner 增强

1. 步骤超时配置

现在可以通过 timeout 选项为单个测试步骤指定最大运行时间。如果某个步骤的运行时间超过此限制,测试将失败。

示例:

test("example test", async ({ page }) => {
  await test.step(
    "step with timeout",
    async () => {
      // 此步骤必须在 1000 毫秒内完成
      await page.click("#some-button");
    },
    { timeout: 1000 }
  );
});

2. 跳过测试步骤

新增的test.step.skip()方法允许跳过特定的测试步骤,这在某些条件未满足或功能尚未实现的情况下非常有用。

示例:

test("some test", async ({ page }) => {
  await test.step("before running step", async () => {
    // 正常步骤
  });

  await test.step.skip("not yet ready", async () => {
    // 此步骤将被跳过
  });

  await test.step("after running step", async () => {
    // 即使上一步被跳过,此步骤仍会运行
  });
});

3. ARIA 快照存储于单独文件

expect(locator).toMatchAriaSnapshot()方法已扩展,允许将 ARIA 快照存储在单独的 YAML 文件中,便于更好地组织和版本控制。

示例:

test("ARIA snapshot test", async ({ page }) => {
  await page.goto("https://example.com");
  await expect(page.locator("body")).toMatchAriaSnapshot();
});

在此示例中,ARIA 快照将存储在对应的 YAML 文件中。