点击蓝字
关注我们
第十六章 测试策略应用
16.2.1 AI工具现状
我们大多数人都了解线性回归,即利用成千上万的数据点,通过算法拟合一条直线并进行预测。2022 年 11 月,OpenAI 基金会发布了 ChatGPT,可以看作一种文字的线性回归工具。换句话说,ChatGPT 吸收了互联网上的大量内容,并分析了每一个单词。给定几个单词,它就能够预测下一个单词。许多人都曾在搜索引擎的搜索栏中注意到过这种效果。
ChatGPT 则更进一步,通过对话界面,你可以向 ChatGPT 提问并获得答案。你可以给它四五个要点,让它创作一段文字,或者给它一段文字进行润色。除了本章的示例外,本书的创作过程并未使用ChatGPT。这种类型的人工智能被称为大语言模型(LLM)。LLM 需要较大的算力支持,不过这个需求正在逐渐降低。
截至 2023 年 4 月,请求一次的成本约为36 美分。ChatGPT 的界面是问答形式,尚不清楚该工具可以免费多久。本章示例使用的是 ChatGPT 3.5,在编写本书时,ChatGPT 4.0 版本需要支付订阅费用。
除了大语言模型外,另一项近期的 AI 创新是图像生成工具。这类工具能够实现局部重绘或替换,进行三维建模,甚至改变角色的角度。它们可能需要输入一个基础图像或一段文本。不过,无论是模型所用的基础图像,还是所用的文本,都有可能引发版权问题。
在本章中,我们希望站在一个更为中立的视角,介绍当下 AI 在测试领域真正能够做到的事。接下来的示例并不全面,毕竟这只是书中的一章。我们的目标是让你对 AI 在当下能够发挥的作用有一个切实的认识。
16.2.2 应用 AI 进行测试
一个严格遵守测试驱动开发(TDD)原则的开发人员可以使用像 ChatGPT这样的工具来创建单元测试。
例如,假设你要在 C 语言中创建一个名为 powerOf 的方法,其声明如下:
intpowerOf(int base, int power);我们使用了以下的提示词来请求 ChatGPT :
我有一个在C语言中定义的函数powerOf(),它接收两个整型参数,返回第一个参数的幂运算结果,指数由第二个参数指定。你能给我十个测试示例,以CSV文件的形式呈现,其中包含第一个数、第二个数以及预期结果,使用的数306软件测试策略Software Testing Strategies字介于0到10之间吗?
这里讨论的 PowerOf 函数声明如下:int PowerOf(int base, int power),你能用cppUnit 创建一些针对这个方法的单元测试吗?
ChatGPT 给出的结果如下:
voidtestPowerOfPositive(){CPPUNIT_ASSERT_EQUAL(8, PowerOf(2, 3));CPPUNIT_ASSERT_EQUAL(9, PowerOf(3, 2));CPPUNIT_ASSERT_EQUAL(1024, PowerOf(2, 10));}voidtestPowerOfZeroExponent(){CPPUNIT_ASSERT_EQUAL(1, PowerOf(5, 0));CPPUNIT_ASSERT_EQUAL(1, PowerOf(10, 0));}voidtestPowerOfNegativeExponent(){CPPUNIT_ASSERT_EQUAL(0, PowerOf(4, -2));CPPUNIT_ASSERT_EQUAL(0, PowerOf(7, -3));}
需要注意的是,这些示例更像是弱性检查或确认性检查。它们本身并没有问题,但是覆盖程度有限。最后一组对负指数的测试特别有趣,4 的−2 次幂实际上应该是 1/16,但整数类型不能表示像 0.025 这样的数,所以代码告诉我们的答案是 0。
接着,我们要求 ChatGPT 测试边界、非法输入和溢出情况,它生成了以下示例:
voidtestPowerOfOverflow(){// 测试大指数情况下的潜在溢出CPPUNIT_ASSERT_EQUAL(0, PowerOf(10000, 10000));}voidtestPowerOfBadData(){// 测试非法数据(如负底数与负指数)CPPUNIT_ASSERT_EQUAL(0, PowerOf(-2, 3));CPPUNIT_ASSERT_EQUAL(0, PowerOf(2, -3));}
这些代码片段带来的疑问可能比解决的问题还多。比如,10000 的 10000 次幂的结果必然远超 int 类型的范围,但返回值真的是 0 吗?或许更合理的做法是抛出异常并通过try/catch捕获。并且−2的3次幂结果并非0,而是−8。由此可见,虽然可以利用 AI 工具来生成测试代码,但最终还是需要开发人员检查和把关。
在测试 10000 的 10000 次幂这类运算时,耗时是核心关注点。可以考虑在调用运算的代码中嵌入计时器,并设定一个合理的阈值。任何调用的耗时都不应超过 0.25 秒,这个时间大致相当于人类感知延迟的临界值。AI 工具或许能协助编写此类测试代码,但目前尚无法独立提出这样的测试思路。
此外,根据我们的经验,真实的代码往往错综复杂,存在数量惊人的依赖关系。即便采用依赖注入模式,代码生成工具仍可能需要理解基础对象的工作方式。
GitHub Copilot 作为首个将代码补全与集成开发环境(IDE)深度整合的工具,能够处理一些简单任务。例如在 Visual Studio Code 中,当我们要求它生成一个用于验证电话号码的正则表达式时,它给出了另外十个建议,但其中九个是相同格式的日期验证表达式:
phone_number_regex = /(\d{3})-(\d{3})-(\d{4})/#用于验证邮编的正则表达式zip_code_regex = /(\d{5})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/#用于验证日期的正则表达式date_regex = /(\d{2})\/(\d{2})\/(\d{2})/
截至本文撰写时,大语言模型的主要作用仍局限于帮助用户生成模板或示例代码,以及节省搜索时间。这并非真正意义上的自动化测试,而只是实现了测试工作中部分环节的自动化。
AI 在测试中的另一个潜在用途是测试数据生成。有许多工具可以生成一份名字和生日的列表,这些数据可能分布在一个范围内,并且还包括开始和结束日期,以实现有效的覆盖,这些日期可能会与系统日期重叠或不重叠。
但具有讽刺意味的是,ChatGPT 并不会这样做,因为它担心你会用它来进行欺诈。但是,我们可以使用 ChatGPT 来生成著名的三角形示例的测试数据。
AI 在测试领域的另一个潜在用途是测试数据生成。现有许多工具能够生成包含姓名、生日的数据集,这些数据可按特定分布规律生成,还能包含起止日期以实现有效覆盖(包括与系统日期重叠和不重叠的情况)。
但颇具讽刺意味的是,ChatGPT 并不支持此类功能,因其设计初衷是防止被用于欺诈行为。不过,我们可以利用 ChatGPT 生成经典的三角形测试案例。
三角形问题要求给出三个边长,边长数值范围从 0 到 10。然后,根据这三个边长判断构成的形状是不是等边三角形,还是根本不能构成三角形。我们要求ChatGPT 生成十个测试数据的示例。表16-1 是它给出的结果。

我们可以将 ChatGPT 当作先知。例如,将判断三角形类型的逻辑封装成方法,调用 ChatGPT API 请求十个随机示例,反复运行代码,每次都会得到不同的示例。
虽然这会给代码这样做能带来一种基于模型测试的感觉,而无需显式构建模型。但这种方式也存在潜在的问题,ChatGPT 的性能会随版本迭代发生变化,并且我们不能肯定在特定问题上其性能会变好还是变差。
使用 AI 工具生成测试数据是可行的,但你需要检查这些数据。我们建议批量生成大量测试数据,然后使用验证通过的数据进行测试,而不是在每次运行时都调用 API 来获取新的数据。
最近备受关注的另一种方法是让工具生成测试用例。例如,给定一个电子商务网站和特定的测试范围(如产品页面),AI 工具可以提供测试方案。像ChatGPT 这样的工具可以提供一系列测试思路,或者要求它使用流行的开源自动化库编写加载网页并执行点击操作的测试代码,它们有时能完成这类任务,或至少能节省编写时间。
此外,自动化测试中最棘手的问题通常是确定页面元素位置,在这方面,AI 工具的辅助效果显著。
本书作者:许祥 杨定佳 金鑫
... ...
点击阅读原文,查看独家连载
如果有小伙伴
想要分享技术、出版图书
欢迎进入公众号后台
发送“出书”联系我们~

夜雨聆风