性能不彰的软件不仅不能让人们的生活变得轻松,反而会妨碍企业的正常运转,并且让使用它的人心烦。无论实现了多少功能,这样的软件都只能让用户感觉质量很糟糕。

  一旦你的软件给用户留下了糟糕的体验,他们不会等到你的下一次的改进,而会决定掏钱去购买别人的软件。

  假如一个系统又快又可靠,伸缩性又好,而另一个在这几方面表现都不好的话,用户当然会选前者。我们这里据说的“性能测试”不仅针对性能,而且通常还包括对伸缩性和可靠性的测试,因为这些测试往往可以同时、用同一套工具来完成。在这篇文章里,我将会介绍如何确保终产品能够具备这些好的属性-我通过把它们统称为性能。

  什么是性能测试

  大家应该都能同意:良好的性能不只是好东西,更是一个值得为其花钱的东西。现在的问题是:应该在哪里做性能测试?如何让性能测试帮助我们写出性能良好的软件呢?

  性能测试应该囊括确保产品性能符合要求所需的一切行动。这里有四个关键点:需求、产品性能数据、沟通和流程。

  这四点中一旦有所缺失,性能测试的效果会大打折扣。假如仅仅做测试,情况并不会真正有所改观,因为你并不知道系统应该有多快。所以,你需要采集需求。假如测试的结果没有得到有效沟通,那么没人知道问题的存在,也不会采取任何行动来解决问题。即便我们采集到了需求,对产品做了测试,也把结果告知相关人员,工作仍旧没有结束。假如项目计划中没有给“解决性能问题”留出空间,或者没有一套流程根据测试结果计划后续的工作,那么你还是没有办法对终交付的软件产生太多影响?在这种情况下,你耗费大量成本做性能测试,结果只是让你知道产品的性能究竟有多糟糕或多强大,却对这个结果束手无策。

  我们想要的不仅仅是知道结果,更希望所获得的信息能对我们正在开发的软件产生影响,从而保证我们能够满足---或者至少接近?用户对性能的要求。下面我将一一讨论这四个关键点。

  需求采集

  性能需求采集的重要性经常被人们低估。在这一节里,我将尝试阐明几个重要问题, 要度量什么?如何知道我们需要什么?以及如何得到确实有用的数据?

  要度量什么

  重要的性能度量点有两个,大吞吐量以及给定吞吐量下的响应时间。一个好的做法是:分别度量几种不同吞吐量下的响应时间,从中分析负载对响应时间的影响。如果响应的及时性非常重要,那么在确保满足响应时间要求的前提下所能达到的吞吐量可能会明显低于大吞吐量。你需要通过度量找出两项数据:当响应时间恰好可以接受时的吞吐量以及达到预期吞吐量时的响应时间。伸缩性度量的关键则在此于:随着数据规模、用户数量或者运行系统的硬件变化,起初得到的性能度量数据会发生怎样的变化。

  可靠性的关键度量点是:当负载量高得超乎寻常,或者连续运行了很长时间以后,系统是否仍然正常工作。

  如何设定目标

  要想知道系统需要达到怎样的吞吐量,你首先需要知道有多少用户会使用这个系统,以及他们的使用模式。用户会多频繁地使用某个功能?这个功能需要多快完成?

  业务用户会知道这些问题的答案。你应该让他们明白,你会经常需要向他们咨询这方面的事。然后你应该建立一个良好的沟通流程,以确保信息的获取畅通无阻。

  总而言之,你需要有一个可靠的流程与机制来获得所需的信息,及时获知支撑业务需求所需的性能指标。如果不经常去计算这些数据,有可能发现你正在朝着已经过时的目标努力。

  弄清当前需要负载的吞吐量之后,下一个需要考虑的是响应时间。在结合UI考虑这个问题时,人们常会有钻牛角尖的想法。既然用户界面要在几秒种之内响应,那么功能自然必须在更短的时间内完成。但事实并非如此。UI应该立即响应,告知用户:他们的请求已经得到处理,但实际的处理未必马上完成。在整个过程中,系统的其他部分应该照常工作。

  响应时间的目标应该主要针对用户界面,并且数值越低越好。而且,不应该期望所有功能都能在同样的一段时间内完成。

  如果对前面所说的还不明白,下面我将简单介绍一个采集性能需求的流程。

  如何将性能测试融入日常开发流程

  理想情况下,项目组每周应该召开一次会议,确定当前的性能需求。参加这次会议的人应该包括项目经理、关注性能的客户、开发者、以及性能测试人员。如果某些性能需求明显无法达到或者完全不合理,开发者需要在第一时间指出。客户的参与是为了提供业务上的信息与知识,从而帮助判断需求的合理性。项目经理需要知道团队做了哪些决定,并提供一些方向性的指导。至于性能测试人员,他们显然应该在场,这样他们才知道需要测试什么。

  接下来,你需要找到适当的讨论对象。开发团队需要从客户中找到一个联系人,与他一道决定性能需求,这样才能确保客户和开发者都清楚目标所在。不要把性能需求看作神圣不可侵犯之物,和所有需求一样,它们也应该是开发者与客户对话的起点,双方需要共同讨论决定终的目标。

  一旦需求确定下来,能决定当需求得到满足时如何向客户展示,并跟其他的任务一样对编写测试的工作进行评估和计划。

  开发者需要性能测试告诉他们什么

  开发者的需求有很多种,但背后的驱动力总是一致的。如果某段代码需要返工,他们需要更多的信息来了解当时的情况。这些信息可能来自代码检查工具,也可能来自线程转储,甚至于来自日志。他们可能需要知道与应用程序服务器相比数据库的忙碌程度,或是负载达到峰值时网络的忙碌程度。

  预先回答所有这些问题可能并不值得一试,因为这会需要很大工作量。我们能做的是:当问题出现时,弄清哪些信息有助于开发者解决问题,然后把获取这些信息的任务加到你的任务列表上,并告知客户。此时你可以考虑以下问题:从此刻开始为所有测试获取信息是否容易,这是否针对眼下的特定的问题所做的一次性测试。

  如果开发者的需求是以这种方式在会议上提出的,那么,所有人都会知道这些需求的存在。客户可以为这些需求排优先级,可以把它们纳入项目计划。终性能测试将满足各方的需求:它让客户对正在开发的软件保持信心,它也能帮助开发者找到并解决性能问题。

  找不到关注性能的客户怎么办

  如果找不到一个关注性能需求的客户,会有以下风险。首先,正在开发的软件可能不符合业务要求,项目可能彻底失败。其次,不管终的产品如何,客户都可能说它不符合要求,因为他们感觉开发团队没有征求他们的意见。后,这可能在团队内部造成紧张气氛。开发团队会觉得自己在被迫做不必要的工作,因为需求不是来自客户-不管项目经理的担心是否正确,这种想法都有可能出现,并导致必要的工作没有被完成。亦或相反,开发者们浪费时间去做不必要的工作。

  如果客户不懂技术又非要坚持不可能的需求该怎么办

  这种可能性问题存在:客户希望产品的性能达到某个水平,而达到这个水平是不可能或者不经济的。这时你需要提出一些中肯的问题,把对话引导到真实的业务需求上来,从而打消客户不切实际的要求。

  如果客户的要求是关于吞吐量的,可以考虑的问题有:每个工作日处理多少事务?这些事务的时间分布如何?是平均分布还是有明显的峰谷之分?每个周五下午有集中访问,还是说峰值的出现没有特别的模式可循?

  关于响应时间表,可以考虑的问题有:用户界面的响应时间会对系统的处理能力造成什么影响?能不能把界面与实际的计算操作分离?比如说,可能有这样一种场景,用户输入一些数据,然后进行较长时间的数据处理。此时用户不希望一直等到处理完成,而是希望立即输入下一段数据。所以这时合理的期望不是在一秒钟内完成数据处理,而是将用户界面与数据处理分离,让系统在后台处理一段数据,同时让用户在界面上输入更多的数据。

  通过上述方式,我们能让开发者与客户共同寻找一个对业务价值有意义的性能水平,并且分清什么是当务之急以及什么是锦上添花。我们都曾遇到下面这种情况:在项目的现有条件下,客户急切希望的某个性能目标不可能达到或是需要付出高昂的代价。如果相关的分析能尽早开展,客户有可能在更早的时候做出决定,从而使这些目标成为可能。

  如果客户期望的目标不能达成,他们会对终交付的系统感到失望,哪怕系统其实足以满足业务需求。上述这些讨论有两方面的作用,不仅让开发团队了解客户的真实需求,而且让客户自己也有一个清晰的目标。这样一来,只要系统达到了双方认可的目标,客户会感到满意。有这些讨论作为基础,客户不太会坚持不切实际的期望;如果他们仍然感到失望,至少那也是出于合理的原因。

  何不让业务分析师一并采集这些需求

  采集性能需求时不一定需要业务分析师在场,原因有几点。首先,此时功能需求的采集应该已经完成了;其次,即使业务分析师在场,开发者还是不能缺席,因为只有开发者才清楚分析性能问题需要获得哪些信息,也只有他们才能判断获得这些信息的途径和难度。性能测试人员应该提出前面介绍的这些问题,以此推动讨论进行,他们也能够判断每个需求是否容易测试。所以,当这些人坐在一起讨论时,业务分析师可以把时间花在其他更有价值的地方。

  小结

  需求采集是为了让所有人都清楚终交付的产品需要有怎样的性能才能支撑业务目标。之所以要让客户参与,是因为他们了解自己的业务,这样才能确保采集到的需求足够准确。而且通过讨论也能帮助客户清晰自己对性能的需求,从而有效管理他们对系统的期望。