批判式思维教你如何从源头消除缺陷

来源:互联网 发布:sqlserver删除一行数据 编辑:程序博客网 时间:2024/05/16 01:41

苏瑞
本文系外文翻译,文章后面有译者结合所服务项目的实践案例,原文链
接:http://www.compendiumdev.co.uk/nlp/NLPForTesters(MetaModel).pdf
简介篇
NLP元模型能为测试做什么?
“……这个元模型的目标不是帮助我们找到‘正确的’答案,而是提出更好的问题–扩展我们对世界的认识,而不是找到‘正确的世界地图’。NLP元模型审查系统的目的是帮助我们识别缺失的信息、无意识的假设和参考的经验,根据这些信息来建立对于世界更深层结构的意识。”
——NLP百科 Robert Dilts (罗伯特·迪尔茨)
NLP元模型为测试人员提供了一种简单的模型,包括:
3类产生混淆的形式——删减、扭曲和归纳
12种易于识别的违背交流原则的方法
这里写图片描述
NLP元模型的用途:
应用NLP元模型在接收到信息时,在代码编入系统前及早识别表达不明确的地方和潜在错误。
一、在需要传递信息时应用NLP模型可以:
1.改进缺陷报告
2.帮助他人理解我们想要表达的
3.改进开发团队/测试团队间的关系
二、应用NLP元模型来识别测试范围
1.文档上说系统会始终这么做,如果我发现某些条件下系统 没有这干?
2.这个对话框的目的是什么?我要怎样证明那个假设不对?
三、为测试人员提供一个简单、高效、可重复的分析文档的方法思维
四、将NLP应用在我们信任的环境中,提供一套思考测试上下文框架
NLP是用于探究、发掘交流沟通中那些容易产生歧义的点的一套系统。
由Richard Bandler和John Grinder与20世纪70年代编写的《The Structure of Magic智能的结构》(以下简称SoM1),是一项语言和将语言应用于治疗学的研究。SoM1提供了一套语言表达的正式模版,旨在被更好的理解、传授和应用于治疗学和非治疗学。
这里提到的正式模版,即被称为元模型,由转换语法的理论组织起来。在这套语法体系下,我们日常写作沟通的内容,是我们要表达的深层内容的一个表象结构。我们通过处理转化结构的方式来表达我们的深层思想。
这里写图片描述

举例来说,如果我告诉你“我买了一台电脑”这句陈述就是深层结构的一个表象。深层思想包含了我关于买电脑的全部记忆,如下:
1.决定要买哪款电脑的策略
2.关于选择这款机型前放弃的全部型号电脑的记忆
3.我买这台电脑的感受
4.买电脑的费用
5.电脑是否值这么多钱
6.销售电脑的店面/店员长什么样
7.从哪里买到的电脑
8.那个店看起来怎么样
9.将电脑带回家的感受如何
以上这些信息都在我将深层结构转化为表层结构然后传递出去的过程中省略了。但是所有这些信息在你问到时都是可达的。
过段时间后,电脑可能会崩溃,可能会有硬件的问题,我可能会开始觉得买的这台电脑并不是一个划算的交易并且我开始表达“我买了一台电脑”时对此感觉很糟糕。这时我不仅忽略了“那是我当时能买到的最好的电脑”这一信息,同时我开始曲解深层信息并因此而影响我对事实的看法。此时深层思想依然是可达的,并且随着正确的质疑,我可能会意识到“我在那时买了台最好的电脑”,和“我当时买的那台电脑,现在遇到很多问题”是代表我深层想法的截然不同的两种表层陈述方式,而这两种表述的效果也会完全不同。
NLP元模型将信息从深层结构到表层结构的转化归为三类:归纳 、扭曲和删减。
识别信息传输过程中的删减、扭曲和归纳,我们可以对一个陈述进行深层的分析并提出以下问题:
1.哪些信息是被泛化了,哪些信息是隐含在陈述中的
2.会有哪些可能导致问题的信息在传递时被省略了
3.哪些信息被扭曲了,或者表达的不够充分
NLP元模型进一步将这三类细分为12个要素:虚泛词式(Nominalization)、因果式(Cause-Effect)、猜臆式(Mind Reading)、相等式(Complex-Equivalent)、价值判断式(Lost Performative)、以偏概全式(Universal Quantifiers)、能力限制式(Modal Operators)、假设(Presuppositions)、简单删减(Simple Deletion)、比较删减(Comparative Deletion)、名词不明确(Unspecified Nouns)和动词不明确(Unspecified Verbs)。每一个要素将在下文中展开并详细解释。
这12要素中的每一个都与可识别的人们之间交流信息的语言模式相符,并且都有一些关联性的问题来帮助我们更好的挖掘信息中的深层结构。
这里写图片描述

