你有没有想过为何有时修复错误彷佛比它应该花费更长的时间?当你终于找到问题时,事实证实你所须要的只是一个小小的改变。然而,花了不少时间才能找到正在发生的事情。这种状况比我想象的更频繁。面试
另外一方面,当您编写代码并进行测试而且没法正常工做时,修复错误很是快。你跳回编辑器,掀起一行代码,问题就解决了。数据库
为何即便问题很简单,有时修复错误也须要不少工做,有时候,修复问题的速度很快 - 甚至可能很难解决问题?咱们能够从易于修复的错误中学到一些东西,这样咱们能够花更少的时间来修复bug吗?浏览器
让咱们来谈谈这个问题,看看咱们能够用什么方法来解决这个问题,而且由于很难找到错误而中止拔头发。服务器
为了肯定在修复错误时花了这么长时间,咱们先来看看修复错误所涉及的步骤。编辑器
嗯,我想咱们已经开始在这里看到一个问题了。修复bug自己只有六分之一!函数
但在咱们得出结论以前,让咱们更详细地看一下这些步骤。而后,咱们能够看到每一个步骤中的内容须要花费时间,并找到使它们更快的方法。 工具
错误修复过程的第一步是理解问题。咱们须要收集足够的信息,以便咱们知道发生了什么,以及应该发生什么。性能
这个步骤花费很长时间的最大贡献者是可怕的,糟糕的错误报告。单元测试
用户从不提供好的错误报告。这是生活中无能否认的事实。学习
我可能会夸大一点,但我确信你已经比你想要的更频繁地听到“它不起做用”的字样。
“X不起做用,它须要在昨天修复!”
而后你继续问一些问题,但愿你能从记者那里收集一些比“它不起做用”更有用的信息。
固然,有时当行星和恒星正确对齐时,你会获得一个好的错误报告。您能够清楚地了解出现了什么问题,重现它的精确步骤,甚至能够得到有关用户使用的浏览器和操做系统的信息!那时候你能够直接进入第2步并开始修复bug。
但在最糟糕的状况下,你只会对发生的事情有一个模糊的概念,这意味着在第2步中须要付出更多的努力。
若是您在步骤1中得到了良好的错误报告,则此部分能够很容易。您能够按照错误报告中的步骤操做,而后当即重现错误。太棒了!如今,您能够继续查找损坏的代码。
可悲的是,这一步每每不是那么顺利。
因为模糊的错误报告,这一步每每涉及不少猜想。
也许用户使用的是Firefox,或者他们使用的是Chrome。在点击此按钮以前,他们不肯定他们作了什么。我想知道我是否应该随意按下按钮并但愿最好?
有时,在尝试重现问题后,您必须反复执行步骤1和步骤2,而不会产生任何结果。但愿您能够从用户那里得到更多信息,而后再试一次。
在这一点上很清楚,为了加快步骤1和2,咱们须要收集尽量多的信息。咱们掌握的信息越多,理解和重现问题就越容易。
一旦咱们再现了这个bug,咱们就须要找到致使问题的代码的特定部分。
此步骤的难度各不相同,主要取决于两个因素:
代码量会影响这一点,由于每行代码都会增长可能的错误数量。值得庆幸的是,熟悉代码库能够显着缩小范围。
找到问题一般从采起有根据的猜想开始。
“好吧,这就是问题,这就是我能够重现它的方式,因此我认为问题出如今代码的Y部分”
您对代码库的熟悉程度越高,您的猜想就越好。这使您能够缩小须要查看的代码量,可能须要大量调整。
“好吧,我最近在处理函数Z,它有与此相关的代码。我最好先检查一下。“
根据问题的类型,您还可使用调试工具来帮助您更轻松地找到有问题的代码。
“是的,当我点击它时会出现错误。我将在事件处理程序中设置一个断点并从那里开始。“
**在此过程的这一步,最大的时间汇是找到问题发生的确切位置。**它多是行为不当的功能,用户的不良价值或任何数量的东西,您须要在继续以前找到问题的根源。
这多是这个过程当中最重要的一步,但它常常被彻底跳过!
因为感知时间限制,或者仅仅由于经验不足的开发人员可能不知道他们应该这样作,它可能会被跳过。不管哪一种方式,跳过此步骤一般意味着您的代码慢慢开始填充hacks和kludges。
注意,我说感受时间限制。一般你可能会感到有压力要快速修复。
“只需快速修复,客户就在等待。你之后能够作好工做。“
所以,您可使用一些代码来修复损坏的代码并跳过根本缘由。固然,你极可能永远没法妥善修复它,由于总有一些东西须要完成。
但快速修复快速修复的结果与使用胶带修复漏水管道相同。即便在芬兰,咱们称胶带为“耶稣胶带”,由于它具备修复任何东西的神奇能力,在某些时候胶带修复开始泄漏,你须要再使用一些胶带。不久以后,你手上就会有一个巨大的混乱,你必须把它所有撕下来。
最后,您须要花费更多时间来修复快速修复,而不是花费更多时间来完成正确的工做。
但我离题了。
肯定根本缘由意味着您须要找到错误的真正来源。让我给你举个例子。
假设您网站上的某些价值显示不正确。您能够经过更改显示代码来解决此问题,但更多时候,显示症状的代码不是根本缘由。
若是您更深刻地研究问题,您可能会发现数据库中的数据也是错误的。进一步深刻研究,您会发现保存该值的代码已被破坏。这是问题的根本缘由。您找到的原始代码只是在其余地方显示问题的症状。
若是您只是修复了症状,那么真正的问题就会存在。它将继续在未来引发问题,同时你不断修复更多的症状。
与查找症状不一样,此步骤不须要太多猜想。你有一个起点,从那里你能够追溯到根本缘由,因此你不须要猜想。
尽管如此,这一步可能很是耗时,由于您常常须要在几个级别上深刻研究代码。多长时间在很大程度上取决于根本缘由与症状相比的位置 - 有时它们甚至多是相同的,但如示例所示,它可能会下降几个等级。
最后咱们能够解决这个问题。咱们已经复制了这个错误,找到了症状发生的地方并找到了根本缘由。
在完成全部工做以后,这一步一般是至关微不足道的。咱们有关于出了什么问题,应该发生什么以及出现什么症状的信息。错误一般不须要大的修改来修复,所以实现部分每每很快。
做为这个过程的最后一步,咱们须要确保错误被完全掩盖。
这能够经过重复您以前重现问题的步骤来完成。
偶尔这个bug仍然会重现。在这种状况下,您一般须要返回步骤4或5并从那里继续。
若是对软件测试、接口测试、自动化测试、性能测试、LR脚本开发、面试经验交流。感兴趣能够175317069,群内会有不按期的发放免费的资料连接,这些资料都是从各个技术网站搜集、整理出来的,若是你有好的学习资料能够私聊发我,我会注明出处以后分享给你们。
如今咱们已经查看了错误修复过程当中的每一个步骤,咱们能够肯定这些关键难点:
全部这些都有助于减缓错误修复并使其成为一个繁琐的过程。咱们编写代码来修复bug的部分不多是最大的时间下沉!
可是,尽管如此,有时咱们能够很是快速地修复错误。这一般发生在咱们添加新功能和处理全新代码时。
为何是这样?
若是咱们在考虑使用全新代码时的典型状况,咱们一般会很是熟悉咱们刚才写的内容。在这种状况下发现错误的人一般与编写代码的人相同。
这几乎彻底消除了猜想!
所以,修复错误是一件垂手可得的事。一般状况下,您只需将alt-tab返回到编辑器,当即发现问题并进行更快的修复,而不是说“它不起做用”。
咱们能够有把握地说,缺少信息和由此产生的猜想是致使修复bug变慢的最大因素。
咱们能够作些什么来改善这种状况?
让咱们首先看一下咱们能够作些什么来从用户那里获取更多信息并进入错误报告。迈出这一步的第一步是向用户询问一些具体问题。这有助于指导用户为咱们提供更有效地解决问题所需的信息。
如下是您可使用的一些问题。我不记得我第一次看到这些,但我倾向于本身使用这种格式而且效果很好。
第一个并非绝对必要的,可是若是您使用像JIRA这样的工具,由于您须要该问题的名称,这将很是有用。第二个是至关明显的,第三个对于理解用户指望发生的事情很是有用。虽然你能够本身解决这个问题,但最好事先了解一下 - 特别是有时它可能不是技术问题,而只是混乱的结果。
第四点多是最重要的,但用户并不老是知道如何填补这一点。若是可能的话,最好给他们一个小样本,如你想要它填充,如“1。我在第X页2.我点击按钮Y 3.我输入值Z“。
特别是对于Web应用程序有用的其余信息是用户的浏览器和操做系统。根据用户的不一样,他们可能并不老是知道这一点,所以可以自动收集这些信息可能颇有价值。为此,您能够考虑集成Usersnap等服务,这有助于将更多数据收集到错误报告中。
在脚本错误的状况下,具备堆栈跟踪一般也是有用的,尽管具备良好的再现步骤,您也应该可以本身得到它。像Loggly这样的工具可用于自动收集有关错误的信息(即便在客户端JavaScript代码中),这样您就能够更好地了解发生的状况。
这些步骤是改进流程的良好起点。可是他们并无真正解决全部问题。例如,不管您尝试多少,用户均可以而且将继续发送使人困惑的错误报告。
我知道。我反复告诉用户他们须要包含重现问题的步骤,或者咱们不能作任何事情,并且我仍然不断获得可怕的“它不起做用”的错误报告。
“Jani,X破了修复它”
啊。
那么还有什么咱们能够作到这一点并不依赖于那些挑剔的用户呢?
记录常常被忽视做为一种工具。也许这样作缺少好的库,或缺少使用日志输出的好工具 - 由于让咱们面对它,谁想经过手工查找特定事件来浏览一个巨大的日志文件?可是正确完成并使用好的工具,日志能够提供有价值的信息。
大多数开发人员仅将日志记录用做临时措施。很容易将一堆`console.log'打入咱们的代码只是为了看看发生了什么 - 我作了不少。
可是当我说伐木时,我不仅是谈论调试日志或错误日志。我正在谈论通常的登陆 - 关于代码中发生了什么,正在发送什么输入等的信息。
以更系统的方式登陆须要一些工做。咱们须要注意包括登陆咱们的代码,咱们须要确保记录可能有用的信息。那么这有助于加快bug的修复速度呢?
特别是在自动化流程的状况下,日志记录很重要。除非您有日志,不然一般没法跟踪此类进程中发生的状况。日志应该足够详细,以便让咱们对发生的事情有一个合理的了解。
使用这样的日志有助于经过向咱们提供更多有用信息来减小猜想工做量。
尽管我喜欢将Java变得糟糕,但日志记录是他们作得很好的一件事。它有许多库和已创建的日志实践。若是您遇到过Java应用程序的问题,您可能会查看日志甚至增长日志详细程度。他们中的许多人输出了大量的日志。
记录有用的是什么?对于每一个应用程序来讲,拥有日志或记录全部内容并非绝对必要的,但这里有一些例子:
根据您查找日志的有用程度,实现启用/禁用某些类型的日志或基于每一个用户启用/禁用日志的方法也是一个好主意。
到目前为止咱们所看到的全部这些措施都没有解决咱们的关键问题。错误报告和日志虽然有用,但只会在过后提供更多信息。
还记得咱们如何找到快速修复的错误之间的重要区别,以及须要很长时间才能修复的错误是咱们检测问题的时间。
每当咱们积极处理一段代码并在开发过程当中发现错误时,它们的修复速度要快得多。咱们对代码有了全新的记忆,咱们已经掌握了全部信息,所以咱们不须要进行其余必要的考古。
到目前为止,这些都没有任何帮助,即便这是花费多少时间的最大贡献者之一。
咱们怎样才能更快地发现更多的错误,甚至在咱们的开发过程当中?
显然,咱们能够聘请二十多位QA专家来用显微镜进行更改。然而,对于大多数团队而言,这并非很实用,即便使用质量保证流程,也可能须要一些时间来发现问题,此时咱们已经转向了其余方面,因此它无济于事。
在开发过程当中能够帮助咱们发现错误的是测试自动化。
测试自动化是一个更加现实的目标。它不须要大量的前期投资:您能够逐步开始使用它,而且每一步均可以得到愈来愈多的好处。
每当咱们更改代码时,咱们都会冒险引入错误。可是,若是咱们新添加的代码存在错误,咱们一般会轻松地发现并修复它们。
新添加或更改的代码很容易修复,由于咱们已经掌握了它 - 咱们只是花时间研究它!这意味着能够轻松找到并修复其中的任何问题,由于咱们不须要开始挖掘代码来找到它。咱们仍然能够记住事情的发展方向。
所以,咱们能够赞成,咱们越早发现错误,就越容易修复。
但单元测试如何帮助咱们作到这一点?
首先,单元测试一般包含如下部分:
而后,若是这样的测试失败,咱们会获得如下信息:
让咱们将这些与咱们想要的错误报告进行比较:
你能看到咱们从测试中获得的结果吗?咱们从一个好的错误报告中得到了咱们想要的信息!不只如此,测试在开发过程当中为咱们提供了这些信息*!*
当您仍在处理代码时,单元测试能够为您提供所需信息的即时反馈,所以您的想法一切都很新鲜。
全部这些都有助于确保咱们有足够的信息来快速修复错误。咱们知道发生了什么,应该发生什么,咱们能够经过再次运行测试来重现错误...咱们甚至能够经过再次运行测试来验证咱们的错误修复代码是否正常工做。
做为额外的好处,测试也会捕获代码中其余地方的更多错误。一般因为咱们的更改,咱们会在其余地方意外地致使错误。这些很容易被忽视,最终难以修复,但若是你有单元测试,没问题 - 一旦你编写测试,你能够保持它,它不断捕捉错误和有用。
经过修复错误,最大的时间接收器不是编写修复程序。在咱们开始编写任何代码来修复bug以前,咱们须要作的全部工做。其中大部分是因为缺少信息 - 错误的错误报告,大量的代码,甚至糟糕的代码均可能致使错误。
咱们能够经过尝试在错误报告中获取更多信息来改善这种状况,但更快地修复错误的最佳方法是更早地发现错误。
在开发过程中遇到的错误是最快修复的,由于咱们正在积极处理有问题的代码,而且咱们在头脑中拥有所需的信息。这意味着咱们不须要开始挖掘错误报告或代码来弄清楚发生了什么。
在测试期间捕获更多问题的最佳方法是单元测试。他们解决了全部三个问题:
您也不须要花费大量精力进行测试。您能够逐个开始添加测试,例如修复错误时。随着您添加的每项测试,您将得到愈来愈多的好处。
测试的主要问题是它可能很难入门。然而,一旦你学会了这些概念,它们就不会过期了 - 不像当下流行的图书馆,测试已经存在了很长时间,不管你使用什么库或语言,均可以使用彻底相同的原理。
单元测试还有更多的好处,而不只仅是更快地修复bug。