zoukankan      html  css  js  c++  java
  • 先解决思想:为何要写单元测试

     

    写单元测试简直是傻,如果不符合预期,我就直接改我自己的代码好了。

    如果说领导让研发写单元测试,我敢打赌80%的研发脑海里都会想过这个问题。 我写了一个函数,这个函数的结果我当然知道是什么,但是为什么我还要写一个单元测试来确定这个事情?

    我的答案是,再简单的事情,都有可能出错

    让我们想想我们的工作中的情况在自己写功能的时候,有多少情况是自己一次编写就能确保这个函数能够一次编译通过的?随着自己工作年限的增长,我写的代码越多,就越明白一个道理: 人是会犯错误的,无论这个错误有多么低级

    以下是一个非常简单的例子。

    class Member
    def need_notication?
    return false if %w(cancel paid).include? self.status
    self.expire_date - 1.week > Time.now
    end
    end

    如此简单的代码,程序员一眼就能看明白,那为什么我们要对如此简单的代码写单元测试呢?

    有一天下午,我晕晕乎乎的读到这段代码的时候,觉得这里的 expiration 的判断有问题,于是乎,改为了

    self.expiration_date + 1.week > Time.now

    当时比较忙,觉得改动很简单,直接push代码了 
    由于早期写这个功能的时候顺手写了个简单的单元测试

    it "could send expiration notification correctly" do
    member = build(:member, expiration_date: 5.days.since)
    assert_equal true, member.need_notication?

    member2 = build(:member, expiration_date: 1.month.since)
    assert_equal false, member.need_notication?
    end

    push代码后一两分钟,我们的CI系统 flow.ci 就发邮件提示单元测试失败了,打开邮件一看,原来是自己脑袋不清醒瞎改东西了。

    会有人说,自己不会犯这个错误,其实我在清醒的时候也不会犯这种错误,但是我深知自己肯定会有不清醒的时候。

    就像那句著名的概率学玩笑 “不可能事件随着时间的累积是一定会发生的” 一样,项目越大,越久,出现各种自己预想不到的错误越大。该大写的小写了、打字 “O” 结果按到 “0” 了等等问题,都会出现,更别代码提逻辑上的错误了。

    当然,很多种方式可以避免这种问题。大多数人使用工手动测也能发现类似的问题:在代码中加 print, 或者在 IDE中debug自己刚写的代码,手动跑一跑就可以解决。

    然而换个角度想想,为什么不能将“手动跑”这个过程代码化过来呢?我将手动测试转化为单元测试时间大概是原来手动测试的 2-3 倍。乍看起来还挺多的,然而却解决了我另外一个问题:无论什么时候,我都能确保我的函数是测试过的

    一般在上线的时候大家都会问,“所有功能测过了么?” 如果这次上线是一次大上线,积累了很多功能,我相信没人能够说“都测过了”,就算都测过了,也会因为时间间隔太久,而不敢确定这件事情。但如果自己写过单元测试,则每次运行测试的时候,所有测试用例都会运行,会非常有底气的说,都测过了。

    更重要的是,当项目的代码发生变更的时候,仅仅跑一下测试,就能重复之前的测试动作,判断修改的代码是否影响到了之前的逻辑。特别是当项目由很多人参与的时候,时常代码的逻辑就被你不知情的改变了,而跑一遍单元测试,如果代码的改变影响到了测试的逻辑,则测试就会failure,这时大家就可以充分的意识到修改的内容影响到了哪些代码了。

    这一系列的好处,仅仅是比手动测试多出 2-3倍 的时间而已。远远低于在出问题后debug的时间。

    很多时候,我们拒绝做出那些看起来无趣的事情,然而就是那些看起来很愚蠢,很繁杂的事情,却会在你不经意的时候,拯救于你。不信,你可以想想背包里的伞,以及钱包里的夹层。

    确定引入单元测试后,肯定会有一些阵痛感,如何降低这些阵痛,提高单元测试的价值,下次写 “小谈单元测试写法”。

  • 相关阅读:
    ConCurrent并发包
    volitale最经典理解
    java中关于volatile的理解疑问?
    一直对zookeeper的应用和原理比较迷糊,今天看一篇文章,讲得很通透,分享如下(转)
    架构师成长之路
    rocketmq,zookeeper,redis分别持久化的方式
    rocketmq持久化方式
    源码主干分支开发四大模式
    HDU 4876 ZCC loves cards(暴力剪枝)
    webView用法小结
  • 原文地址:https://www.cnblogs.com/jicheng1014/p/6083220.html
Copyright © 2011-2022 走看看