精华内容
下载资源
问答
  • Bug

    2006-12-29 11:58:00
    Bug的生命流程从新增的opened状态开始,到closed状态结束,主要流程包括bug新增、bug解决、bug验证和bug关闭。 一、 Bug跟踪流程Bug的生命流程从新增的opened状态开始,到closed状态结束,简单而言,Bug核心跟踪...

    Bug的生命流程从新增的opened状态开始,到closed状态结束,主要流程包括bug新增、bug解决、bug验证和bug关闭。

     

    一、             Bug跟踪流程
    Bug的生命流程从新增的opened状态开始,到closed状态结束,简单而言,Bug核心跟踪管理流程应该包括:

    1、  新增:测试人员发现Bug之后新增一个Bug,并将Bug指定给对应的开发负责人,Bug状态为DEV处理。Bug新增成功后,只有开发负责人才有权限回复这个Bug,其它人只能查看或追加回复。Bug

    2、  审核:测试人员提交bug之后,应该由测试经理和项目经理对bug进行审核,审核Bug的优先度、哪些Bug可以等到下个里程碑或版本中解决、对问题有何修改建议。这一步非常重要,避免由于测试人员的素质参差不齐而导致的软件质量问题。Bug

    3、  回复:开发人员修改问题之后,将Bug回复给对应的测试负责人,Bug回复后,只有测试负责人才有权限跟踪回复或关闭这个Bug,Bug状态为QA确认。开发人员回复Bug之后,测试人员会进行验证,如果问题还没解决,则将这个Bug重新回复给开发人员,并且在回复中进行详细的问题描述。测试人员回复此bug给开发人员之后,Bug状态又转为DEV处理Bug

    4、  回复审核:开发人员修改问题之后,应该由测试经理对bug进行审核,检查bug的修改处理方法是否正确。Bug

    5、  追加回复:一个Bug的记录不能删除或修改,只能够新增,如果测试人员或其它开发人员或项目经理想对Bug增加说明,可以通过追加回复进行。

    6、  关闭:开发回复Bug之后,测试负责人验证该Bug,如果问题得到解决则关闭(否则回复给开发负责人,让其继续追踪),Bug状态为问题解决Bug

    7、  查询:输入查询条件,查询对应的Bug。Bug

    8、  删除:删除Bug,但这个记录不会被删除,也就是说只是做一个特殊的标志,没有真正删除。Bug

    9、  :在后续测试中又出现了相同或类似的问题,重新打开此Bug。Bug reopen

    10、              统计:输入统计条件,统计对应的Bug。Bug

        
    二、             Bug跟踪管理系统
    Bug跟踪管理系统用于帮助公司和团队跟踪工作中的问题,管理和记录这些问题的处理过程,并为用户提供事务分配和自动通知的平台。Bug跟踪管理系统对于一个团队的Bug管理非常有效,可以确保每个出现的问题都可以得到记录和跟踪,为团队提供有效的交互平台,提高团队效率和增强团队工作氛围。同时,作为问题记录的数据库,可以积累处理问题的经验,也可以轻松吸取他人经验,对以后维护也很有帮助。
    对于比较大型的公司或开发团队,比较倾向于自己开发符合自己需求的Bug跟踪管理系统,除了缺陷跟踪外,还可以对工程需求、分析设计、任务管理、工程故障等进行管理;而对于一个小型团队,可以使用现成的Bug跟踪管理工具,有些工具也是开源的,可以自己很方便的修改,对于小团队来说它所提供的功能也已经够用了。常见的缺陷跟踪工具有Rational ClearQuest、Bugzilla、Testtrack pro、source forge、teamshare、PVCS Tracker、TestDirector、Track+和Wicresoft BMS。我个人偏向使用Testtrack pro,比较友善简单。不管是自己开发的管理跟踪系统还是bug管理工具,都只是工具而已,真正要做的是流程上的管理。

     

     
    展开全文
  • 这种新手都不会范的错,居然被一个工作好几年的小伙子写出来,差点被当场开除了。

    你知道的越多,你不知道的越多

    点赞再看,养成习惯

    本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。

    正文

    我先描述一下bug的现象哈:

    这两个输入框的值都是我从KV(Redis之类的存储中间件)里面获取到的,也是可以实时修改的,我自作聪明,想着KV里面如果没值,就默认取一个静态变量,这样有个兜底,在类加载的时候加载静态变量,我取的时候也效率高了。

    这就也为我后面的Bug埋下了伏笔,问题是这个Bug烦就烦在他在预发环境是好的,线上却是坏的。

    先看看代码怎么写的:

    可以看到代码里面,我是在静态代码块去KV取值,如果有值就用KV的做初始值,没取到我也有默认值,我当时还在想自己的构思真巧妙,用KV比DB效率高,用常量去做兜底,不至于没配置的情况没有值,报空指针啥的。

    当时一个劲给自己加油打气,一个劲的妙啊,不知道自己写了多蠢的代码。

    这样写看似没什么问题,但是我这个值是可以修改的这就有问题了,而且我有几个地方还是取的变量,不是一直取的KV。

    而且常量被我当变量用,也都违背了这玩意的初衷了。

    我上线后,三歪就说:敖丙出大问题了,为啥我刷新一下值就不对了,再刷新值就回来了。

    我惊恐万分,深知我写了BUG,我不着痕迹的擦去我鬓角的汗水,深呼吸了一下。

    回答道:我代码还没写好呢,你怎么乱点,我告诉过你不要乱点的,现在你点坏了吧。

    三歪好像真的以为他错了,委屈巴巴的啥也没说就默默离开了。

    这个时候我马上打开电脑,也顾不上歪歪的感受了,思绪转的飞快,开始在闹海中构建整个值传递的链路。

    我改了页面的值,之后我也改了这个静态变量和KV的值,但是我在线上发现我刷新页面一会是修改之后的,一会是修改之前的值.

    这就奇怪了呀,主要是在预发还不能复现,这就很坑爹了,难受呀歪歪。

    Tip:预发指的是,代码跟线上一样,数据库一样,环境配置不一样。

    我把代码看了一遍又一遍,还是没发现问题。

    在当天那个饱暖思淫欲的下午饭之后我,突然灵光一闪发现了问题的核心,预发是好的因为他是一台机器。

    而我们线上的机器是负载均衡的,有两台机器,我修改一次只改了一台机器的值,另外一台没修改到。

    那么问题就简单了,我们看下图:

    预发情况,是单机,不管我怎么读怎么修改,每次数据都是准确的(这里我还没意识到其实每次去取变量是不对的)。

    但是线上不一样,服务器启动的时候给每台机器赋值了,这样的情况如果只是读是没问题的(怪不得静态常量都是private的,能修改的话基本上都有这个问题)。

    但是如果修改,你修改的请求只是打到了一台机器上,如果下次负载均衡请求到了这个机器,那么你很幸运,结果是对的,但是往往负载均衡算法就是那么公平,雨露均沾这样的情况 1/2的请求,都会拿到错误的结果。

    而且这个地方的问题还有一个就是,应该是修改KV之后,修改变量,我有的地方取的是变量,因为我想每次反正都改了,取也没事。

    其实正确的做法是我每次去都读KV就好了,只有KV为空的时候才去读静态变量,作为一种兜底方案,不应该去改变常量的值。

    而且大家要知道,我修改KV成功万一修改常量的时候出错了呢?你取常量的值就不对了。

    所以查询,修改应该这样做:

    主要是想提醒大家,谨慎操作静态常量,能不变就不变,不要写这么骚的操作了,我这算少的很多 40、50台线上机器的服务,这种问题是真的难发现。

    我是万万没想到,我居然写出这种代码,下次再写出来,只能让歪歪不要乱点了,免得又点坏了哈哈。

    絮叨

    另外,敖丙把自己的面试文章整理成了一本电子书,共 1630页!目录如下

    现在免费送给大家,在我的公众号三太子敖丙回复 【888】 即可获取。

    我是敖丙,一个在互联网苟且偷生的程序员。

    你知道的越多,你不知道的越多人才们的 【三连】 就是丙丙创作的最大动力,我们下期见!

    注:如果本篇博客有任何错误和建议,欢迎人才们留言!


    文章持续更新,可以微信搜索「 三太子敖丙 」第一时间阅读,回复【资料】有我准备的一线大厂面试资料和简历模板,本文 GitHub https://github.com/JavaFamily 已经收录,有大厂面试完整考点,欢迎Star。

    展开全文
  • SonarQube检测出的bug、漏洞以及异味的修复整理

    万次阅读 多人点赞 2019-04-15 12:35:17
    BUG 1.Not enough arguments. 上面的这种bug在项目中很常见,参数都用new Object[]{}封装起来。特别是从class文件反编译回来成的java文件格式也是这样的。但是如果要消除bug的话直接使用参数就好了,不要用new ...


    大家好,我是程序员爱酸奶,希望您能喜欢我的文章。可以专注我个人公众号获取更多内容。

    下面开始正文啦~~~


    BUG

    1.Not enough arguments.

    在这里插入图片描述
    上面的这种bug在项目中很常见,参数都用new Object[]{}封装起来。特别是从class文件反编译回来成的java文件格式也是这样的。但是如果要消除bug的话直接使用参数就好了,不要用new Object[]{}封装。
    在这里插入图片描述

    2.This branch can not be reached because the condition duplicates a previous condition in the same sequence of “if/else if” statements

    if分支中不能出现两个分支一样的情况。
    在这里插入图片描述

    把重复的删除掉就可以了。

    3.Use try-with-resources or close this “FileInputStream” in a “finally” clause.

    在这里插入图片描述

    提示资源没有关闭,需要在finally中进行资源关闭,但是把资源关闭放到finally中由提示这样写不规范有异味。所以它推荐的写法是将创建资源流的代码放在try()中,这样系统会自动的关闭资源,不需要我们写.close()方法,如图
    在这里插入图片描述

    4.A “NullPointerException” could be thrown; “document” is nullable here.

    在这里插入图片描述
    这种提示是指可能存在空指针异常,需要增加空值检测。
    在这里插入图片描述

    5.Cast one of the operands of this addition operation to a “double”.

    在这里插入图片描述
    这里提示的是在进行操作运算之前应该先进行类型转换。下面是他提供的一些规范和不规范的实例。
    在这里插入图片描述

    可以看出来,基本上是给提示的参数进行强类型转换,怎么知道应该转换什么类型呢,可以点击对应的方法查看这个参数是什么类型的,就将这个参数强转成这个类型就好了,比如上面的doubleTostring()方法的第二个参数是double类型的,所以强转一下就好了,如下:
    在这里插入图片描述

    6.emove or correct this useless self-assignment.

    在这里插入图片描述
    提示是删除或纠正这种无用的自我分配。一看上面的代码,因该是哪位大佬写错了吧,所以改成temp2[i]=temp1[i];也算消除了异味

    7.Save and re-use this “Random”.
    在这里插入图片描述
    这种提示是随机数应该需要重用,然后他给出的参考是这样的
    在这里插入图片描述
    在类中定义一个Random,然后在方法中可以重复使用,但是我按照这个方法试了一下没发现并不可行,导入下面的两个包都会报错,应该是需要什么额外的jar包才行感觉。
    在这里插入图片描述
    所以做了一个消除bug的方法。如下图,其实感觉变复杂了哈哈,但是消除了bug
    在这里插入图片描述

    8.Use an “instanceof” comparison instead.

    在这里插入图片描述
    上面代码都是报这个bug,提示不应该按照名称来比较类。
    不要求类名是唯一的,只要它们在包中是唯一的。 因此,尝试根据类名确定对象的类型是一种充满危险的练习。 其中一个危险是恶意用户将发送与受信任类同名的对象,从而获得可信访问。
    相反,应该使用instanceof运算符或Class.isAssignableFrom()方法来检查对象的基础类型。
    下面我是通过isAssignableFrom()来消除bug的。如下图:
    在这里插入图片描述

    9.Prevent “int” promotion by adding “& 0xff” to this expression.

    在这里插入图片描述
    提示原始字节值不应与逐位运算结合使用,读取字节以构建其他原始值(如整数或长整数)时,将自动提升字节值,但该提升可能会产生意外结果。要防止此类意外值转换,请使用按位和(&)将字节值与0xff(255)组合,然后关闭所有较高位。所以在后面就加上“&0xff”如图:

    在这里插入图片描述

    10.Make “df” an instance variable

    在这里插入图片描述
    提示非线程安全字段不应该是静态的,所以把前面的static 修饰符去掉就可以。

    11.Either re-interrupt this method or rethrow the “InterruptedException”

    在这里插入图片描述
    这种interrupt异常,需要在catch中加上Thread.currentThread().interrupt();

    在这里插入图片描述

    12.Remove the unboxing from “Integer”

    在这里插入图片描述
    提示是这个Integer封装是多余的,所以直接用强类型转换就可以吧。
    在这里插入图片描述

    13.Use another way to initialize this instance

    在这里插入图片描述
    这个提示用其他的方式初始化,不要在定义的时候就初始化,修改如下:
    在这里插入图片描述

    遇到的基本上就是这些bug了,还有css中的一些bug,按照提示修改的

    14.Unexpected missing generic font family

    在这里插入图片描述
    将这两个body的样式合二为一,可以消除bug和漏洞

    15.Unexpected duplicate “display”

    在这里插入图片描述
    Display 重复了,删除掉一个。

    16.Unexpected unknown type selector “element”

    在这里插入图片描述
    空样式,直接删除掉。

    17. Change this condition so that it does not always evaluate to “false”

    (更改此条件,以便它不总是评估为“false")
    这是很多webservice文件中出现的一个bug。 如果后期会对webservice文件过滤,这个就可以不管了。不过也可以把这行删除掉,obj不可能为null if (obj == null) return false; 这样这个bug也没有了。
    在这里插入图片描述

    二 漏洞

    1.Use a logger to log this exception

    在这里插入图片描述
    这种提示就是异常应该用日志打印出来。
    在这里插入图片描述

    2.‘password’ detected in this expression, review this potentially hard-coded credential

    在这里插入图片描述
    提示密码不能直接这样传递,不安全。但是也没有提供参考的案例。所以我是这样的改的,也能消除漏洞。如下图:
    在这里插入图片描述

    3.Make areaList a static final constant or non-public and provide accessors if needed

    在这里插入图片描述
    类变量字段不应具有公共可访问性。所以把public访问修饰符,改成其他的修饰符,最好是private.
    在这里插入图片描述

    4.Secure this “Transformer” by either disabling external DTDs or enabling secure processing.

    在这里插入图片描述
    提示应该保护XML变换器。创建javax.xml.transform.Transformer但未启用“安全处理”或创建一个而不禁用外部DTD时,可能会发生XML外部实体或XSLT外部实体(XXE)漏洞。 如果该外部实体被攻击者劫持,则可能导致机密数据泄露,拒绝服务,服务器端请求伪造,从解析器所在机器的角度进行端口扫描,以及其他系统影响。
    进行修改如下可以消除漏洞:
    在这里插入图片描述

    5.Do something with the “boolean” value returned by “delete”.

    在这里插入图片描述
    提示当包含操作状态代码时,不应忽略返回值。也就是说不应该忽略文件删除操作的结果。
    所以进行如下修改,但是如下修改虽然修复了漏洞,但是新增了异味。
    在这里插入图片描述
    异味提示"java.nio.Files#delete" should be preferred (squid:S4042)。应该使用Files.delete()方法,而不能之间文件delete.所以最后修改成:
    在这里插入图片描述

    6.Make this “public static userInfoUrl” field final

    在这里插入图片描述
    这种“public static”字段应该成员变量应该是不变的,所以需要加上final修饰,如下:
    在这里插入图片描述

    还有几种漏洞不好修复,暂时没有思路

    7.Change this method so it throws exceptions

    在这里插入图片描述
    这种提示,TrustManagers不应盲目接受任何证书。通常会创建X509TrustManager接口的空实现,以允许连接到未由根证书颁发机构签名的主机。 这样的实现将接受任何证书,这使得应用程序容易受到中间人攻击。 正确的解决方案是提供适当的信任存储。

    8.Use the recommended AES (Advanced Encryption Standard) instead.

    在这里插入图片描述

    这种原来用DES加密的提示不应使用DES(数据加密标准)和DESede(3DES)。它推荐的使用AES.但是将DES加密改成AES加密虽然程序异味消除了,但是程序肯定不对吧,加密方式换了肯定会出问题的吧。

    三 异味

    异味太多了,我也没有消除太多了异味,一个项目异味一般都是好几k,所以消除起来一两个异味对基数没有什么影响,并且异味太多,消除一部分后,并没有感受到那种异味数量巨减的感觉,导致消除异味的积极性不是很高。并且有的异味是真的不好消除,有时候打开一个文件,几千行代码一片都是标异味。直接就放弃了。

    1.Replace the type specification in this constructor call with the diamond operator ("<>").

    在这里插入图片描述
    Java 7引入了菱形运算符(<>)来减少泛型代码的冗长。 例如,您现在可以使用<>简化构造函数声明,而不必在其声明及其构造函数中声明List的类型,编译器将推断该类型。如下:
    在这里插入图片描述

    2.Add a default case to this switch

    在这里插入图片描述
    swatch 中没有default,也没有break;虽然上面的代码不要break也不会有什么问题。但是万一哪天变了,不是return 就很容易出错了吧。

    3.Remove this empty statement.

    在这里插入图片描述
    两个分号,代码中有很多地方有这种情况感觉,删掉多余的。

    4.Remove this useless assignment to local variable “XXX”.

    在这里插入图片描述
    上图,定义的变量但是没有使用,就会抛出这种异味,解决这种异味,是需要看看这个变量有什么作用,没有作用的可以删除掉,如果不改随意改动,可以在他们下面增加一条日志打印他们,这样也能消除这个异味。

    5.Directly append the argument of String.valueOf().

    在这里插入图片描述
    String.valueOf()不应附加到String。这里我的理解是,result是string类型,arerType是int类型,在拼接的时候会自动的将int类型转换成string,不用多此一举。

    在这里插入图片描述

    6.Define a constant instead of duplicating this literal “XXXX” 4 times.

    在这里插入图片描述
    类似这种,当一个不变的字符串在一个文件中多次出现,就应该给这些字符串提取成常量,这样方便以后修改和维护。但是说实话提取常量这个异味真的很枯燥,并且代码中有大量的这种情况,感觉每个项目或者每个模块都应该提取一个常量类,这样这个模块用到这些不变字符串,就直接从这个类中获取,但是这个工作量有点大哈哈,我就简单的尝试了一下,把自定义报表那部分提取常量,但是进行了一部分就没有进行下去了,枯燥且工作量大
    在这里插入图片描述
    在这里插入图片描述

    但是我觉得这个工作还是做比较好,这样便于以后的维护,常量值改变只用改一个地方就好了,不用所有地方都修改。

    7.Use a StringBuilder instead.

    在这里插入图片描述
    当字符串需要频繁变化时,用stringBuilder代替string .这里还有一种异味是代码中有的地方用的是StringBuffer,也需要转成StringBuilder.因为Stringbuffer是确保线程安全的,stringBuilder
    不用,所以stringBuilder效率更高。那会不会引发线程安全问题呢,不会,因为这个是在方法内部定义的变量,所以对这个方法而言是线程封闭的,不会引发线程安全问题。

    8.Reorder the modifiers to comply with the Java Language Specification.

    在这里插入图片描述
    提示修饰符的顺序应该符合java语言规范,它给出的参考如下:
    在这里插入图片描述
    所以把static修饰符 放到final就好了。

    9.Declare “XXX” on a separate line.

    在这里插入图片描述
    定义变量的时候,一个变量一行,便于查看

    在这里插入图片描述

    10.Return an empty collection instead of null.

    在这里插入图片描述
    最好不要直接返回null,应返回空数组和集合.如下:
    在这里插入图片描述

    11.Use isEmpty() to check whether the collection is empty or not.

    在这里插入图片描述
    判断集合时候为空是,不要使用size(),建议使用isEmpty()方法。如下:

    在这里插入图片描述

    12.This block of commented-out lines of code should be removed

    在这里插入图片描述
    这种可以直接删除掉,或者不想删除的可以用/***/注释,对于单行的可以把后面的分号去掉就不会报错异味了。
    在这里插入图片描述

    13.Remove the literal “false” boolean value

    在这里插入图片描述
    布尔文字不应该是多余的。用true或者false在if中判断是不好的写好,直接可以通过本身进行判断,如下:
    在这里插入图片描述

    14.Add a private constructor to hide the implicit public one.

    在这里插入图片描述
    如果一个类的里面的方法都是static修饰的静态方法,那么需要给这个类定义一个非公共构造函数(添加私有构造函数以隐藏隐式公共构造函数)如下:

    在这里插入图片描述

    15.Refactor this method to reduce its Cognitive Complexity from 55 to the 15 allowed.

    在这里插入图片描述
    关于代码圈复杂度大于15的异味,以及代码过长的异味,说实话也没有什么好的方法,只能读代码,然后抽离函数出来,当然抽离函数不可能一次就能做到代码简洁之道要求的那样,一个函数只做一件事,单一层次原则。但是我们也不能因为做不到这样就就什么都不做,还是要迈出这一步,先抽离函数,虽然没有做到单一层次原则,但是消除了异味。下面代码是对上面的进行简单的函数抽离,消除异味
    在这里插入图片描述

    16.关于代码中很多的stitch分支问题。

    在这里插入图片描述
    在这里插入图片描述

    这样代码上看去显得非常的臃肿且感觉特别low,但是这却是我们最喜欢写的包括我自己,因为简单进本不用思考。并且如下图,18个case都没有报异味,所以SonarQube上也没有检查出来,所以大家都将就先改其他,后来被数据端同事看到了下面这个代码,说代码简洁之道不是说不能用这么多的swatch么?我竟然一时不知道怎么回答,只能说修改成本太大,不好改。但是事后自己仔细想想自己接受这段代码看的也感觉特别low,那自己为什么不能对自己的要求高一点呢,所以痛定思痛打算改这段代码。

    我修改这部分代码采用的是枚举类型,先创建一个枚举,并将所有的case换成对应的枚举值,然后创建两个成员变量和一个带两个参数的枚举的构造方法。然后实现这两个成员变量的get方法,使得其他类可以访问。如下图:
    在这里插入图片描述
    然后在原来的swatch的代码中,删除这些分支,创建这个枚举,并根据分支创建对应的枚举值,如下:

    在这里插入图片描述
    这样就完成啦,看起来总算比那么多的swatch-case舒服很多吧,并且也没有那么low了。

    17.还有一些其他的异味消除。直接贴图

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    两个分支一模一样的,需要删掉其中一个。然后像这种有很多if-else if的getsql()方法的圈复杂度肯定是超过了,这里比较好的方法我也不知道怎么做,但是我是将整个分成多个一样的if-else if的方法。但是这样只能消除异味,代码的可读性变差。
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述
    条件语句如果是单行,需要使用缩进。
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    18.还有一些不知道怎么清除的异味。

    在这里插入图片描述
    在这里插入图片描述
    异味有很多,不会清除的异味也肯定不止这些,难清除和不会清除的异味可以先记录下来。先把容易的好清除的异味清除掉,应该也能达到标准吧,至于难清除的,以后可以一起讨论看看怎么清除。

    展开全文
  • 程序员的bug修复宝典

    万次阅读 多人点赞 2020-12-28 01:36:00
    程序员对bug的感情可谓是五味杂陈:一方面bug非常可恶,尤其是一些偶现的bug,它强大到可以摧毁一个优秀程序员的意志;另一方面很多bug又是程序员自己亲手写下的,无奈之余只能自嘲一句:不写bug我们就要失业了! ...

    前言

    bug, 又名程序缺陷或者程序漏洞, 是每个程序员每天都回避不了的东西。程序员对bug的感情可谓是五味杂陈:一方面bug非常可恶,尤其是一些偶现的bug,它强大到可以摧毁一个优秀程序员的意志;另一方面很多bug又是程序员自己亲手写下的,无奈之余只能自嘲一句:不写bug我们就要失业了!

    作为一名职业程序员,同时也是一名开源创作者, 夸张点说,我解过的bug可以绕地球一圈, 每天写bug解bug几乎是我的日常。

    但是,作为一个善于思考和总结的技术up主,我怎么能止步于每天写bug和解bug呢?更何况,人生在世,总得有点追求。既然我不能够阻止bug的产生,那么就让我总结一点bug的修复技巧,让bug消失地更快点吧!


    1.bug修复的生命周期

    中医讲究"望闻问切",其实修复一个bug就像给病人看一场病,本质上是相通的。

    当我们遇到一个bug(问题)的时候,一般我们需要经历如下6个步骤:

    • 1.了解bug。我们首先需要到底出了什么bug,现象是什么,怎样发生的。
    • 2.复现bug。在了解了bug的大致情况之后,我们需要能够找到复现的路径,这就为后面bug的定位提供可靠的依据。
    • 3.定位bug。当有了稳定的复现途径之后,要做的就是打断点、打日志进行调试,来一步一步分析和定位bug,到底是那块代码导致的错误。
    • 4.确认bug。当我们定位到bug出错的地方之后,我们就需要分析这到底是不是bug。如果是bug,那么这个bug出现的根源是什么,到底能不能解决。
    • 5.修复bug。在明确了bug的根本原因之后,下面就需要发挥我们的聪明才智去修复这个bug了。
    • 6.验证bug。并不是每次我们修复完bug之后就可以万事大吉了,此时我们还需要去重现bug以确保bug被真正修复。除此之外,有条件的我们还需要去验证相关场景,以保证修复该bug不会引入其他bug。

    以上可以总结为12字方针–"了解、复现、定位、确认、修复、验证"bug。一般在稍微大一点的公司,都会有对应的流程对bug的修复进行流程控制,最终形成闭环。

    可以看到的是,其实修复bug只是解决一个bug的6个步骤中的其中一步。很多刚刚参与工作的程序员经常犯的错误就是一遇到bug,就开始漫无目的地看代码或者是上网各种瞎搜索,又或者各种无脑问,最后搞了一圈可能连自己要解决的bug到底是什么都不知道,这样解决bug的效率可想而知。

    可能读到这的你此刻非常想问:怎样才可以更快地修复一个bug呢?那么下面我就根据上面讲的六个步骤来分别讲解一下对应的技巧。


    2.解决bug的艺术

    在我看来,修复一个bug是相对容易的。因为修复一个bug的方法可能有很多种,但是如何从根本上解决一个bug,并保证这个bug下次不再复现的话,其实是非常难的,这就需要我们学习一下解决bug的艺术。

    2.1 了解bug

    俗话说,知己知彼百战不殆。bug修复的第一步当然是先了解bug了。

    了解bug是解决bug最重要的一步,它直接决定了后面五步执行的效率和质量。糟糕的错误报告和不负责任的问题描述都是埋葬程序员修复bug意志的罪魁祸首。

    在了解bug之前,我们需要收集足够的信息,了解它产生的现象、描述、复现步骤、以及解决后的预期是什么等等。那么我们应该怎么做才能更加全面地了解它呢?

    下面我给几点建议供大家参考:

    2.1.1 观察现象

    光凭文字说明是无法准确领悟到bug的精髓的。因为每个人思考问题的角度以及文字表达描述都是千差万别的。

    如果说这个时候能提供一段出错的视频或者问题截图,又或者能够现场演示错误的话,这样观察现象,然后再结合问题描述之后,一定能够帮助你快速地了解这个bug。

    2.1.2 询问相关人员

    这里你询问的可以不仅限于发现bug的人(一般是测试人员),当然你首先应当询问的还是这个发现bug的人。

    这里你需要着重询问bug报告上你觉得迷惑的点,比如出现bug的应用版本、设备型号、bug出现的频率、bug产生的步骤和恢复的途径、bug修复的预期效果等。这里你需要进行刨根问底地询问,因为可能bug发现人觉得一些无关紧要的细节,对你来说却是至关重要的点。

    问完发现bug的人之后,我们还可以向bug对应模块的负责人(测试、开发、产品)询问该模块的业务逻辑,说不定能够获取到有价值的信息哦。

    2.1.3 提供bug报告模板

    一份优秀的bug报告模板,可以让程序员直接跳过bug修复的前三步,直接进入到确认bug步骤,从而能够极大地提高bug修复的效率。那么一份优秀的bug报告模板应当具备哪些内容呢?

    • bug的标题和问题描述
    • 出现bug的应用版本
    • 出现bug的设备信息(型号、版本等)
    • bug产生相关的视频、截图和错误日志
    • bug复现的步骤
    • bug出现的必要条件(环境)和恢复途径
    • bug修复后的预期效果
    • bug对应的模块或者关联bug

    有了以上的内容之后,相信程序员能够很快地了解这个bug,定位出bug产生的原因并予以解决。

    2.2 复现bug

    如果你在第一步了解bug中获得了良好的bug报告的话,则此部分可以很容易。你只需要按照bug报告中的bug复现步骤,按顺序操作即可稳定复现bug。

    当然,很多时候往往并不是一帆风顺的,即使你手握bug报告,做了非常详细的调查工作,然而bug就是无法复现,那么这个时候我们应该怎么做呢?

    2.2.1 重新了解bug

    此时为了能够复现bug,你可能需要回到上一步,重现去了解bug。因为你之前对bug的理解可能产生偏差,又或者你第一步并没有做好才导致了bug未能复现。这个时候带着疑问去重现了解bug,可能你会发现新的大陆。

    2.2.2 将偶现bug转为必现bug

    偶现bug算是bug家族中最调皮的一个了。它们以没有规律,难以复现等特性,经常能把以一个好好的程序员给逼疯。

    但是既然是要复现bug,那么肯定要找到bug稳定复现的路径,这样才能方便下面bug的定位。这里我推荐大家的一个做法就是想办法把偶现的bug转化为必现的bug。因为即使是偶现的bug,很多也是特定条件下必现的bug,只不过此时你还没发现这个特定条件而已。

    那么怎样才能将偶现bug转为必现bug呢?这里我简单介绍一下我常用的技巧:

    • 1.对比法:观察并对比复现和不复现的各方面条件,找到那个必现的特定条件。

    • 2.注释(删除)代码法:对怀疑的代码进行注释(删除),直到彻底将偶现bug转变为必现bug。

    2.3 定位bug

    一旦我们找到了bug稳定复现的步骤之后,下面的工作就是开始定位bug产生的地方了。

    这一步可以说是解决bug的关键环节,这一步骤的难易程度一般取决于以下几个因素:

    • 1.程序员自身的代码量(工作经验)
    • 2.对项目代码(业务)的熟悉程度。
    • 3.分析问题和解决问题的能力

    那么我们如何才能更快地定位出bug产生的位置呢?下面我提供一些思路供大家参考:

    • 1.断点调试法。这是程序员通用,同时也是最有效的定位问题的方式。一个不会断点调试的程序员和瞎子没有本质上的区别。
    • 2.日志分析法。其实并不是所有bug都可以进行断点调试的。比如在一些循环调用或者业务较为复杂的场景下,打日志分析定位是较为适合的方式。
    • 3.排除法。如果一个bug产生的原因可能有多种情况的时候,这个时候采取排除法的方式是最优的。你可以把可能导致bug产生的代码块都打上日志或者断点,然后重现一下bug进行问题的定位。
    • 4.代码回滚法。如果你这个bug在之前的版本是好的,但是在现在版本上又出现了,这个时候就可以使用代码回滚大法。把你的代码回滚到你怀疑的版本,运行看bug是否消失,然后对两个版本之前代码有何区别,最终定位出bug产生的位置。这里我们可以使用二分法来提高代码的回滚效率。
    • 5.注释(删除)代码法。这个我在上一个步骤中也提到过。对于一些难以理解和定位的bug,我们可以使用这个方法进行尝试。不过这个方法使用起来有一定的风险,因为可能你删除的那一串代码虽然能够解决bug,但是却不是bug产生的根源,这个时候你可能会将必现bug改成了偶现bug,让问题变得更加复杂。
    • 6.源码分析法。有的时候有些bug可能并不是你的代码导致的问题。可能是第三方库本身的bug,又或者是系统本身的bug,又或者是你误用api导致的问题,这个时候就需要你拥有源码分析的能力。深入源码中,一层层分析直到最终找到bug产生的原因。
    • 7.联想法。通过一些类似的bug修改经验从而联想猜测出bug产生的位置。这个方法对使用者本身有较高的要求。需要使用者对项目代码和业务逻辑非常熟悉,同时对问题分析的能力有较高的要求。这就是我们常说的牛人能够一眼就能看出问题,他们常用的就是这种方式。
    • 8.场外支援法。这是实在定位不出bug才采取的下下策。因为它并不能提高你定位bug的能力,同时请别人帮忙定位bug,你就需要把你之前所做的工作都要全盘地向他表述一遍,这样不仅会降低bug修复的效率,同时还不一定能保证定位出bug产生的位置,它取决于你表述问题的能力和帮你的人分析和解决问题的能力。

    2.4 确认bug

    在我们定位出bug产生的位置后,下面的工作就是分析bug产生的根源了。

    这一步可以说是bug修复6个步骤中最为关键的一步。这一步直接决定了这个bug能否被彻底地解决,同时也是最能体现bug修复艺术的步骤。

    但是很遗憾的是,这一步往往被很多人给忽视了。我为什么会这样说呢?因为很多时候我们修复bug的时候,都会受到各方面的限制:

    • 1.自身经验水平的限制:一些初入项目的程序员经常因为修复一个bug而导致了另一个bug,又或者只是看到了bug的表象却不能感知到bug产生更深层次的原因,所以10种产生bug的情况他可能只改了一种,将必现问题改成了偶现问题,让bug变得更加复杂。
    • 2.时间限制:这是我们程序员经常碰到的限制。这在互联网企业非常普遍,通常解决一个bug是有时间限制的,例如:这个项目明天就要上线了,并强制要求你今晚就得想办法解决。这个时候你可能就被逼无奈,采取硬编码的方式去临时把这个bug给按住。其实这样虽然bug是被临时解决了,但是却会让这个bug变得愈加复杂。很多公司出现的那些祖传代码就是在这种情况下产生的,动一下就可能产生无数未知的bug,令人绝望。
    • 3.业务限制:很多时候导致代码逻辑非常复杂难懂的罪魁祸首就是这种业务限制。我们在修复一个bug的时候,很多时候就是因为这种业务的限制,导致bug的修复一种不能从根源上予以解决,只要业务一调整就可能导致这个bug反复地出现。

    说了这么多限制,那么我们如何才能找到问题的根源呢?

    • 1.多积累经验,提升自身的水平:这是打破自身经验水平的限制。
    • 2.及时处理bug:在收到bug报告的第一时间就去处理,尽可能打破时间的限制。
    • 3.多熟悉业务:有时间就多去了解和梳理业务,深入研究项目代码。这样我们在解决bug的时候也不会因为对业务不熟悉而无法分析出bug产生的根源。
    • 4.准确定位bug:bug定位的准确性直接决定了你能否分析出bug产生的根源。因此你需要仔细分析和定位bug,使用我上面介绍的8种方式去定位bug。

    2.5 修复bug

    其实前面的四步都是为这一步所做的铺垫。有了前面四步的工作,相信到这儿也是相对微不足道的了,剩下的就是如何优美地解决这个bug了。

    到了这个阶段,bug通常不需要大的修改来修复,因此这一步往往会非常快,当然也就没有什么好的技巧啦。

    2.6 验证bug

    作为bug修复的最后一步,它是确保bug被真正修复的最后保障。

    在这里需要我们着重注意以下几点:

    • 1.重复之前复现bug的步骤来验证bug是否被彻底解决。
    • 2.验证bug修复可能改动到的相关模块是否正常,保证bug修复不引入新的bug。

    如果上述有任何一点没有达到的话,请返回步骤四和步骤五,重新修复bug!


    3.如何提高bug修复的效率

    上文我们着重讲解了解决bug的艺术,为的是能够更好地解决bug。但是如何才能保证既有效,又快速地修复bug,提高bug修复的效率呢?

    通过上面对于解决bug的艺术的讲解,我们可以总结出以下影响bug修复效率的几个关键点:

    • 1.bug信息收集的效率以及有效性。
    • 2.时间限制的压力。
    • 3.人员对项目代码(业务)的熟悉程度。
    • 4.人员自身经验和分析问题的能力。

    以上4点可以说直接决定了bug修复的效率。那么如何才能提高bug修复的效率呢?下面我将一一给出我的看法。

    3.1 建立健全的信息收集机制

    bug信息的收集可以说是修复bug过程中最为耗时的环节。提升bug信息收集的效率以及有效性可以大幅度地提升我们修复bug的效率。

    那么我们应该如何建立健全的信息收集机制呢?这里我给出我的几点建议:

    3.1.1 提供优秀的bug报告模板

    上文我们在了解bug一步中提到过:一份优秀的bug报告模板,可以让程序员直接跳过bug修复的前三步,直接进入到确认bug步骤,从而能够极大地提高bug修复的效率。

    这里我再次重复一步,一份优秀的bug报告模板应当具备哪些内容:

    • bug的标题和问题描述
    • 出现bug的应用版本
    • 出现bug的设备信息(型号、版本等)
    • bug产生相关的视频、截图和错误日志
    • bug复现的步骤
    • bug出现的必要条件(环境)和恢复途径
    • bug修复后的预期效果
    • bug对应的模块或者关联bug

    3.1.2 建立完备的日志体系

    一套完备的日志体系,可以让我们更加清晰地知道用户到底做了什么才导致bug的出现。

    在项目的初期,我们可能为了赶工期而常常忽视了日志打印的重要性,这很可能就会导致该项目日后的维护将非常得艰难。

    那么我们为什么要建立一套完备的日志体系呢?

    • 1.并不是所有的用户(测试)都能够给你描述清楚bug产生的信息。
    • 2.即使用户(测试)给你描述了bug产生相关的信息,但是他们并不理解你的代码逻辑,他们只能根据bug出现的现象告诉你问题,可能他们的表述和你的理解不在一个频道。

    如果你有这么一套完备的日志体系,那么你就可以在用户(测试)不用开口的情况下,直接get到用户的操作行为以及对于的代码逻辑。同时,可能一句关键点的报错日志就可以帮你直接定位到bug产生的位置,从而直接进入第四步确认bug

    说了这么多,我们应该如何打印高效的日志呢?

    • 1.在异常分支返回前打印日志。
    • 2.在复杂业务流程的关键点打印日志。
    • 3.在对外交互或者模块交互点打印日志。
    • 4.在用户交互或者生命周期的关键点打印日志。
    • 5.对重要的信息点打印日志,记录用户画像。
    • 6.按重要性分等级打印日志。
    • 7.禁止在循环中打印日志,禁止打印无效的日志。
    • 8.禁止打印用户隐私相关的信息。

    3.2 建立自动化测试机制

    建立自动化测试机制,可以让突破时间限制成为可能。

    3.2.1 更早地发现bug

    很多时候来自时间限制的压力,往往是测试不充分导致的。很多bug直到产品临近上线或者交付的时候才被发现,这个时候唯一解决问题的方式就是在时间上做出限制,无情压迫我们这些活在公司权力最底层的程序员们。

    如果这个时候能有一套自动化测试机制,每天下班后都进行自动测试的话,那样很多bug就能被提前发现,从而为我们修复bug预留了不少宝贵的时间。

    3.2.2 节约bug验证的时间

    对于一些复杂难解、偶现的bug,我们往往会在确认bug验证bug之间花费大量的时间。这个时候如果有一套自动化测试机制或者工具帮助我们验证bug的话,就可以极大地缩减我们修复bug的时间。

    3.3 提高项目代码(业务)的熟悉程度

    提高人员对项目代码(业务)的熟悉程度,这样就可以极大地提高人员定位bug的效率。

    3.3.1 建立丰富的知识库体系

    建立一套丰富的知识库体系,可以帮助我们加深对自己责任内项目代码(业务)的理解,同时还能帮助我们快速了解我们所不了解的业务模块。

    那么如何才能建立起丰富的知识库体系呢?下面我给出我的几点建议:

    • 1.对知识进行分类。
    • 2.定期添加和更新知识库的内容。
    • 3.提高知识库的检索效率。
    • 4.定期组织知识的分享。
    • 5.激励贡献知识库的人员。

    3.3.2 建立责任田划分机制

    划分责任田的目的就是:让专业的人做专业的事情。

    划分责任田的好处:

    • 1.专业的人做专业的事情。划分完责任田后,田主需要对自己负责的模块负责,这就必然要求其对模块内的代码(业务)更加熟悉。
    • 2.责任到人利于追责和bug跟踪。

    当然责任田也不是想象中的那么完美,它也存在一定的缺陷:

    • 1.职责明确之后可能导致缺少全局视野。一些复杂的bug可能是几个模块共同作用下才产生的,对于这类bug的定位势必会大大增加难度。
    • 2.划分责任田之后,可能导致踢皮球的情况。

    责任田划分机制,它是一把双刃剑。所以是否需要建立责任田划分机制,还是需要结合企业自身的情况而定的。

    3.4 提高人员的综合素质

    提高人员的综合素质,可以帮助我们提高定位bug确认bug以及修复bug三个步骤下的效率。

    • 1.建立公平的员工晋升制度。这样可以充分调动人员的主动性的积极性,提升人员的个人素质和业务能力。
    • 2.建立岗位轮换制度。让人员定期负责不同的模块,可以极大地提升人员的综合素质和全局视野。
    • 3.定期组织培训学习

    4.最后

    以上内容,是我参与工作五年,开源六年以来所总结下来的全部经验,喜欢的可以点击收藏或者三连支持一下!最后,还是祝福大家从此代码无bug,哈哈哈!!!

    5.微信公众号

    更多资讯内容,欢迎搜索我的微信公众号:【我的Android开源之旅】

    展开全文
  • Bug管理系统BugFree

    千次阅读 2019-02-21 20:46:49
    BugFree是借鉴微软的研发流程和Bug管理理念,使用PHP+MySQL独立写出的一个Bug管理 系统。 下载XAMPP安装工具 https://pan.baidu.com/s/1FFXRWxQBPHla-UajBDcZLg XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建 ...
  • bug流程简图

    万次阅读 2020-06-20 15:42:37
  • PyTorch(总)——PyTorch遇到令人迷人的BUG与记录

    万次阅读 多人点赞 2017-06-28 16:42:04
    这篇博客就用来记录在使用pytorch时遇到的BUG,虽然年纪大了,但是调出BUG还是令人兴奋^_^! BUG1: 在使用NLLLoss()激活函数时,NLLLoss用来做n类分类的,一般最后一层网络为LogSoftmax,如果其他的则需要使用...
  • 定位bug

    千次阅读 2018-10-23 17:09:23
    测试工程师不只是负责发现bug,除了发现bug这种基本功外,定位bug,提出解决方案,提出预防方案也是要掌握的技能。这里先说定位bug的要求,定位bug要更深入,前提当然是对功能、产品的流程、开发方案、开发人员非常...
  • 解决bug问题,查找bug的方法

    千次阅读 2020-07-08 14:32:35
    想告别“写代码2分钟,找bug两小时”吗?,就必须掌握查找bug的能力 下面这些方法都是我这几年解决bug常用的 一、定位bug:如果在控制台中看不出bug,可以使用以下方法帮助查找bug 1、IDE编译器debug调试代码,在...
  • BUG分析

    千次阅读 2018-04-16 11:06:01
    建议从以下几点分析总结BUG,尽量用数据去量化和证明 1. BUG分布图(可明确知道哪些模块存在BUG多),及对应rd的开发质量、qa漏测情况 2. BUG严重性(BUG严重性,严重错误和次要错误占有比例大,相对系统的功能不...
  • BUG状态

    2018-07-04 17:05:38
    "状态”和"解决”域定义并且跟踪了bug的...RESOVLED”,但是通常的情况是bug需要先被指定这个bug的属主开发人员确认。NEW----bug已经被加入到属主的bug列表中,必须被处理。在这种状态下的bug即将被接受且...
  • 在测试过程中,作为软件测试工程师,经常会遇到bug定位问题,也是其中一个重要的问题就是到底如何判断自己提交的bug属于前端问题还是属于后端问题? 要知道自己提交的bug属于前端还是后端问题,那么首要需要理解...
  • Bug报告

    千次阅读 2018-08-28 20:10:47
    bug报告当中一些必备的内容: 硬件平台和操作系统: 1)测试应用的硬件平台(Platform),通常选择“PC” 2)测试应用的操作系统平台(OS) a) 版本 提交缺陷报告时通过该字段标识此缺陷存在于被测试软件的哪个版本...
  • BUG处理规范

    2019-04-03 19:57:17
    为了减少开发、测试在Bug上花费不必要的沟通成本,同时为迭代总结会提供报告依据,督促开发提升质量意识,制定以下规范内容。 相关职责 角色 职责 测试人员 1. 根据规范提交...
  • CSDN粉丝解答:六月份第二期精选——互联网笔试编程解决、简单bug处理、编程系统设计等 导读:因博主后台留言太多,各种奇葩问题都有,博主只能随机挑选几篇对粉丝的解答,放出来与大家分享哈,哈哈…… 博主...
  • 尽量避免bug的一些手法

    千次阅读 多人点赞 2018-12-28 11:43:32
    尽量避免bug的手法
  • git bug分支管理

    千次阅读 2020-06-16 11:16:28
    软件开发中,bug就像家常便饭一样。有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除。 当你接到一个修复一个代号101的...
  • 1、录制bugfree的登录、新建bug、解决bug的脚本 2、如何查看那些是有效的脚本 简单点:一般都是post或者get请求,找图片是绿色箭头的,再对比请求头和输入, 其他复杂情况请查看: 3、打开jmeter,将数据的链接...
  • 什么是bug 怎么找bug

    2013-09-05 13:41:30
    什么是bug 怎么找bug 我是个菜鸟 请大神来解答一下
  • Bug避障算法简介(Bug1 & Bug2)

    千次阅读 2018-05-22 20:09:56
    基本概念 障碍物是指妨碍机器人通行的静止状态和运动状态的物体。 避障是指移动机器人根据传感器感知到的障碍物的状态信息,包括障碍物的... Bug算法大概是人们能想象到的最简单的避障算法。其基本思想是机器人在...
  • 本博主自2020年6月1日起,如有任何问题可在博客贴吧留言或者私信博主(包括并不限于GUI软件编写、安装及编程语言中的bug、AI算法设计等),非诚勿扰! 导读:因为博主后台留言实在是太多太多,大多网友都是前来...
  • 软件测试工程师的职责是发现BUG,此外,如何体现个人价值?那么我们试想,只提出问题而不去解决,问题就永远得不到闭环。所以,一个资深的测试人员的基本功应该是这样的:深挖业务和功能需求,找出BUG,定位BUG,...
  • bug修复报告

    千次阅读 2019-08-19 19:53:50
    BUGID Bug的唯一标志,由bug管理系统自动生成 Bug标题 简明扼要地对Bug进行概要描述 产品名称 软件产品的名称 功能模块名 产品子系统 产品版本 测试平台 ...
  • 如何区分前端BUG和后台BUG

    千次阅读 多人点赞 2019-06-03 14:54:46
    这里先说定位问题的要求,定位问题要向深入,前提当然是对功能、产品的流程、开发方案、开发人员非常熟悉了,以我们部门为例,定位bug至少要到下面这种程度。 首先确定是界面显示问题还是功能问题 如果是界面问题,...
  • 首先是BUG的严重等级 BUG优先级 BUG的分类 缺陷/bug的状态 New: 当你发现一个bug的时候,需要与项目负责人或者你的leader沟通以确认发现的确实是一个bug,如果被确认是一个bug后,就可以将其记录下来,并将bug...
  • 一、bug的优先级 bug的严重等级是客观的 bug的优先级是qa结合严重等级、复现概率、用户感受度等主观产出的参数,用来指导rd修复bug的次序,更合理的评估当前版本的可发布程度 可以从用户体验角度考虑优先级: 导致...
  • 小编推荐:Fundebug提供...吃饭的时候,测试提着Bug过来了。 当他们要求我添加已存在的功能时 当我第一次启动我的单元测试时 程序没有看逻辑关系就抄过来 我改了500个Bug,但是!! 实习生找 Bug ...
  • 在我们睡觉的时候,程序能不能自动查 bug

    万次阅读 多人点赞 2019-12-05 13:19:52
    作者介绍:我和我的 SQL 队(成员:杜沁园、韩玉博、黄宝灵、满俊朋),他们的项目「基于路径统计的 sql bug root cause 分析」获得了 TiDB Hackathon 2019 的三等奖。 曾在 Hacker News 上看到过一个 Oracle ...
  • web测试中,如何判断是前端的bug还是后端的bug呢?

    万次阅读 多人点赞 2019-01-23 16:25:28
    web测试中,如何判断是前端的bug还是后端的bug呢? 通常可以利用抓包工具来进行分析。可以从三个方面进行分析:请求接口,传参,响应。 1.请求接口url是否正确 如果请求的接口url错误,为前端的bug 2.传参是否...
  • bug管理系统

    2019-08-31 17:05:31
    bug管理系统 一. 常见的bug管理系统 禅道 (zentao) bugzilla,jira 比较强大,但是搭建起来比较困难 bugfree easybug 免费开源,在线网站类型 Mantis QC(QualityCenter) TD 不管是开源的还是商业的bug管理工具,本质都...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 716,414
精华内容 286,565
关键字:

bug