TDD(测试驱动开发)是否已死?
Rails 大神、创始人 David Heinemeier Hansson 曾发文抨击TDD。
TDD is dead. Long live testing. (DHH)
此后, Kent Beck、Martin Fowler、David Hansson 三人就这个观点还举行了系列对话(辩论)
Is TDD Dead?
笔者作为一个多年在软件测试领域摸索的人,其实更多是跟同行们澄清 "TDD并不是测试活动",“TDD是开发活动”, TDD这里的“测试”和我们正常理解的软件测试并不是一个东西。
倒是很少认真思考过 TDD 本身的价值在哪?是不是真的有用。
这里就谈谈自己的理解:
1. TDD本身是一个开发实践
或者说是一种产品设计实践,准确说应该是对应软件的详细设计。
思路其实就是先根据需求,将需求拆分到足够细。在代码实现之前,传统的研发流程中会有详细设计,到伪代码这个层级。TDD其实起到的是类似的目的,只是方式上变成先思考这个需求拆分到方法级别后,方法对应的产出是什么,方法到达到什么目的。思考的结果就是先完成这里的Test,对应的其实是单元测试。
在有了各种路径和场景的Test之后,再编写代码让这些测试通过,这样其实就完成了功能的实现。
这样带来的好处是,因为测试已经包含了需要的逻辑,这样就便于产品的不断迭代、重构,只要测试能够通过,就不会担心因为修改导致功能的不可用。会为产品的不断优化提供保障。
理论上听起来不错,而且似乎也受到行业的广泛推崇。不TDD似乎就落伍了

2. TDD在现实中并不成功
作为多年的测试工程师视角,也参与过大量软件项目,其中不乏很多项目重点推行TDD的实践,并引入咨询师进行指导。但就我的个人观察,没有成功的。也没有一线的开发人员能真正地坚持TDD,大部分实践TDD的项目,最终也就不了了之。
结合题主给出的线索,这里的答案可能就是 “TDD已死”,或者就我个人的体会,TDD是一个理想化的产物,在实际实践中,放到复杂的产品需求和团队合作中,很难把理想落地并发挥它预期的作用。(题外话,敏捷项目实践也有点类似,理想化的产物)

3. 为什么TDD难以真正落地?
1)ROI不高。要达到TDD的目的,测试代码会是实现代码的数倍,在软件项目大部分都是进度、资源稀缺的情况下,按理想情况去投入TDD并不现实。
2) 更多是只从最小的方法层面去覆盖。即便足够高的单元测试覆盖,依然会有集成测试、系统测试的场景遗漏,集成测试、系统测试依然不可或缺。TDD本身对质量的保障作用不明显。(这也是为什么我说TDD更多是设计实践,不是测试实践;是开发活动,不是测试活动)
3)方法层面进行测试覆盖,必然牵涉到大量依赖Mock,而mock本身其实就潜在数据、场景和实际有偏差的风险。
4)开发工程师的思维模式其实更趋向追求确定性,而测试的思维模式是需要基于各种不确定性去发现测试路径。开发和测试这两种活动,先天上是比较对立的。一定要让一个角色去同时完成这两种活动,有点勉为其难。