这些信息之所以重要是因为:
1.人们交流时有些信息的表达是含混的
2.含混不清的地方对信息传播者和接收者都是有害的
3.识别信息中的歧义是可传授的
4.消除歧义并设法澄清是可行的
5.澄清信息对信息传播者和接收者都有帮助
6.软件开发就是一个人与人之间传播信息的过程
大多数软件测试人员都碰到过这样的问题:需求看起来被所有人理解,但事实上各个角色在实施过程中都有不同的理解。这很有可能会导致软件缺陷、延期、伤害用户、返工以及一连串问题。
这不仅仅是需求的问题,详细设计、缺陷报告、测试策略,事实上在软件开发过程中任何传播信息的过程都可能会被含混的表达所影响。
软件开发过程中由沟通导致的问题不仅局限于交付品上,“消息从一个人向另一个人传播时每次都发生一些变化”效应贯穿在软件开发的整个生命周期中。许多跨团队协作的问题就是由于沟通导致的。因此,学习并实践NLP元模型可以有效帮助测试人员理解和解决这些问题。

应用篇
NLP元模型和软件测试详解
以上概要的介绍了NLP元模型,接下来会详细介绍如何将其应用于软件测试领域。
大多数情况下软件测试是一个无限期的任务,总是存在一个可执行的测试任务。NLP元模型同样是无限期的,它提供了一套用于发掘用户深层结构并转化为表象结构的方法。表层结构的描述则由另一套元模型来探究。
就像我们不是为了测试而测试一样,元模型也不是为了信息而发掘信息。测试团队获取信息是为了影响开发团队对于系统的认知。使用元模型获取信息是为了更好的理解客户。测试人员在任何可能导致理解上有偏差的信息上都可以提出问题并探究必要的信息。
当以元模型的视角分析以前测试过的项目时,我发现大多数用到的测试方法都跟概化和省略有关。我设计了足够细致的测试用例来确认两种转化间的信息。
我发现的许多需求和详细设计的问题也可以跟概化和省略有关,我提出一些简单的基于元模型的问题来确保他们表达的足够清晰。这些使得测试团队可以更好的影响并与参与软件开发过程的其他角色协作。
然而,许多跨团队沟通的问题却是起源于扭曲。
注:元模型的每一个要素都没错,而其是否真的合适则取决于所使用的上下文场景。元模型可以发现软件开发沟通过程中表达含混的地方,而这些点则很可能导致软件错误

归纳
归纳是一种基于过去经验来建立规则或模型的过程。
我碰到的软件开发过程中因未明确定义的归纳而导致的问题如下:
随着测试阶段的深入,人员发现的异常越来越多,更多细节被暴露,开发人员不断修改代码,代码数量急剧上升,测试难度原来越大,软件更易于出错和难以维护。
这里如果那些泛化的地方能早些被识别,就会有不同的实现方案,而这很可能会减少缺陷或错误的发生。
许多系统处理不了的情况,都是由于系统架构在建立时没有对预设环境考虑周全。
例如,一个文件系统的定期失败,归结于文件损坏和由于多进程同时访问同一文件造成的资源竞争,如果这一情形能在早期被识别并采取措施,使用数据库将是个更有的解决方案。
系统崩溃的原因,则往往是由于设计阶段对规则定义的不全面,且没有足够的容错处理。
错误格式的文件传入系统时将会导致崩溃的发生。
归纳是软件研发交流过程中应用最广泛的元模型之一。我们都有过这样的经历:有缺陷的归纳在早期没有被挑战而贯穿于整个研发过程中,最后导致问题的发生。接下来将探索如何识别并质疑泛化。

这里写图片描述

假设

