我们可以在测试软件时假设用户不会对软件执行此类愚蠢的操作吗?


71

例如:在Web应用程序中执行表单的功能测试时,我们将通过输入不同种类的随机输入值来测试字段。

通常,作为Web应用程序的用户,我们实际上并未在字段中输入随机值。

那么,当生产中出现此类问题的可能性较小时,合并所有可能/可能不会导致错误的测试用例有什么用呢?

注意:上面的示例仅是示例案例;此类问题可能发生在任何种类的功能/模块中。

我问这个问题只是为了知道是否要遵循任何标准做法,或者它完全取决于产品,领域和所有其他因素。


4
可能相关:猴子测试,有其优点和缺点
Christophe

Answers:


190

您可能不会在Web应用程序的字段中输入随机值,但是肯定有人在那里执行此操作。

有些人是偶然输入的,其他人则是故意破坏应用程序的。在这两种情况下,您都不希望应用程序崩溃或表现出其他有害行为。
对于第一种类型的用户,您不希望这样做,因为这给他们带来了糟糕的体验,并可能使他们拒之门外。
对于第二种类型的用户,他们通常没有光荣的意图,您也不想让他们访问他们不应该访问的信息,或者不允许他们拒绝真正的用户访问您的服务。

测试的标准做法不仅是验证天气情况是否有效,而且还应验证是否探索了异常边缘情况以发现潜在问题,并确信攻击者无法轻松访问您的系统。如果您的应用程序已经因随机输入而崩溃,那么您就不想知道攻击者可以使用特制输入做什么。


16
然后有些事情不是人们做的。👽–
kojiro

110
或者他们可能试图输入其实际的法定名称,例如“ O'Malley”,“姓名”或“ Robert”);DROP TABLE学生;-”
l0b0

90
或者也许是真实的公司名称;拖放表“ COMPANIES”;-LTD

25
我认为可以通过强调,如果程序由于猫的随机输入在键盘上行走而崩溃而崩溃,那么几乎可以肯定的是,恶意输入会使程序崩溃(甚至更糟)。
phihag

11
而且,许多人输入随机输入是因为他们不想提供真实的数据(例如他们的姓名,生日等)。有些人还认为计算机像服务员一样聪明,可能会键入“去年”而不是“ 2016”,并希望您的应用程序像人类一样处理它。
a安

102

永不承担任何责任

您不能假设任何用户不会因意外或故意对软件进行任何“愚蠢”的操作。用户可能会不小心按下错误的按钮,猫会在键盘上走动,系统可能会发生故障,其计算机可能会受到恶意软件的劫持等。

此外,用户本身可能是恶意的,有意寻找破解软件的方法,以期希望他们找到一种利用软件的方法来发挥自己的优势。即使他们发现了无法利用的错误,知道自己缺少QA程序的情况下,发现的任何内容仍可能促使他们探查系统中可以攻击的内容。

就测试而言,防止随机输入是很有用的,但是完全随机选择测试输入(即不考虑任何用例或边缘用例的情况)几乎是无用的。测试的目的是根据雇主/客户/用户的要求和期望来验证您的解决方案;这意味着您需要专注于针对所有边缘情况和边界条件,以及与用户预期工作流程不符的任何“退化”情况。

当然,您可能会运行测试,以发现后来您认为不值得修复的错误。这可能是出于各种原因-该错误相对于其对用户的影响而言可能过于昂贵而无法修复,或者您可能会发现没人使用的功能中的错误,或者该错误可能已经很好地建立在系统中,以至于有些用户将其视为功能。

