调试九法-制造失败

当你发现一个故障时改怎么办?试着让它在此发生。这样做有3个原因。

  • 可以观察它。要观察错误,就必须使它发生。我们必须尽可能有规律地制造失败。

  • 可以专心查找原因。准确地知道问题在什么条件下会发生。有助于集中精力查找原因。

  • 可以判断是否已修复问题。当你认为已经修复了问题时,如果才能确信它确实已被修复呢?那就是明确知道问题是如何发生的。当问题没有修复时,如果你执行X操作,失败率为100%;在修复问题后,在执行X操作,如果失败率为0,那么你知道bug确实已被修复。

制造失败

但如何才能让它失败呢?一种简单的方法是进行一次内部预演,还有一种同样有效的方法是演示给未来的投资者。如果碰巧没有客户或投资者在现场,那么你就必须正常使用,并观察它是如何出错的。当然,测试本来就应该是这样的,但这里的重要之处是在错误第一次出现之后,能够使它再现。通常,认真记录测试过程可以作为补充,但你必须认识到仅有一次错误是不够的。

仔细观察你做了什么。然后再做一次,并且记下你做的每个步骤。然后,按照你自己所写的步骤去做,确定这样做确实导致了错误(实际上,在有些情况下,令设备发生错误具有一定的破坏性,或者代价很大,这时每次都使设备发生同样的错误就不是一种好办法。为了控制损失,必须改变一些地方,但我们尽量少改动原来的系统和顺序)。

从头开始

通常,所需的步骤很短,也很少。

引发失败

在调试故障的时候,如果需要手工执行很多步骤,那么使整个过程自动化会很有帮助。在很多情况下,只有在重复很多次后,错误才会出现,因为我们希望在夜间运行自动测试工具。

不要模拟失败

引发失败(正确)和模拟失败(错误)这二者之间存在着非常大的差别。

在类似的系统上再现bug是一种较为有用的方法,但有一些限制条件。如果一个bug可以在多个系统上再现,那么我们就可以认为它是设计bug,因为它并不是在一种系统上以某种特定的方式出现。如果在某些配置下能够再现它,而在另一些配置下无法再现,那么这就帮助我们缩小了查找范围。但是,如果无法快速地再现它,那么不要为了使它出现而改变你的模拟环境。这样会产生新的配置,而不是原来发生错误的那个配置了。无论一个系统在哪种常规配置下发生故障,都要在该系统上使用该配置来查找问题。

如何处理间歇性bug

当故障只是偶尔发生时,用"制造失败"这种方法来调试就困难得多。很多棘手的问题都是间歇性的,这就是不能总是应用这条规则的原因——它很难应用。

关键问题在于你并没有完全弄清楚失败时如何发生的。你知道你做了什么,但并不知道完整的、准确的条件。还有其他你没注意或无法控制的因素。如果你能够控制所有这些条件,那么就可以一直使错误发生。

那么,如何控制这些条件呢?首先,查明它们。

一旦想到了有哪些条件可能影响你的系统,必须大量尝试与这些条件相符的各种形式。初始化这些条件,并按照一种已知模式把这些条件作为你的问题软件的输入。

有时,你会发现当你控制某个条件的时候,问题消失了。这时你就发现了是什么条件导致了失败。当然,如果发生这种情况,你需要尝试该条件下的每个可能的值,直到找到导致系统失败的那个值。

有时,你会发现有些条件是无法控制的,但是可以增加它的随机性。

如果做了所有尝试之后问题仍然间歇性发生

记住,我们之所以制造失败,是处于3个目的:一是观察错误,二是查找线索,三是确认是否已修复。

仔细观察失败

你必须能够看到失败。如果它不是每次都发生,那么就必须忽略掉不发生的时候,而在它每次发生时观察它。关键是在每次运行的时候捕捉相关信息,以便在发生失败之后查看数据。方法就是让系统在运行的时候尽可能多低输出信息,并把它们记录到"调试日志"文件中。

通过查看捕获到的信息,很容易把正常运行和错误运行放在一起进行比较。如果你捕获到了正确的信息,就能够看到正常运行与错误运行之间的区别。仔细观察只在错误运行中才发生的那些事情。这是实际开始调试时需要注意的地方。

尽管失败时间歇性的,但这样就能识别并捕获发生错误的条件,然后对其进行分析,就像它们每次都发生一样。

不要盲目相信统计数据

制造失败的第二个目的是获得问题发生的线索。当发生一个间歇性的问题时,你可以注意那些看起来与问题有关的操作模式。这种思路是没有问题的,但不要被表面现象所误导。

如果失败是随机发送的,你可能无法收集到足够多的统计样本来作出判断。很多时候,巧合会使你误认为某种条件比其他条件更可能引发问题。然后你就会开始自习研究"这两种条件之间有什么区别",由于你找错了对象,这将会浪费大量时间。

这并不意味着你所看到的这些巧合的区别与问题不存在任何联系。但是,如果它们没有直接的影响,那么它们与问题的联系将会隐藏在其他随机因素背后,这时通过查看这些区别来找到原因的机会时非常渺茫的。

当你捕获到足够多的信息时,就可以确定哪些因素总是与bug有关,或者哪些因素从来都与bug无关。在查找问题根源的时候,这些因素时需要重点关注的

是已修复bug,还是仅仅由于运气好,它不再发生了

如果失败是随机发生的,那么要想证明bug是否已被修复就会困难得多。

如果采用统计测试方法,那么运行的样本越多,结果就越准确。但是,更好的方法是找到一个总是与失败有关的时间序列。即时这个序列本身就是间歇性的,但当它发生时,100%会发生失败。然后,当你认为已修复bug时,就可以运行测试,直到这个序列出现,如果没有发生失败,那么你确实已修复了bug。

"那不可能发生"

这里的关键是"那"这个词。"那"是指什么?它是测试人员或工程师所认为的问题背后的失败机理。或者说"那"是指一个事情序列,这个序列看起来是再现问题的关键。

永远不要丢掉调试gongju

有时,一种测试工具可以在其他的调试场合重复使用。当你设计它的时候,应该考虑到这一点,并且使它易于维护和升级。这意味着要采用好的工程技术,并实现文档化,等等。把它加入到源代码控制系统中,并构建到你的系统中,以便随时可以使用。不要只把它当做一次性的工具来编码,扔掉它可能是错误的。

小结

虽然看起来很简单,但如果不制造失败的话,调试就会变得很困难。

  • 制造失败。目的是为了观察它,找到原因,并检查是否已修复。
  • 从头开始。
  • 引发失败。
  • 但不要模拟失败
  • 查找不受你控制的条件(正是它导致了间歇性失败)
  • 记录每件事情,并找到间歇性bug的特征。
  • 不要过于相信统计数据。
  • 要认识到"那"是可能发生的。
  • 永远不要丢掉一个调试工具
原文地址:https://www.cnblogs.com/uetucci/p/7988756.html