到目前为止,大师思想的大意和战略原则已经清晰,终于,他开始探索下一步的最佳实践。他将进一步确认哪些行为是可能并且符合他计划的。然后他将开始分析每个变量,对每一步进行审查:预见他人的应用策略,给出他的最佳实践并依此类推。完成他的巨大量任务后,纯粹的分析,Smyslov会停止并改变其中的一步吗,仔细考量然后继续!
像大师一样思考
———-Alexander Kotov, 1971

假设是陈述句中的一个元素,只有当假设为真时整个陈述才能为真。
假设分析是研究一个系统的方法之一,通过假设分析了解系统哪些场景可能会出错,识别“测试点”然后暴露问题。
当从他人那里得到信息时,首先识别他的陈述中哪些假设需要为真,因为当假设中的任何一个不为真是,整个陈述都不能成立,也因此不能为他的目标服务,这时我们应该帮助他们探究新的视角,给出选择并帮助他们建立有效的方案。
然而这篇文章是用于软件开发的,所以……下面这个需求中的假设是什么呢?
例如:
The daily trade file must be processed in under 5 seconds when the system starts up(每日交易文件必须在系统启动后5秒内被处理)
我列举了如下一些假设,以及测试人员对于这些假设的一些应。
这里写图片描述

更完整的关于这个需求陈述的分析见附录“元模型案例注释”

以上的需求是从以往项目中多个需求中组合而成的。类似的需求引起的含混的地方都导致了系统实现上的一些问题,归根结底都是因为潜在的问题没有被及时识别出来并解答。
1.假设通常被认为是理所当然并且不需要验证的,他们往往需 要被验证。
2.在需求文档中常常会发现一些需求中没有陈明的假设,如果这些问题没有 在早期被抓住,我们会陷入这样的场景:“用户”不知道自己需要什 么,需求则一直在变更。
3.假设分析可以帮助我们尽早识别潜在的问题,在系统实现以前对假设提出 质疑,从而发掘更深层次的问题。
4.假设是以测试的角度提出质疑的目标对象。
5.假设分析帮助我们确认测试的先决条件并设置测试顺序。这 一测试用例的先决条件是什么?确认这个,然后我们就能确定出测试的原则。
当我们与人交流时多想想他们为什么这么做时,就会熟悉设。“我要那样做的话必须相信什么?
找到测试点
当我面对屏幕、需求文档或者系统的功能集时,我开始思考将他们与假设联系起来。测试的方法是我是否能使这些假设中的一个不成立。
当治疗专家询问患者的问题导致患者情绪激动时,奇迹就发生了。
这一点在测试中同样有效。哪些测试用例会导致系统在基础实现上发生基本的错误?在这一点上,测试就是我们向系统提出问题。
我们提出第2个,第3个……第n个假设,依次向系统提问来分析这些预设。本节开始部分引用的Kotov的分支假设分析的流程就很好。
当顺着假设链向系统依次提问时,我们的假设越来越基础,当这些假设失效时我们很可能发现了使系统失效的测试点。这就是擅长探索式测试者们能快速有效攻破系统的一种方式。
例如:
The daily trade file must be processed in under 5 seconds when the system starts up.(每日交易文件必须要系统启动后5秒内被处理。)