或者,您可能正在编写某些定制软件,这些用户的“专家”用户非常有限,而花时间修复错误并没有商业利益,因为这些用户能够使用错误软件来完成工作(例如,诊断工具内部IT团队使用的收入不会带来任何收益,因此,如果它偶尔崩溃,那么没人会愿意为修复它而花费时间-他们只会告诉IT团队忍受这些错误。 。

但是,只有知道这些错误,您才能做出这些决定。例如,用户可能输入恶意输入,从而抹去了整个数据库-如果您尚未针对这种情况进行明确的保护和测试,那么您将无法确定这种情况是否会发生。将未发现的错误留在系统中的风险意味着,如果其中一个错误在现实世界中暴露出来并对您的用户产生重大影响,则可能使您面临真正的问题。

因此,虽然是否要修复错误的决定可能需要软件所有者(通常是谁付钱给谁)的一些输入,但是是否要测试错误以及要测试哪种情况的决定是需要解决的工程问题。考虑到估算和项目计划,在时间/金钱/资源的限制下,目标应该是尽可能合理地接近全部覆盖范围。


12
尽管完全随机地进行测试是没有用的,并且您当然应该显式地测试尽可能多的极端情况,但是一定数量的随机模糊有时对于检查您可能无法预见的问题也很有用。
肖恩·伯顿

10
我们有一句话:“编写防傻瓜软件太困难了,因为傻瓜是如此聪明。” 因此,请测试“废话”输入!
拉尔夫·克莱伯霍夫

For example, a user may enter a malicious input which wipes the entire database - if you haven't explicitly protected against and tested for this scenario, then there's no way you can be sure whether or not this can happen.这个 XKCD漫画中的小Bobby Tables一样吗?;)
nick012000

12
“永远不要承担任何责任。” 我认为这是个好建议。
candied_orange

感谢您指出并非所有的“错误”都是“修复”。了解边缘情况和花费时间和金钱修复边缘情况有很大的不同。允许将任何可能的输入输入到Web表单并在所有情况下都具有固定的响应肯定会很好,但是也许与您的特定软件无关。也许您的输入只允许在前端输入数字,所以不可能在后端接收非数字。“修复”仅在数字中包含非数字的潜在错误是浪费时间和金钱。
EvSunWoodard

60

有几个因素需要考虑。为了说明这些观点,我将使用一个字段示例,在该字段中,用户应在为特定任务定义的配额的上下文中输入百分比,以该任务可以使用的磁盘空间为单位。0%表示该任务将无法向磁盘写入任何内容;100%表示任务可以填满所有磁盘空间。中间的值表示它们的含义。

作为开发人员,您可能正在考虑可接受的值为[0、1、2、3,⋯99、100],而其他所有内容都是愚蠢的。让我们看看为什么用户仍然可以输入那些“傻”值。

错别字

%^

用户输入的值是56,但Shift在输入时误按了(例如,因为在法语键盘上,您必须按Shift输入数字,并且用户不断在法语键盘和QWERTY之间切换)。

以相同的方式,您可以获得一个数字,该数字在其之前或之后或之间:

56q

在这里,用户可能正在输入数字,然后输入制表符以移至下一个字段。  ⇆  用户没有按,而是按了邻居键。

误解和误解

空输入可能是最常见的。用户以为该字段是可选的,或者不知道该字段中要放置什么。

56.5

用户认为浮点值是可以接受的。用户错了,应用程序应该礼貌地解释为什么只接受整数值,或者初始要求错了,让用户输入浮点值是有意义的。

none

用户误解了,当被问及任务可能占用的空间时,该应用会期望有一个数字。这可能表明用户界面不佳。例如,询问用户“任务应占用多少磁盘空间?”邀请进行此类输入,而带百分号的字段将收到较少的此类输入,因为“无%”不会很有道理。

150

用户在这种情况下误解了百分比的含义。也许用户想告诉该任务可以占用当前使用空间的150%,所以如果在2 TB的磁盘上使用了100 GB,则该任务可以使用150 GB。同样,更好的用户界面可能会有所帮助。例如,与其在裸露的输入字段上附加百分号,不如将其添加为:

[____] % of disk space (2 TB)

当用户开始输入内容时,它将即时更改文本,使其变为:

[5___] % of disk space (102.4 GB of 2 TB)

制图表达

大数字或带有浮点数的数字可以不同地表示。例如,一些1234.56可以写这样的:1,234.56。根据文化的不同,相同编号的文本表示形式也会有所不同。在法国,同样的号码将被写成这样:1 234,56。看到,一个逗号(不要期待)和一个空格。

始终期望使用特定语言环境的特定格式会或早或晚给您带来麻烦,因为来自不同国家/地区的用户会有不同的书写数字,日期和时间等习惯。

人与计算机

Twenty-four

普通人与计算机的想法不同。“二十四” 实际数字,与PC会告诉您的内容无关。

