V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
PixelMage
V2EX  ›  程序员

[讨论] 在业务系统中写了 e2e 测试,还需要写单元测试吗?

  •  
  •   PixelMage · Jan 15, 2020 · 3373 views
    This topic created in 2296 days ago, the information mentioned may be changed or developed.

    假设你现在实现了一个登录注册的系统

    你写 e2e 测试用例把你的所有的 http 接口的功能以及异常情况都测了一遍并通过

    这时候还需要写单元测试吗?

    如果用?为什么? 如果不用,那是否以后业务系统就只需要写 e2e 测试就好了?

    19 replies    2020-01-16 18:48:09 +08:00
    lihongjie0209
        1
    lihongjie0209  
       Jan 15, 2020   ❤️ 1
    你测试了 HTTP 接口就不需要测试 StringUtil 了? 单元测试测试的具体的代码, HTTP 接口测试的是具体的业务
    index90
        2
    index90  
       Jan 15, 2020   ❤️ 1
    如果你能确保你的接口测试用例,能够覆盖代码中所有可能的条件分支,那当然是最好的了。
    然而现实问题是,编写有效的接口测试比编写有效的单元测试成本更高。
    我这边的做法是,开发编写单元测试,覆盖 99%的代码行。QA 做功能测试,优先覆盖开心路径,逐步补齐异常测试用例。这样兼顾开发效率和软件质量。
    lihongjie0209
        3
    lihongjie0209  
       Jan 15, 2020
    @index90 #2 99%的单测覆盖率, 可以具体说一下吗
    kwrush
        4
    kwrush  
       Jan 16, 2020   ❤️ 1
    e2e 把所有分支和情况都 cover 了,那可比单元测试难度高多了,我觉得根本就不可能,何必自寻死路。
    PixelMage
        5
    PixelMage  
    OP
       Jan 16, 2020
    @lihongjie0209 其实我想表达的意思是,如果所有的业务情况,以及业务能考虑到的异常情况都通过了测试。为什么还需要考虑代码的单测?毕竟 it works?
    这只是我片面的想法哈,因为我觉得既然 e2e 都写好了,业务都 OK 了,我又何必在乎具体的代码。
    还请多指教~
    PixelMage
        6
    PixelMage  
    OP
       Jan 16, 2020
    @kwrush 可能是我写的系统的比较简单,最多也就十来张表,CRUD,所以都是直接写 E2E 不写单测,最近产生了这个疑惑——“为什么还要写单测”
    PixelMage
        7
    PixelMage  
    OP
       Jan 16, 2020
    @index90 学习了,感谢回复。可能是我现在的系统比较简单的缘故,我直接写 E2E 更快~
    lolizeppelin
        8
    lolizeppelin  
       Jan 16, 2020 via Android
    写单元测试的过程就是优化和重构代码的过程

    写接口测试做不到
    index90
        9
    index90  
       Jan 16, 2020
    @lihongjie0209 #3
    1. 每开发一个特性,就从主干拉出特性分支
    2. 开发完并加上单元测试,就提 MR
    3. MR 触发流水线,跑单元测试,计算代码行覆盖率,不达标就不通过
    4. 流水线跑通过后,才能合并回主干

    PS:关于特性,这里不是产品特性,更多是研发角度的特性,例如加个函数,加一个类等。我们一般趋向于把产品特性切分成多个更细的开发特性,这样可以确保分支不会离开主干太久。
    PPS:关于单元测试的有效性,执行层面上,只有代码覆盖率这一个可量化指标,而单元测试有效性只能靠自觉了( assert 的编写其实很影响单元测试的有效性的),例如一旦被发现“作弊”,就会被开除。

    不知道这是不是你想问的……
    index90
        10
    index90  
       Jan 16, 2020
    @lolizeppelin #8
    对,写久了单元测试,就会有这样的感觉:
    如果发现单元测试比较难写,就会考虑我的代码设计是不是有问题
    lihongjie0209
        11
    lihongjie0209  
       Jan 16, 2020
    @index90 #9 感谢回复, 我比较好奇你们的 service 层和 dao 层是做单元测试的.
    index90
        12
    index90  
       Jan 16, 2020
    @lihongjie0209 凡是人手写的代码都需要写单元测试,只要是个函数都可以写单元测试。实践过程里可能比较棘手的是如何 mock 了。刚开始的时候挺痛苦的,现在基本不会出现无法写单元测试的情况(除了要往老代码里加特性)。
    PixelMage
        13
    PixelMage  
    OP
       Jan 16, 2020
    @index90 想请教一下
    在 e2e 测试覆盖了所有业务逻辑的情况下,
    出于对业务系统稳定性的考虑,而不是代码逻辑优化的考虑下,
    是否还有必要再写单测?
    index90
        14
    index90  
       Jan 16, 2020   ❤️ 1
    @PixelMage 你这句话从理论上说没错,但实际上,你要 e2e 测试覆盖所有业务逻辑几乎不可能。

    而且服务程序还要考虑 failure 的情况吧,例如下游服务无响应,响应超时,例如数据库连接失败,查询失败等情况。如果要在 e2e 测试中完成,你还要部署这样的环境出来,而用单元测试的话就可以轻松覆盖这些异常情况了。

    回到你的问题:
    “在 e2e 测试覆盖了所有业务逻辑的情况下,” ——业务逻辑覆盖是否有可量化指标,如何证明你覆盖了“所有”的业务逻辑呢?
    “出于对业务系统稳定性的考虑,而不是代码逻辑优化的考虑下,”——系统稳定并不只有业务逻辑,还有其他异常情况考虑
    “是否还有必要再写单测?”——单元测试只是一种软件质量保证的手段,而且经过多年的考验,看看那些著名的开源软件有没有写单元测试。如果你觉得你比那些牛人聪明,你有比单元测试更好的手段去保障软件质量,你可以选择你的方法。
    PixelMage
        15
    PixelMage  
    OP
       Jan 16, 2020
    @index90 感谢你的回答,真的,我困扰了很久。

    确实如果你所说,我并没有考虑到下游没响应,数据库失败的情况,我只覆盖了业务的正常流和异常流。但我很好奇如何在单测里覆盖这些东西?不知道有没有 repo 可以参考一下(我是真的想学习一下,没有别的意思)

    “业务逻辑覆盖是否有可量化指标,如何证明你覆盖了“所有”的业务逻辑呢” ——也只能尽量,毕竟总有黑天鹅,尽量的意思就是 1. 梳理出所有可能的业务异常情况并测试到 2. 测试覆盖率

    “系统稳定并不只有业务逻辑,还有其他异常情况考虑”, “单元测试只是一种软件质量保证的手段,而且经过多年的考验
    ....你可以选择你的方法”——
    没错你说得对,但是在日常的业务系统开发中,而不是伟大软件开发中,经常会出现为了开发速度牺牲质量的 tradeoff,我其实很倾向于“只写 e2e 是一种比较划算的 tradeoff”。另:我问一个我在阿里写 java 的同事这个问题,他说:哪有时间写什么测试,直接丢给测试同学。所以我觉得这种现象是常见的。理想情况下,当然是都写最好,但是现实世界往往不尽如人意。

    再一次感谢你的回答~真的很认真,感谢。
    index90
        16
    index90  
       Jan 16, 2020   ❤️ 1
    @PixelMage 要找 repo 的话,可以上 github 上找,我看得比较多是 dgraph 和 k8s 的 repo (跟工作有关)。
    哦对了,我是 Gopher,Java 不是很熟,不过根据经验,标准库里面的例子就足够学了,我相信 Java 的标准库应该也有单元测试的。

    关于你最后一点“但是在日常的业务系统开发中,而不是伟大软件开发中,经常会出现为了开发速度牺牲质量的 tradeoff”,我想还是分享一下我的经历。(这里的质量,我理解的是程序是否有 bug,而不是代码优不优雅的问题)

    其实刚开始我们也是觉得写单元测试浪费时间,如果把开发活动框在从研发到打包这段过程的话,单元测试的确是影响了开发进度的。但是如果你把软件的发布,运营,bug 反馈,定位,修复,再发布这些环节考虑进来,你会崩溃掉的。

    “为了开发速度牺牲质量”,其实到了最后我们发现这是个伪命题来的,因为软件质量是第一位的。如果软件万一真的有 bug,即使不考虑业务损失,当这个 bug 出现的时候,你需要马上放下手上正在开发的特性,去排查定位,重建环境,代码修复,测试,打包,发布等,这一系列的工作牵扯到的不只是写出这个 bug 的那一位研发人员,而是牵扯到运维,测试等一系列人员。将人力成本,时间成本,沟通成本等考虑进来之后,其实整个团队的研发效能非常低的。

    当然,如果一个研发人员和一个测试人员合作无间,测试能够在出现 bug 的时候,就直接告诉研发人员是哪个模块甚至哪一行出问题了,这种分工也是没问题的,但是我没见过。语言沟通有效率本来就够低了,更何况现在研发和测试都不在一个办公室里,用 IM 发着文字沟通,又或者在看板上发评论来沟通 bug。

    “为了开发速度牺牲质量”这种观念很普遍,我猜是因为大部分研发人员都是个体在工作,容易把自己的职责框在写代码到代码提交之间。但当你开始关心整个研发团队的效能上时,你很容易发现问题。
    PixelMage
        17
    PixelMage  
    OP
       Jan 16, 2020
    @index90

    对于“业务系统是否应该写测试”,我觉得我们都是一致的,不写测试带来的都是短期的时间收益,和长期的整体研发效能损失。所以对于“为了开发速度牺牲质量——不写测试”,我也是觉得不可取的。

    但是我更想知道的是“ [业务] 系统里只写 E2E 不写单元来达到时间和收益的最佳 tradeoff”是不是合适的?
    我举一个量化的例子
    我假设写 E2E 测试能 COVER 90%的业务 BUG,需要花费 1 个单位的时间
    如果我再补上单元测试,能再补上 9.9%的业务 BUG,但是需要额外花费 1 个单元的时间

    那么此时我认为,只写 E2E,不写单元是比较划算的。
    这里有两个问题
    1. E2E 测试能不能 COVER 90%的业务问题?
    2. E2E 测试环境的搭建是否真的比单元测试简单?

    其中
    1.我觉得对于中小系统都是适用的,写完正常流和异常流的 E2E,我认为能够覆盖 80 90 的问题。
    2. E2E 的测试环境,如今在各种中大型开发团队,比如阿里,都是日常、预发、线上,三套或以上环境 ,天然就有公司准备好的环境,不需要你再去搭建什么,所有的系统都遵守了这个规则,所以在中大型团队,我认为这个没什么成本。在小型团队,那可能写不写测试都是问题了。

    综合来说,我想说的观点,一句话就是
    “在大部分非核心中小型系统里,只写 E2E 测试是权衡了效率和质量的好选择”
    index90
        18
    index90  
       Jan 16, 2020
    @PixelMage sorry,我看了前半句没看后半句,误解了你的意思。

    感觉我们的讨论有点跑偏,e2e 测试和单元测试其实是处在不同维度,解决的具体问题是不一样的,不能用来直接比较,不是一个非零即一的问题。

    单元测试是验证代码逻辑问题,而不是验证业务逻辑问题。
    相反,e2e 测试只能保证业务逻辑正确,但无法保证代码或软件是健壮的。(或者需要很大代价)
    PixelMage
        19
    PixelMage  
    OP
       Jan 16, 2020
    @index90
    我个人的粗浅理解是,一些核心基础中间件之类的,单测,E2E 我觉得都不能少。
    但是如果是一个业务系统的话,这可能就回到我提出的这个问题了~

    其实我个人的小心思是:既然业务 e2e 测已经 work 了,异常流也 cover 到了,单测带来的代码健壮提升 i don't care,毕竟后面还有 IDE,语言框架,lint, 代码风格检查,开发规约拉着我。

    这样可以提高业务的落地速度,但是要是说后续的可维护可扩展性的,写单测应该是会有提高的,但是提高多大,就不太好说了,估计每个业务系统可能都不一样。

    还是特别感谢你的回复,我收获了不少东西~~对单测的看法也没有那么片面了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1180 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 58ms · UTC 17:46 · PVG 01:46 · LAX 10:46 · JFK 13:46
    ♥ Do have faith in what you're doing.