V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
asj
V2EX  ›  程序员

感觉在这里 TDD 不是很受欢迎啊

  •  
  •   asj · 2018-04-13 08:43:47 +08:00 · 10930 次点击
    这是一个创建于 2451 天前的主题,其中的信息可能已经有所发展或是发生改变。

    有没有特别的原因啊?

    发个自己用 TDD 解 leetcode 题目的练习

    https://www.bilibili.com/video/av21007067/

    欢迎拍砖。

    第 1 条附言  ·  2018-04-13 17:26:36 +08:00
    看到很多人说起改需求,

    这里有个题目,虽然是简单的例子性质的,但是还是挺像现实中需求变动的情况的。

    有兴趣的话,可以自己试试有测试和没有测试一步步改过来的区别。
    http://osherove.com/tdd-kata-1/

    也有视频可以观摩:
    https://anotherdave.wordpress.com/2010/01/13/calculator-tdd-kata-in-javascript/
    64 条回复    2018-04-16 05:44:05 +08:00
    LokiSharp
        1
    LokiSharp  
       2018-04-13 09:08:35 +08:00
    这里,讨论技术的人里面业余开发者比较多。。。没有规范约束的话没什么人愿意多写测试的。。。
    projectzoo
        2
    projectzoo  
       2018-04-13 09:27:51 +08:00
    发现楼主似乎用键盘刷网页?
    asj
        3
    asj  
    OP
       2018-04-13 09:31:17 +08:00
    @projectzoo 是的 vimium
    codehz
        4
    codehz  
       2018-04-13 09:52:44 +08:00
    TDD 还可以理解为 Type-Driven Develop (
    Zeahoo
        5
    Zeahoo  
       2018-04-13 10:01:48 +08:00
    看完了,楼主是看啥学的 TDD,感觉用 TDD 方式写代码,心里会比较有底。
    cxh116
        6
    cxh116  
       2018-04-13 10:10:33 +08:00
    没有什么欢迎不欢迎,只有个人的喜欢不喜欢.

    这就跟 v2 喜欢推荐 apple 产品一样. 楼主明明说了不要 mac ,还狂推荐,有意思吗?

    跟一个撸着袖子就是干,一个文件写到底的人谈 TDD ,有意思吗?
    asj
        7
    asj  
    OP
       2018-04-13 10:10:42 +08:00   ❤️ 1
    @Zeahoo TDD 基本概念很简单,好像是在解析极限编程里最先看到的。要想真正用起来摸索了很久。其间收获最大的书是 重构,修改代码的艺术,clean code。
    sulang
        8
    sulang  
       2018-04-13 10:31:08 +08:00
    我司现在全部要求 TDD,很爽
    asj
        9
    asj  
    OP
       2018-04-13 10:34:25 +08:00
    @sulang 我们也要求,但是没人理。说说你们怎么搞这么 nb 的。

    我的感受是如果程序员自己想 TDD 很爽,如果被 TDD 就很不爽。
    chenxytw
        10
    chenxytw  
       2018-04-13 10:45:38 +08:00   ❤️ 6
    TDD 比较适合有明确目标且目标不会轻易变更 0 0
    国内的程序员工作环境,能让产品不三天两头改需求。不随意变更需求截止时间就烧高香了 0 0
    在需求时间很紧,且随时可能变更需求的情况下,TDD 有些吃力不讨好 0 0
    可能刚写完 T, 准备开始下手了,产品和你说这里要改,然后截止时间要压缩,这种情况下能选择抗住压力去改 T 然后按部就班的做完的人很少。
    niubee1
        11
    niubee1  
       2018-04-13 10:53:56 +08:00
    匆匆写好的 T 的代码有 bug 怎么办? 谁保证你的 T 没有 bug? test test 代码的 test 代码, 那么谁又保证你的 test test 代码的 test 代码没有 bug? TTTDD ?
    asj
        12
    asj  
    OP
       2018-04-13 10:57:57 +08:00
    @chenxytw 我倒是觉得 TDD 特别适合整天改需求的情况。

    如果需求特别稳定,写好了 30 年都不会变,那其实源代码没有了也没啥关系嘛是不是?
    asj
        13
    asj  
    OP
       2018-04-13 10:59:41 +08:00
    @niubee1 既不能保证实现代码没有 bug,也不能保证 test 代码没有 bug。只是写代码的一种方式而已。
    qile1
        14
    qile1  
       2018-04-13 11:09:25 +08:00 via Android
    @chenxytw 我想请问下我前段时间弄了个这种代码 python3.6 的:

    首先从 oracle 数据库查影像 dcm 文件路径,
    然后通过本地映射驱动器,把路径转为本地路径,使用 gdcm.exe 程序运行 cmd 批处理命令把 dcm 文件转为 png 文件,

    然后用 pil 把 png 转为 jpg,然后利用 py 的 ftp 库把文件上传到另一台 ftp 服务器

    然后连接另一台 mssql 数据库把文件路径转为 ftp 地址写入数据库表里

    这个如何写 tdd
    qile1
        15
    qile1  
       2018-04-13 11:10:29 +08:00 via Android
    忘记说了,正常程序开发我在别地方,服务连接上面说的两个数据库及文件服务器,我在外网,那些服务器安装在医院内网
    asj
        16
    asj  
    OP
       2018-04-13 11:50:52 +08:00
    @qile1 听起来很繁琐的样子,仿佛都能想象到各种调错的困难了。你是怎么搞定的啊?
    wspsxing
        17
    wspsxing  
       2018-04-13 12:23:23 +08:00
    Arnie97
        18
    Arnie97  
       2018-04-13 12:30:20 +08:00 via Android
    @qile1 写一大堆 mock …
    gladuo
        19
    gladuo  
       2018-04-13 12:34:45 +08:00
    Cool
    feverzsj
        20
    feverzsj  
       2018-04-13 12:40:09 +08:00
    tdd 开发效率太差,互联网公司最喜欢的是直接出产品让用户测试,大不了快速迭代
    ericls
        21
    ericls  
       2018-04-13 12:50:53 +08:00 via iPhone
    @feverzsj 大方向可以 有些地方 特别是明明清楚一定要有测试才放心的地方 不如就 TDD 咯……
    Phariel
        22
    Phariel  
       2018-04-13 13:28:08 +08:00 via Android
    个人是反 TDD 党 随着 IDE 的不断增强类型检查不断深入以及语言越来越成熟 在代码层面出错的概率已经降低了很多 现在出错的大多是数据层面的东西 你数据开发的时候 mock 的再好也挡不住上线出幺蛾子 这就得快速上线→让用户来测→快速迭代来保证
    hu6360567
        23
    hu6360567  
       2018-04-13 13:29:17 +08:00 via Android   ❤️ 4
    我们开发一般都是 DDD,deadline driven
    we000
        24
    we000  
       2018-04-13 13:31:59 +08:00   ❤️ 1
    我个人觉得 TDD 以及很多软件工程的方法, 本质上都是为了保证猴子编码的质量, 把人当猴子当工具, 默认都是低质量的码农.

    出于个人兴趣和意愿的话, 很少有人愿意这么搞.
    lol173
        25
    lol173  
       2018-04-13 13:47:46 +08:00
    @chenxytw 有理
    chenxytw
        26
    chenxytw  
       2018-04-13 13:56:10 +08:00
    @asj
    从道理上来说你是对的,但从国内的现实来说,缺少时间的考虑。
    维护一份完善的 100%覆盖率的 case 基本上等同于开发一份业务代码了。
    国内一大堆赶工的东西,上线后 bug 都一大堆,我甚至都可以想到可能连基本的自测都没有做好了。
    让他们去自增差不多一倍工作量去维护 case 简直是天方夜谭 0 0

    而且 TDD 也不是一个人做可以不管团队其它人的东西,只要一个人没有按照 TDD 来搞,就很可能导致 TDD 执行不下去。
    chenxytw
        27
    chenxytw  
       2018-04-13 14:08:49 +08:00
    @qile1 额,TDD 的前提当然是你能有一个跑通 case 的环境。
    假设这个环境有了,那么 case 简单点划分可以是
    case 1. 正常情况
    1.1 dcm 路径指向文件是否存在
    1.2 png 文件是否存在
    1.3 jpg 文件是否存在
    1.4 另一台 ftp 文件是否存在
    1.5 mssql 中 ftp 记录
    case 2-n. 异常情况 如果代码中有预期处理异常情况的,相对应的 case

    至于实现测试代码的方式很多,
    mock 呀,甚至自己单独写一份测试代码都可以
    asj
        28
    asj  
    OP
       2018-04-13 14:12:40 +08:00
    @we000 嗯,同意。如果是“被 TDD ”的话就是把人当猴子。

    我自己做的主要动力是有了测试就能重构了,否则整天看糟心的代码又不敢改,有损健康啊。
    amon
        29
    amon  
       2018-04-13 14:22:33 +08:00
    之前有个帖子是你所在公司开发有多少人,结果都是几个人,甚至一个人的。。。

    说明 v 友所在小公司居多,还没有养成习惯的。
    czzhengkw
        30
    czzhengkw  
       2018-04-13 14:29:41 +08:00   ❤️ 1
    TDD 的意义在于修 bug、加 feature、重构代码的时候,不至于影响到原来的功能,也就是不会引入新的 bug ……



    @hu6360567 DDD 跟 TDD 不是同一种类型的概念……
    DDD 更多的是把需求变成可用代码表达的东西,当然它也提倡 TDD ……
    @we000 事实上当公司假设员工都是高质量的码农的时候,出问题的机率更高。而且,能掌握 TDD 的码农,都是工程师,他们的工程思维更强,写的代码质量更高
    chenchangjv
        31
    chenchangjv  
       2018-04-13 14:57:36 +08:00 via Android
    我还以为是……时分复用,又要炮轰移动了呢
    Martin9
        32
    Martin9  
       2018-04-13 15:09:45 +08:00
    键盘控制鼠标好用么,准确度啥的。。
    asj
        33
    asj  
    OP
       2018-04-13 15:13:13 +08:00
    @Martin9 不好用啊,鼠标还是实际鼠标移动啊。
    AntiGameZ
        34
    AntiGameZ  
       2018-04-13 15:30:39 +08:00   ❤️ 1
    TDD 对工具,平台的要求太高了。很多时候配个持续集成都磕磕巴巴的公司,或者上了持续集成但是部署基本还是要靠手的情况下,TDD 成了负担而不是解决方案。

    程序员如果一周就开一个小时的会,沟通基本靠邮件。有完善的持续集成和可依赖的本地测试环境,写好的代码 commit 后可以不用管的话,估计 TDD/BDD 才会更受欢迎才是。
    lance0z
        35
    lance0z  
       2018-04-13 15:58:32 +08:00
    现在大部分纯互联网公司比较注重快速,迭代,即敏捷开发模式。
    asj
        36
    asj  
    OP
       2018-04-13 16:03:33 +08:00
    @lance0z TDD 不是敏捷开发的一项重要实践嘛。

    我一直觉得,没自动化测试的敏捷都是假敏捷。
    xiaozhizhu1997
        37
    xiaozhizhu1997  
       2018-04-13 16:45:00 +08:00 via iPhone
    难道只有我以为楼主想说中国移动
    hantsy
        38
    hantsy  
       2018-04-13 16:52:51 +08:00
    @asj 这个我认同,不写测试,然后搞什么敏捷,CI/CD 自动化都是自欺欺人。
    hantsy
        39
    hantsy  
       2018-04-13 16:58:37 +08:00
    @AntiGameZ 真正的 Engineering,几乎要做到 no meeting,。。至于国内沟通还是靠吼的方式,几乎不可能。

    TDD 永远不会成为负担,在项目前期,好像写测试走通一个自动化 Pipeline 很费时间,但不写测试的后果是,项目后面花几倍的人力和物力去保证质量,加班就是变成常态了。
    lightening
        40
    lightening  
       2018-04-13 17:00:57 +08:00
    有的事情适合 TDD,比如有明确需求,知道自己要做什么。有的事情不适合 TDD,比如实验性质的科研项目。关键还是要看场景。

    我个人会在某些情况下使用 TDD,但不会过分神化 TDD。我并不认为 TDD 适合所有场景。
    另外贴一篇反对的声音: http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html
    q397064399
        41
    q397064399  
       2018-04-13 17:10:36 +08:00
    反对 TDD,上个迭代写的代码,下个迭代 逻辑就改的面目全非了,别说啥 OCP 原则了,
    一般都是从脑子里 找出所有需要改动的地点,然后赶紧铺代码,啥 TDD,写个测试,首先要保证测试是正确的,
    如果你的 testcase 在整个模块的生命周期就执行那么几次,然后又要被改动,那 testcase 的意义又何在呢?
    MajorAdam
        42
    MajorAdam  
       2018-04-13 17:11:39 +08:00
    妈耶, 整天改需求的
    asj
        43
    asj  
    OP
       2018-04-13 17:46:18 +08:00
    asj
        44
    asj  
    OP
       2018-04-13 17:47:36 +08:00
    @q397064399
    如果你的 testcase 在整个模块的生命周期就执行那么几次,然后又要被改动,那 testcase 的意义又何在呢?
    ---------
    不能赞同更多。

    所以我巴不得改代码的时候,每敲一下键盘就跑一次 testcase。
    kaneg
        45
    kaneg  
       2018-04-13 19:59:10 +08:00 via iPhone
    TDD 说起来是一种增加代码单元测试覆盖率的方式,但在实际中,很多程序员是排斥写单元测试的,所以很多搞 TDD 都是虎头蛇尾,一旦没有强势的管理层推动,往往就不了了之了
    yingfengi
        46
    yingfengi  
       2018-04-13 20:37:53 +08:00 via Android
    我这联通好像都是 FDD,等等,我们说的应该不是同一个东西
    langjiyuan
        47
    langjiyuan  
       2018-04-13 20:54:12 +08:00
    需求变动太大,一通电话需求改了大半,求着发封邮件确认.
    TDD 是个好东西,但是经不住 漫天飞舞的需求更改.
    如果可以搞定方案,宁愿前期加班赶测试代码...
    kx5d62Jn1J9MjoXP
        48
    kx5d62Jn1J9MjoXP  
       2018-04-13 21:02:36 +08:00 via Android
    tdd 从来就没受过欢迎,声势很大但从来都是非主流
    n1dragon
        49
    n1dragon  
       2018-04-13 21:35:22 +08:00 via iPhone
    我觉得通过写 test case 能让人更明确代码的逻辑,而且能模拟一些不常见的 edge case
    Philippa
        50
    Philippa  
       2018-04-13 21:48:17 +08:00 via Android
    按照经验, 测试是必须的, 但可以后面写。然而文档是最重要的, 文档驱动能很好地限制产品, 可靠地传达产品设计思路。那才是消耗最大的地方。现实中 TDD 带来的一点优点, 远远不如项目管理的重要性。我宁愿代码是避免多重继承的, 或是糟糕变量名又多重封装的, 这些比测试更重要。不然协作成本远远高出质量成本。有少量的质量问题通常也可以接受。
    hxtheone
        51
    hxtheone  
       2018-04-13 22:31:42 +08:00   ❤️ 1
    https://github.com/MrHuxu/leetcode 我也是这样来做 leetcode, 但是在工作中很难能做到这样, 讲真, 如果用写测试来当工作量汇报的话, 八成会被领导干死
    dddd1919
        52
    dddd1919  
       2018-04-13 22:38:10 +08:00
    一般 T 都最后补,很少 TDD
    kid1412621
        53
    kid1412621  
       2018-04-13 23:03:28 +08:00
    @codehz 我还是以为 tdd fdd
    msg7086
        54
    msg7086  
       2018-04-13 23:21:02 +08:00   ❤️ 1
    我来加个反对意见吧。

    我个人是很不喜欢 TDD 的。增加测试覆盖很好,但是我觉得 TDD 本末倒置了,很多时候为了测试而测试,反而忘了软件开发的原本要求 —— 软件开发。

    比如要设计一个返回 输入+1 的功能,先写单元测试:
    assert(add_one(4), 5)
    assert(add_one(-1), 0)
    然后写代码 add_one(in),会不会有人写成 return in == 4 ? 5 : 0 ?

    还有,当你没有一个方法的时候,先写测试再写方法,会让人的思维更优先地去让方法满足测试,而不是满足项目的需求。有很大的可能,会导致面向测试开发,而不是面向需求开发。

    我一直遵从的是 BDD,基于行为驱动开发,大量测试程序的行为而不是内部实现。可以剥离出来的类库函数则剥离出来以后再测试其对外的 API 接口。因为程序行为是和用户需求相关,而非内部实现,所以重构的时候不会增加大量的重写单元测试时间,同时也能保证需求里规定的行为被正确实现。

    当然我们的 BDD 里,集成测试是在功能结构设计完,代码写完以后再上的。
    fish47
        55
    fish47  
       2018-04-13 23:53:18 +08:00   ❤️ 1
    https://github.com/fish47/leetcode
    做算法题写一下验证是有用的,例如用 DFS 来验证 DP 算法。

    https://github.com/fish47/MPVDanmakuLoader/tree/dev
    普通工程写单元测试,好处是帮助你调整出更清晰的架构,避免代码改坏。坏处是多了一些不必要(?)的抽象 /封装。
    bitlaoyuan
        56
    bitlaoyuan  
       2018-04-14 06:51:28 +08:00
    一个人做自己的项目,一直都是 BDD,Bug Driven Develop
    ghostsf
        57
    ghostsf  
       2018-04-14 10:36:54 +08:00
    不适合 XP 极限编程
    lowzoom
        58
    lowzoom  
       2018-04-14 14:31:33 +08:00
    TDD 是好东西,可惜真正理解并掌握正确设计方法的人极少
    很多人都是理解个皮毛,然后就骂骂咧咧地用回他们那套“去实际运行环境中运行打断点看变量 /在控制台临时打印输出”的小学生做法了
    mightofcode
        59
    mightofcode  
       2018-04-14 17:01:05 +08:00
    TDD 不能应对快速变化的需求
    asj
        60
    asj  
    OP
       2018-04-14 17:36:33 +08:00
    @ghostsf 没看懂,是说现实中不适合使用 XP 极限编程?

    还是说 TDD 不适合 XP ? TDD 不就是极限编程首先提出的么。
    asj
        61
    asj  
    OP
       2018-04-14 17:44:31 +08:00
    @msg7086
    > 增加测试覆盖很好,但是我觉得 TDD 本末倒置了,很多时候为了测试而测试
    -----------
    同意,为了增加测试覆盖率而 TDD 就是本末倒置。

    > 先写单元测试:…… 然后写代码 add_one(in),会不会有人写成 return in == 4 ? 5 : 0 ?
    -----------
    如果程序员觉得先写成这一步有帮助,不妨写成这样再重构。当然不能停留在这里。原因是这种代码其实是重复,实现代码与测试代码之间“知识”的重复。具体就不多展开了。

    > 先写测试再写方法,有很大的可能,会导致面向测试开发,而不是面向需求开发。
    -----------
    如果在没有实现代码的时候就不基于需求写测试用例,那确实会出现这种问题。
    msg7086
        62
    msg7086  
       2018-04-15 09:08:49 +08:00
    @asj
    TDD 提的做法是,先写测试,拿 Fail,实现他,拿 Pass,重构他。
    而我们一般的做法是,先设计结构,写代码,然后写行为测试,拿 Fail 或者 Pass,然后再重构他。

    这样能够让「绝对测试」和「纯结构设计」之间找到一个比较经济实惠的中间点。

    事后测试的缺点是容易放过一些边界条件,因为测试会跟着代码的思维走,只能查到预期的错误,而很难查到非预期的错误。所以我们的事后测试还会和 Peer review 结合,让另一个人来检查代码和测试,从另一个视角来寻找问题点。

    优点嘛,可以有更多的时间花在结构设计和功能实现上,提高开发的效率,又不会引入太多的技术债,所以比较经济实惠。
    asj
        63
    asj  
    OP
       2018-04-15 10:11:22 +08:00
    @msg7086 事先写测试也还是容易放过一些边界条件。而且往往边界值是和具体实现相关的。如果你看我这次练习视频后半部分重构提升性能的地方,就会发现代码出现了新的边界值,而原有的测试并不能覆盖。

    TDD 只是以自动报错的方式定义预期的行为,自然不能查到非预期的错误。
    简单来说 TDD 中的 test 事实上是类似 checklist 里的 check,是帮助开发者更有效开发的。而不是 QA 领域所说的 test
    AntiGameZ
        64
    AntiGameZ  
       2018-04-16 05:44:05 +08:00
    @hantsy 干一件超过能力 /智商的事情,客观来说就是负担啊。

    TDD 好不好,好。覆盖率重不重要,重要。但是这都是建立在个人,团队会用 TDD,也确实具备 TDD 条件的前提下。

    所以或许把问题换一个方向:

    完全不懂 TDD 的团队,怎么样才能最高效的培训 /实践 TDD,从而尝到好处。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2705 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 12:32 · PVG 20:32 · LAX 04:32 · JFK 07:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.