尽管(1)大多数系统不能完全处理这种类型的输入,并且(2)几乎每个用户都无法想象输入用全字母写的数字,但这并不意味着这种输入是愚蠢的。艾伦·库珀(Alan Cooper)在《关于面孔3》中指出,不处理此类输入表示计算机无法适应人类,并且理想情况下,该界面应该能够正确处理这些输入。

我唯一要添加到艾伦·库珀(Alan Cooper)的书中的是,在许多情况下,数字是错误地用数字写的。计算机希望用户犯错(并且不会容忍写得正确的用户)的事实令人讨厌。

统一码

5𝟨

Unicode保留了自己的惊喜:看起来相同的字符并不相同。不服气吗?复制粘贴"5𝟨" === "56"到浏览器的开发人员工具,然后按Enter

这些字符串不相等的原因是Unicode字符𝟨与该字符不同6。这将导致生气的客户打电话告诉您的应用程序无法正常工作,提供看起来合法的输入屏幕截图,并且您的应用程序声称该输入无效的情况。

您会问为什么有人要输入看起来像数字的Unicode字符?虽然我不希望用户无意间输入一个字符,但从其他来源复制粘贴可能会导致这种情况,而且我遇到了这样的情况:用户实际上对包含Unicode字符的字符串进行了复制粘贴,而不会出现在屏幕上。

结论

这些是您获得基本数字输入字段的情况。我会让您想象一下,对于更复杂的表单(例如日期或地址),您必须处理什么。

我的回答集中在您所说的“傻”输入上。测试不是要检​​查幸福的道路。这还与当恶意用户有意输入奇怪的东西并试图破坏它时,检查您的应用程序是否不会中断有关。这意味着当您要求提供百分比时,还必须测试当用户使用包含1,000,000个字符,负数或bobby table的字符串进行响应时会发生什么。


9
啊,U + 1D7E8:数学无衬线数字六。
Andreas Rejbrand '17

23
换另一个unicode字符:在日文键盘上,从普通数字切换到全角数字(这是一个与汉字一样宽的数字)是很常见的。因此,日语用户可能输入了日语(而不是英语),并且不小心输入了全角数字。

3
在看到有关同一个象形文字问题的5分节之前,我实际上是在期待一个1 234,56字符串(使用U + 00A0 NO-BREAK SPACE而不是U + 0020 SPACE),这是编入这些数字标记(或使用U + 202F的正确方法)窄边休息空间,peroahps)。在呈现给用户之前,从任何根据语言环境对数字进行格式设置的应用程序中复制值,将非常容易产生该值。
安赫尔

4
复制粘贴是一个更大的麻烦。常见的做法是复制粘贴空格,换行符,不可见的字符...
Sulthan

7
@Arseni Mourzenko您一定很幸运。从例如PDF和粘贴复制易于粘贴各种字符,这可能是不可取取决于队伍现状,如连字(用于网络连接等),智能引号,EN或者ASCII减去被期望的破折号,等等
罗西˚F

12

这里有很多很好的答案来描述为什么这很重要,但是关于如何合理地保护应用程序却没有很多建议。“标准做法”是在客户端和服务器上都使用可靠的输入验证。不明智的输入很容易被抵制;您只是拒绝在特定情况下没有意义的任何事情。例如,一个社会保险号仅由破折号和数字组成;您可以放心地拒绝用户在社会保险号字段中输入的任何其他内容。

对您编写的每个应用程序都应进行两种测试,每种测试都有不同的用途。您在自己的应用程序上进行的测试肯定测试;其目的是证明该程序有效。 测试人员还对您的应用程序执行的测试是负面测试;其目的是证明您的程序不起作用。 你为什么需要这个?因为您不是测试自己的软件的最佳人选。毕竟,您已经写了东西,显然它已经可以了,对吧?

在编写输入验证时,您将采用积极的测试来证明您的验证有效。测试人员将使用随机输入来尝试证明它不起作用。请注意,随机输入的问题空间实际上是无限的。您的目标不是测试所有可能的排列,而是通过拒绝无效输入来限制问题空间。

还要注意,最终用户并不是唯一向程序提供输入的人。您编写的每个类都有自己的API和对有效输入的约束,因此,可靠的验证(即“代码约定”)对您的类也很重要。这样做的目的是对您的软件进行强化,以使意外行为很少或根本不存在。

