批判性思维是指一种合理的反思性(反省的)思维,是一种训练有素的思维方式的体现。它借助观察、经验、反思、推理或沟通等收集信息,并对这些信息进行抽象、应用、分析、综合或评估,以此决定相信什么或做什么。 从批判性思维看,软件测试就是借助观察、经验、反思、推理或沟通等收集信息,并对软件产品相关的质量信息进行分析,以此评估软件质量,并做出结论。
但是在下结论之前,或多或少包含了假定和推理,而作为批判性思维的践行者就可以质疑其假定、推理和结论,这样可以消除认知中的误区,突破知识构建时的边界,重新认识某个主体(如软件产品/系统)。如“人们彼此之间也有欺骗”分为恶意欺骗和善意欺骗,但如果不仔细想,就会局限于恶意欺骗。人类的认知是有限的,人们在常识(普遍接触的条件,这也是有边界的)下得出的理论,当达到或超出边界时,认知就会发生谬误。而且,需求文档也包含着一定的模糊性、不确定性和局限性,只有消除其中的模糊性、不确定性和局限性,对软件产品或系统的认知才会前进一大步,测试才会深入下去。
没有审视和分析就不能做出正确的判断。 批判性思维促进我们重新审视问题或主题、意图和陈述之间实际的推论关系,勇于质疑证据,去分析和评估陈述、论证的过程 。清楚对方是表达一种信念、判断还是一种经验?其理由正当、充分吗?仅仅是个人的感觉?相关的因素都考虑了?有依据支撑吗?依据来源哪里?可靠吗?也就是要评估陈述的可信性,分析其推理的合理性、前后逻辑关系的严谨性等。这些恰恰是 软件测试所需要的。
基于批判性思维,我们需要重新定义“软件测试”: 软件测试就是测试人员不断质疑被测系统的过程 ,如图1-8所示。
图1-8 “基于批判性思维的软件测试”示意图
需求定义、系统设计中存在研发人员太多的猜测、不真实的假定、片面的理解、不合理的推理等,软件测试在需求评审、设计评审、代码评审和系统测试中就是要重新审视被测对象,质疑那些不合理、不真实的内容,发现软件中的错误、漏洞。
这种软件测试定义,特别适合探索式测试方式。探索式测试聚焦被测系统,侧重发现缺陷,强调在一个相对封闭时间(90min左右的session)内以“ 设计、执行、分析、学习 ” 的过程不断循环、不断优化测试过程 。这里的session 不宜翻译为“测程”,而是 会话 —— 测试人员和SUT一次真正的对话 ,不断地向系统提出问题( 质疑系统 ),再审视SUT所做出的回答(系统的响应),从而根据Test Oracle判断SUT的响应是否符合我们的期望。从隐喻看,可以把“测试人员”看成客户端(浏览器),把SUT看成服务器,测试过程就是测试人员和SUT建立会话的过程,客户端不断发出请求,并检验系统发回来的响应结果。
再举一个例子,帮助大家理解这样一个过程。我们招聘一个新人,会给出职位描述(JD)——详细描述工作岗位要求和责任,应聘者会根据JD提交详细的简历。本来我们就可以根据应聘者的简历来决定是否录用他/她了,为什么不能?还需要安排面试呢?原因如下。
·质疑简历不真实(这种情况虽然很少)。
·简历中某些描述,大家的理解可能不一致,例如“精通Java”“沟通能力”“情商”没有明确的标准,应聘者和企业对此认识可能差别很大,需要收集更多信息和数据,进行比较分析,才能更加具体客观。
·有些内容缺失或不宜在简历中描述,个人气质、性格、情绪控制能力等需要在面试中获得相关信息,做出判断。
·简历中某些描述可能比较粗,不够具体,不知是否和企业需求匹配如何,需要从多个应聘者中择优录用。
从批判性思维角度来理解软件测试,就是测试人员“面试”SUT的一次会话过程。虽然有需求文档和设计文档,但是不够。今天敏捷开发模式下就更不充分,需要测试人员去面试系统。探索式测试的核心(出发点)就是质疑系统,不断深入下去质疑系统的每一个业务入口、应用场景、业务操作和数据输出等,怀疑某个地方存在某类缺陷。
·开发人员对用户真实的需求的错误理解。
·漏掉某些需求。
·错误地实现了需求或设计。
·没有完整实现需求或设计。
·算法不够优化,存在性能问题。
·数据输入缺乏保护。
……
这就要求测试人员善于质疑、善于向系统提问,可以参考M.N.Browne的《Asking the Right Questions: A Guide to Ctitical Thinking(10th edition)》(中文版书名《学会提问》)。