第1步假设:每日交易文件必须存在
问题:这个文件包含了什么内容?
答案:可以被处理的信息
第2步假设:这些内容是有效的
问题:如果内容失效会发生什么?—这将是一个测试点
如何使用假设来测试的案例在测试文献中可以找到:James Whittaker 的《How to Break Software》第4章:测试文件系统接口,攻击6:修改或毁坏文件内容。
假设测试的方法同样适用于GUI系统的测试。
当面对一个屏幕时,当前界面需要哪些条件?
当界面是一个列表时
1.要展示的条目必须存在,如果不存在呢?我们是否能在系统中创造一个状态来展示列表项,删除后台生成展示列表记录,然后尝试打开这条记录。
2.展示的条目必须包含哪些信息,如果不包含呢?如果这些信息在别处被修改呢?我们是否能在系统中创造一个状态来修改数据细节,然后尝试打开并访问此列表?这些后台细节数据会被展示吗?还是列表详情数据会被展示?
测试人员随着经验的积累会学习做这些,有经验的测试人员有时也会照这步骤来执行,但仅仅是因为他们以前碰到过类似的缺陷,而不是按照假设分析的思路来思考。对我而言,学习“假设分析”帮助我更精准的应用探索式测试,多多练习实践,就能从中获取更多的益处。
以偏概全
(All所有,Never无,Every每一个) 多个:1个(Just that只是, 仅仅Only)
“他从来都不听我的”,“他总是欺负我”。在治疗学的语境中,这些表达会导致当事人对事物的片面认识,这时治疗专家需要挑战并进一步扩大当事人碰到的概率。
当以偏概全的标识词汇出现在软件文档中“系统将一直……”“系统不会……”这些都需要引起测试人员很多的思考:
1.这类陈述将隐含一系列反例,它限制了软件的行为,需要 尽早对其提出 挑战以确保对异常场景考虑周全。
2.具体构造的测试集所识别出来的陈述中的异常场景也可以被归结为缺 陷。
3.测试人员需要考虑如基于组合测试数据生成技术(正交数组、全排列组 合)的测试数据策略,为被测对象准备充足的数据集。
4.边界值分析,或者更具体地说,域测试技术可以应用于这种情况。我们 可能遇到的是无限域,或者没有清晰边界值的域。
测试过程改进的一部分就在于检测我们软件测试过程的教义以及识别这些教义中哪些是有益的哪些是无用的。我见过达到很高水准的成熟的软件测试过程:对于如何实施测试以及实施过程都有着严格的规定。
高效的测试过程改进(TPI – Test Process Improvement)要处理的合宜,这对于在测试过程中检查全称量词规则以及他们真实的通用性是很有帮助的。
1.永远不要让软件测试人员看源代码
2.永远不要让编写代码的人去测试自己的代码
3.要始终在执行测试之前写好测试脚本
4.所有的测试必须引用自需求
你会发现并不容易在日常项目中证明这些陈述是有道理的,测试过程改进的实施已经走得太远,生成规范多于提升测试效率的能力。
在软件测试过程或策略的文档,以及表达软件测试信念的文档上应用元模型。以上任一陈述是否也在遭受泛化转换的痛苦?
能力限制
应该(should),必须(must),能(could),需要(need),可能(might)
在与人交流时,能力限制词汇(情态动词)是情绪变化的有效手段。当我们用不同的情态动词交流时会取得完全不同的结果,如:“我必须洗这些餐具”,“我应该洗这些餐具”,“我可以洗这些餐具”,“我需要洗这些餐具”。自己在陈述时试试不同的情态动词,有些会激励你去做,有些假设你可能会忽略或者延期去做,有些则会因为用词的关系让你觉得反感。
在需求文档中,有些概率性的能力限制词汇会增加混淆。{可能,也许,经常}“系统可能需要重启”在何种条件下?在这种条件下每次都会重启还是可能会重启?是随机重启吗?
在评审文档时有意识地针对能力限制词汇提出具体问题,可以帮助我们量化需求,这对消除歧义是很有必要的。
注:元模型的应用,并不是让你在工作时向共事的人提出无止境的问题。
1.有经验的测试人员有能力在缺失一定信息的情况下工作
2.有经验的测试人员分析已知的信息,识别当前含混的地方是否可接受,然 后评估并指出表达不明确的地方存在的风险
3.有时问题并没有答案,但测试还是要继续进行,幸运的是,测试人员可以 通过向系统提问来探索他们的问题。
这里写图片描述
删减(Deletions)

 在收集信息的会议或面谈结束时,我总会问这样的问题:“还有什么我不知道而你还没有告诉我的信息吗?这些信息可能会阻碍我为你提供帮助。” 我已经太久都不记得从哪里听说的这类询问了,也不能随后将其归到你的学习计划中。但我发现基于识别删减信息及其所带来的影响这种方法在咨询时非常有用。通过提问可以探究到通过面谈时的反馈所得到的知识以外的被删减信息。 你是否碰到过这样的情况:你没有测试过软件的某些方面因为你根本不了解它们?删减在软件研发过程中会带来重大问题。