最后,工作流程很重要。我看到了应用程序崩溃的原因,不是因为用户输入了一些不合逻辑的内容,而是因为它们以意外的顺序在应用程序中执行了操作。您的应用程序应该意识到这种可能性,并且可以优雅地处理意外的工作流,或者要求用户按照您指定的顺序执行操作。


期望有特定顺序的应用程序的一个常见示例是“拆卸”功能,该功能释放从未保留的句柄。
wizzwizz4

2
不幸的是,标准做法是拒绝任何没有意义的内容,并使用户感到困惑和沮丧。正确的做法是准确地解释(例如,使用错误消息/反馈)拒绝输入的原因,以便用户知道如何更正输入并使输入被接受。一个简单的“从1到100获取整数”至少需要4条不同的错误消息(空字符串,不支持的字符,太大,太小);加上测试以确保在每种情况下都能给出正确的反馈。
布伦丹

2
@Brendan:只需输入一条消息:“此数字必须介于1到100之间。” 用户不知道(也不需要知道)什么是字符串,或者“不支持的字符”是什么意思。这些是程序员的影响,而不是用户的帮助。
罗伯特·哈维

@RobertHarvey我可能会在该语句上加上一些“由数字组成”的字眼。因为输入“ Seventy-Nine”是介于1到100之间的数字,但不是大多数程序可以使用的输入。
迪洛斯(Delioth)'17

1
@Delioth:你不能解决愚蠢的问题。
罗伯特·哈维

11

通常,“随机”值不是随机的。您正在尝试捕获极端情况,即“未知未知”。

举例来说,#字符会使您的应用崩溃。您事先不知道这一点,因此不可能为每个可能的输入编写测试用例。但是我们可以写一个测试"¬!"£$%^&*()_+-=[]{};'#:@~,./<>?|\",看看它是否损坏


2
+1令人惊讶的是,乍看之下那些随机字符经常发现错误。来自用户输入的数据可以通过许多组件/服务进行大量传播。它只需要链中的一个组件,而不会对其进行正确处理,从而导致系统出现错误。

4
尤其是 现在,所有移动键盘都带有表情符号
Ewan

对于.Net开发人员而言,IntelliTest工具(以前称为Pex)确实是锻炼代码路径以查找边缘情况的好方法,它在输入验证和获得良好的代码覆盖率方面特别有用。
詹姆斯·斯内尔

7

我曾经写过一个程序,并在一个有60名学生的实验室中进行了现场测试。我站在60个计算机屏幕的后面,看到他们正在使用它。他们做的荒唐之举令人毛骨悚然。看着他们的“创造力”,我浑身是汗。他们所做的远远超过任何一个人一生中都能幻想的事情。当然其中之一打破了它。

之后,我遵循一种方法: if "a very specific use case" do, else show error

如果我有几个用例,我会严格定义它们并将其链接起来。