所以我的看法:确实 TDD已死,或者说 TDD 本身就是先天难产
相关文章:
TDD(测试驱动开发)是否已死?
Rails 大神、创始人 David Heinemeier Hansson 曾发文抨击TDD。 TDD is dead. Long live testing. (DHH) 此后, Kent Beck、Martin Fowler、David Hansson 三人就这个观点还举行了系列对话(辩论) Is TDD Dead? 笔者作为一个多年在软件测试领域摸索的人&…...
Debezium系列之:实时从TDengine数据库采集数据到Kafka Topic
Debezium系列之:实时从TDengine数据库采集数据到Kafka Topic 一、认识TDengine二、TDengine Kafka Connector三、什么是 Kafka Connect?四、前置条件五、安装 TDengine Connector 插件六、启动 Kafka七、验证 kafka Connect 是否启动成功八、TDengine Source Connector 的使用…...
数据结构(一)顺序表
顺序表的概念及结构 线性表 线性表是具有相同特征的数据结构的集合 物理结构 不一定连续 逻辑结构 连续 顺序表 顺序表是线性表的一种,顺序表的底层是数组 物理结构 连续 逻辑结构 连续 顺序表分类 静态顺序表 struct SeqList {int a…...
如何在 Jupyter Notebook 执行和学习 SQL 语句(中)
1. 基础SQL操作 创建数据库和表,插入数据: import sqlite3# 创建SQLite数据库并连接 conn sqlite3.connect(example.db) cursor conn.cursor()# 创建用户表 cursor.execute(CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT…...
AutosarMCAL开发——基于EB Wdg驱动
目录 一、Wdg原理以及作用1.看门狗类型2.看门狗功能特点3.看门狗工作模式4.看门狗超时响应5.看门狗寄存器 二、WDG模块EB配置(TC3X系列MCU)1.WDG通用配置:2.WDG设置:3.时钟资源分配4.配置STM IRQ中断5.配置触发执行动作࿱…...
Linux(1. 基本操作_命令)
目录 关于超级用户root: root用户可以做什么? 避免灾难: 格式约定: 浏览硬盘: 命令行补全和通配符: 命令行补全: 通配符: 常用基本命令: 查看目录和文件ÿ…...
难点:Linux 死机定位(进程虚拟地址空间耗尽)
死机定位(进程虚拟地址空间耗尽) 一、死机现象 内存富裕,但内存申请失败。 死机时打印: 怀疑是: 1、内存碎片原因导致。 2、进程虚拟地址空间耗尽导致。 3、进程资源限制导致。 二、内存碎片分析 1、理论知识:如何分析内存碎片化情况 使用 /proc/buddyinfo: /proc/…...
小米路由器刷机istoreOS,愉快上网
istoreOS与openwrt openwrt是一个开源的路由器系统,市场上所有小米路由器的内部系统都是基于openwrt进行二次开发形成的,做了硬件适配和功能上的阉割,不太好用。 istoreos是小宝团队基于openwrt制作的一个发行版,更适合中国宝宝体质。页面简约华丽,完全兼容开源openwrt的…...
微信小程序 - 01 - 一些补充和注意点(补充ing...)
目录 一、节流二、在一个发请求的函数中,只有发生下拉动作,才执行关闭下拉代码 最近在学微信小程序,把学习过程中的一些补充和注意点总结一下,内容会比较简单,因为只涉及基础知识,供个人参考 一、节流 情…...
微服务实战——登录(普通登录、社交登录、SSO单点登录)
登录 1.1. 用户密码 PostMapping("/login")public String login(UserLoginVo vo, RedirectAttributes redirectAttributes, HttpSession session){R r memberFeignService.login(vo);if(r.getCode() 0){MemberRespVo data r.getData("data", new Type…...
windows 安装 ElasticSearch
1、下载安装包 下载地址:https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.14.3-windows-x86_64.zip ElasticSearch 目录结构如下: 2、配置JDK环境 ES比较耗内存,建议虚拟机4G或以上内存,jvm1g以上的内存分…...
Oracle Linux 9 (CentOS Stream 9) 安装 node.js 20
Oracle Linux 的 node 默认版本为 16,运行dnf update也无法改变大版本,还需要进行额外操作1 查看支持的版本 sudo dnf module list nodejs输出如下 Last metadata expiration check: 3:37:22 ago on Fri 11 Oct 2024 09:08:18 PM JST. Oracle Linux 9 Ap…...
【Axure安装包与汉化包附带授权证书】
一、下载Axure安装包与汉化包附带授权证书 1.下载汉化包 【快传】: 点击链接即可保存 2.解压安装包 解压下载好的压缩包,能看到有lang也就是汉化包,AxureRP-Setup-RC.exe 也就是Axure9的安装程序,以及汉化说明和授权码。 二、安装Axure9…...
SSH隧道验证的原理及实现例子
SSH 隧道验证原理详解 **SSH 隧道(SSH Tunneling)**是通过 SSH 协议将数据在客户端和服务器之间加密传输的一种技术。它可以在不安全的网络上创建一个安全的、加密的通道,用于传输各种数据,例如通过不安全的网络远程登录、传输文…...
[计算机视觉]chapter1
一、什么是计算机视觉 计算机视觉就是用计算机编程,并设计算法来理解在这些图像中有什么。计算机视觉是一门研究如何使机器“看”的科学,更进一步的说,就是是指用摄影机和电脑代替人眼对目标进行识别、跟踪和测量等机器视觉,并进一步做图形处理,使电脑处理成为更适合人眼…...
RTKLIB学习记录【postpos、execses_b、execses_r】
本文主要记录对RTKLIB源码中postpos、execses_b、execses_r 函数的源码解读,不涉及其中的天线、星历等文件读取的内容,且为个人理解,如果有误,欢迎交流讨论。 一、postpos 函数部分 /rxn2rtkp函数 → postpos函数传递参数&#x…...
docker,docker-desktop,docker-compose download
docker docker-compose download 百度网盘获取离线包链接release-notes 参考dockerdocker-composewlspowershell...
C#_带参数的委托进入队列执行
我们经常会遇到一些函数多个地方调用,但是只能单独执行的就需要把它放到队列中执行。 1.创建对应该方法的委托(传参和回参类型需要一致)。 //委托: public delegate void CameraTaskDelegate(byte cs, ref byte[] buffer);//对应函数: public void CameraSettingRead(by…...
【OpenCV】(二)—— 图片读取展示和保存
上一小节中我们成功安装了opencv,我们这次学习使用opencv最基础的功能,读取和展示图片,首先准备一张用于实验的样例图片【cat.jpg】如下: 然后就是创建一个python项目并导入相关依赖 import cv2读取图片 读取图片使用imread方法…...
【花卉识别系统】Python+卷积神经网络算法+人工智能+深度学习+图像识别+算法模型
一、介绍 花朵识别系统。本系统采用Python作为主要编程语言,基于TensorFlow搭建ResNet50卷积神经网络算法模型,并基于前期收集到的5种常见的花朵数据集(向日葵、玫瑰、蒲公英、郁金香、菊花)进行处理后进行模型训练,最…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