简单省略
简单省略是指在陈述中缺少必要的可能会引起混淆的信息。
“我烦了。”我们会假设发言者是厌烦了;他们可能之前说过对自己的工作感到厌烦,然后我们就会自然的假设这是他们现在的意思。但事实上他们可能只是对工作上某个细节的方面感到厌烦,而对工作还是很热爱的。我们将省略的信息作为目标去挖掘,“对什么感到厌烦?”“我昨天做了很多DIY,我很高兴回来工作而不需要继续画画了。”
“输入文件是通过邮件接收的。The input file is received via email”这句话存在明显的歧义,“通过谁来接收?received from whom?”
这句陈述中还有更微妙的省略“发送给谁?”,“什么时间接收?”,对于输入文件也有一系列问题:
1.文件的格式是什么?
2.文件的大小?
3.文件都包含什么内容?
最难发现的省略点,和导致主要问题的点,往往在于那些表面的陈述中没有提及到的地方。这就是本段开始时说到的“还有哪些信息是你没有告诉我的……”这句话如此重要。
有些情况下我们可以通过提出问题获取系统信息的方式来发现省略点,然后应用元模型问题在我们的系统中。只有将我们从表面陈述中获取的所有信息和识别出来的省略结合起来,才能发现更多基础的问题。有些省略可以通过假设分析来识别出来。
比较省略
你发现太多bug了——>与谁比较?
你没有发现足够的bug——>与什么比较?
比较对象指的是没有定义参照物。当一个陈述中含有比较省略时,这可能会被作为判定结果而非比较来被接受,而这就是问题产生的根源。
有时事物用来比较,只提到了负面事物而没有提及他们的优良属性。这在软件开发项目的开启阶段评估比较时和攻击项目后期相关人员时。
1.你没有执行足够的测试用例
2.与什么比较得出的结论?
3.这是个评估,我们在知道我们正在做什么和发现真实的任务范围前做出评估,呃,现在也许是需要重新审查我们的评估了。
“系统运行的太慢了。”与什么相比?也许是用户的需求。这里的省略也许反映出之前需求中没有提及到的地方。
主词不明确
主词指的是陈述中所参照的对象,当指代对象被它、他们、我们、那个等指代时需要进一步确认清楚。
对于缺失的主词的处理,就是识别对象具体指的是什么。
“The Users will want to do this. ”关于哪些用户尤其需要这么做的信息是缺失的。关于角色的概念和用户类型在测试过程中将非常有助于我们识别风险并生成测试场景。
动词不明确
未明确动词指的是陈述中缺乏这个动作如何实现。“系统将会处理这个”,如何处理?
如果没有对缺失的动词信息进行假设,在测试过程中将会产生问题。
扭曲(Distortion)
扭曲是假设的常见来源。
你是否在项目中碰到这样的情况:开发人员根据自己的理解添加新的需求,为系统增加一些功能?这是由于开发人员了解用户的需求。
扭曲是团队内部冲突的来源之一,项目经理可以通过团队成员讨论交流过程中的问题来有效识别失真。
这里写图片描述
虚泛词式
测试人员得不到任何尊重(Testers don’t get any respect.)
虚泛词式指的是将动词转化为名词。
“尊重”是一个过程。我们可以说尊重某人,但这不代表任何意义。我们通过向某人征求关于所做决策的意见来表达尊重。你是通过什么来表现你对某人的尊重呢?
软件研发中充满了虚泛词式,事实上“软件研发”本身就是一个虚泛词,在我们将软件研发的过程作为名词表达式就已经扭曲了其中的活动和涉及的角色。
虚泛词是说话者假设信息接收者与自己对于过程的细节有着同样的认识,也可能是为了掩饰对过程的实现缺乏认知。
虚泛词可以通过将名词转化为动词并提出关于细节的问题来质疑。“你怎么知道某人何时会或不会在参与的事情上尊重你?”
价值判断式
这个系统糟糕透了。
谁说的?根据人是谁?你从哪里听说的?
价值判断式指陈述句中所缺失的主语信息。是谁说了这句话,或者最初这么说的人是谁。
在与人沟通时,我们可能想知道这是他们个人自己的想法还是外界的影响。如果是外在影响,则存在着将作者与陈述者等价的问题;也可能作者的表述并不真实。如果是内部的影响,我们可以追踪其根源并提出另一观点(如果这个结构没有帮助)。
价值判断式会引起猜臆:
1.系统真的必须这么做
2.谁说的?
3.用户说的
4.他们在哪里说的?
5.我就是知道。
猜臆式
开发团队不尊重我们测试人员。——>你怎么知道?
猜臆指的是任何来源不明确的陈述。
在口头交流时,猜臆会导致产生不真实的假设,这种情况与书面交流是不同的。
在写文档,尤其是需求文档时,猜臆会导致对权威(授权?)的假设。软件测试中坚持基于需求文档做交叉引用的原因,就是确认测试中用到的信息是有可信来源的。
未经证实的陈述意味着需求分析只是把单词放在用户口中,我们可能有更深入的功能,需求并没有严格遵守需求,这些都导致开发团队不能优先完成必需的需求。
测试人员应该注意被测系统所做的猜臆:
1.真好,这条记录被保存了,开始下一个测试。
2.你怎么知道记录被保存了?
3.呃,进度条显示它被保存了。
4.你查看数据库了吗?
5.呃,没有……
有时我们知道某事发生了,但我们没有确实的信息确认它确实发生了。我们要验证猜臆,可以通过提问对信息源进行确认。
因果式
因果式是一个陈述链,通过一些证据得出一般性结论。X导致Y的陈述如下:
我保存了一个文件,然后系统崩溃了。
因果式陈述需要通过质疑来获取更多的信息:X怎么导致Y的发生?当我们这么做时会发现一系列表象结构上的删减。
因果式通过行为主义带来思维上的触发和响应【JW66】。
用行为主义的方式思考,我们可以结合触发和响应来对条件进行质疑。
行为主义实验表明,在不同的条件下会触发不同的响应结果。在这种理论下, 我们可以对因果式陈述作如下检查点:
1.会每次都触发Y吗?
1.1.我们会尝试不同的过程去测试,看下是否同一个条件会触发不同的响应方式。
1.2.哪些环境因素会对触发条件或响应方式有影响?
2.有哪些情况是X不能触发Y的?
3.Y响应只能被X所触发吗,是否有其他途径也可以触发Y响应呢?
另外,行为主义也尝试用不同的条件来不断测试,是否有可能持续的用X来触发直到没有响应为止?在计算机系统中,这种结果可能是内存泄漏,或者系统遭受攻击而导致负载过度。
相等式
“开发团队从来都不尊重我们测试人员,他们总是不能及时把确认好的设计文档给我们以便我们能有足够的时间来写测试脚本。”
相等式是一种因果模式,响应就是结果。相等式的陈述,往往没有明确的连词如然后、但是、由于等, 而是由隐含的顺序连词来表述。如“他们不知道自己在做什么,需求从来都没有冻结过。”我们应该质疑说话者在这个等式中的陈述。我们可以通过提问来测试这个等式:“如果需求文档先冻结,他们就知道自己在做什么吗?”
沟通中问题的根源可能就是所陈述的等式并没有根据。
测试人员应该留心缺陷报告中的等式,当其与开发人员描述的不一致时往往会产生冲突。
“每次我打开一个文件时系统就崩溃,文件加载也就中止了。”但事实不一定就是这样,我们能确定的,只是我们试过各种方式打开文件时系统崩溃了。我们应该写出这些方式以便协助开发人员复现并修复问题。
一种完美的产生冲突的方法,就是在缺陷报告中使用开发人员并没有分享过的等式。如果你真的想惹恼他们,试试“每次打开文件时系统就崩溃,文件加载流程也中断了,这是因为你是个差劲的开发。”

项目实践
来个具体需求示例:
这里写图片描述

回顾下NLP元模型的要素:
这里写图片描述
根据NLP给出的要素对需求描述进行扩展,提出问题并逐一与项目团队确认,进一步细化需求
这里写图片描述

关注我们的微信公众号查看完整内容哦~~~~

想知道更多测试相关干货
请关注我们的微信公众号:腾讯移动品质中心TMQ
二维码:
这里写图片描述
版权声明:腾讯TMQ拥有内容的全部版权,任何人或单位对本贴内容进行复制、转载时请申明原创腾讯tmq,否则将追究法律责任。

0 0
原创粉丝点击