1
然而,这些具体的使用情况很可能是过于具体。我们总是低估有效输入的空间。(O'Hara,本地格式的小数等)。准备处理多少金融程序来处理负利率?
古兰经

6

您要描述的是Fuzzing或Fuzz Testing:向系统抛出随机和无效的输入,然后看看会发生什么。您不这样做是因为您希望用户这样做。您这样做是为了暴露您自己的假设和偏见,以强调系统的边缘以查看发生了什么。

由人类编写的正常测试输入将带有假设和偏见。这些偏差可能是某些类别的错误无法通过测试发现的。

例如,如果您的大多数输入都在ASCII安全的Unicode范围内,则不会执行有关代码中字符编码的假设。也许它总是小于特定大小,因此不会命中固定大小的字段或缓冲区。也许有一些特殊的字符以令人惊讶的方式被解释,从而暴露了用户输入正被馈送到shell或用于以不安全的方式构建查询。或者,也许有太多的“快乐之路”测试,而没有足够的尝试来执行错误处理。

模糊测试对输入没有这种先入之见。它将通过“有效”输入的任何可能组合来残酷地锻炼您的系统。Unicode,ASCII,大,小以及很多错误。您的系统应优雅地响应所有这些。它永远不会崩溃。用户应该始终获得有关出了什么问题以及如何解决的明智信息。不是垃圾输入/垃圾输出,而是垃圾输入/错误输出

尽管可能会因为“没有真正的用户会这样做”而消除由此产生的爆炸,但这却错过了练习的重点。模糊测试是消除您对可能输入的偏见的一种廉价方法。这是一种廉价的方法,可将用户尝试将所有奇怪的事情扔到您的系统上。作为工程师,您的工作是确保系统正常运行。


此外,模糊“输入”不仅仅与用户有关。它可能表示对第三者服务进行API查询的结果,如果它开始发送混乱的结果怎么办?您的系统如何处理?正确的系统应警告管理员组件已损坏。一个不正确的系统将悄悄地拒绝错误的查询,或者更糟糕的是,将其接受为良好的数据。

最后,一些用户是恶意的。如果您不对系统进行模糊测试,则其他人会进行测试。他们将探测系统边缘的常见错误,并尝试将其用作安全漏洞。模糊测试可以在某种程度上模拟这种情况,并且您可以处理在安全漏洞成为问题之前发现的任何可能的安全漏洞。


并且有做类似事情的Quick Check测试工具
icc97 '17

4

如果您的目标是创建优质产品,请测试用户将能够实际提交的每种可能的输入类型。否则,您只是在等待某人提交一种您不需要进行测试的输入的那一天。

在我工作的地方当局对新的电子拍卖软件进行的大规模展示中,我的经理断定(承认有一些恶作剧),他认为有必要看看如果他以负值进行拍卖时会发生什么。令我感到真正惊讶的是,拍卖软件允许这种毫无意义的投标,整个拍卖过程都停止了。所展示的拍卖类型绝不应该允许提交负数。

大批组装的采购和财务人员中的一些人因我的经理提出了荒谬的价值而感到恼火。但是其他人,包括我自己,对软件开发人员感到恼火,因为他们没有测试并拒绝这种明显类型的无效输入。我只能想象该软件在偏转其他类型的无效输入(代码注入尝试,数据库表中无法表示的外来字符等)方面必须具有多弱的能力。

由我自己决定,我将退还该软件,并认为它不适合其用途。弱软件产品与强软件产品之间的区别在于其所经受的测试水平。


2
test every possible type of input that a user will be physically able to submit.-问题空间本质上是无限的,您通过尝试全部测试来浪费时间。检查负输入是一个单一的分支。这不仅是明智的,而且也是有能力的开发人员所期望的。您不必检查每个负数即可证明这种验证有效。
罗伯特·哈维

13
这就是为什么我说的每一个类型的输入,而不是每一个可能的输入。我会重复我的观点:如果您不测试每种输入类型,那么用户最终会进行测试。
Arkanon

1

例如:在Web应用程序中执行表单的功能测试时,我们将通过输入不同种类的随机输入值来测试字段。

是。这是一种测试,但不是功能测试。这就是所谓的压力测试。向系统施加压力以查看它是否可以处理它。

那么,当生产中出现此类问题的可能性较小时,合并所有可能/可能不会导致错误的测试用例有什么用呢?

当您进行压力测试软件时,您试图发现该软件极限的界限。

这些测试本质上是详尽无遗的。在需要发现使用限制,断点,检查所有逻辑分支或查看部分故障如何影响整个系统的地方。

您可以使所有功能测试通过,但仍无法通过压力测试。

我问这个问题只是为了知道是否要遵循任何标准做法,或者它完全取决于产品,领域和所有其他因素。

是的,这是标准做法。

测试软件是关于询问预期行为的问题,当所有测试通过时,这表明软件可以按预期运行。这就是为什么测试为部署更新提供了良好的前提条件的原因。

压力测试没有提供明确的特定通过或失败指标。结果更具参考价值。它告诉您系统可以处理的内容,并根据这些信息做出决策。

您可以定义压力测试的特定目标,必须通过这些目标才能继续进行开发的下一阶段。这些可以包含在质量保证过程中,但是环境的变化会改变压力测试的结果。因此,人们在不同时间运行压力测试,以了解系统如何处理不断变化的条件。

我的意思是,您不能在每次部署新版本的软件时都进行压力测试,并且认为这意味着以后所有事情都将通过压力测试。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.