单元测试与仿真程序之间的选择

ops/2025/3/6 3:54:36/

为什么写这篇文章

现在的工作需求,让我有必要总结和整理一下。
凡事都有适用的场景。首先这里我需要提示一下,这里的信息,可能并不普适。
但是可以肯定一点的是,有些人,不论做事还是写书,上下文还没有交待清楚,就对你说单元测试如何重要,这种是极为无耻的。
是的,我是说无耻。因为说风凉话的人,他们不需要像那些奋战在一线的程序员那样,需要面对结果质量与进度和成本,以及维护性之间的考量,他们只需要在意自己说的话是不是看来永远正确即可。
这么说吧,一个想要他说的话永远正确,只需要故意将上下文删除即可,这也就是人们常说的站着说话不腰疼,或者永恒正确的废话,或者何不食肉糜之类的正确但无用的话。这些话往往常出现在书籍上。

但是,现实中,我们每天都需要面临痛苦的选择:是让自己良心好受一些,写出质量过得去的程序,还是让老板看到,我又出活了这样的表面文章。

所以,我们必须要考虑如何测试,以及如何避免重复相同的错误这样的问题。

然而,测试从来不是一件简单的事,事实上,我的硕士论文写的就是如何在被测对象升级之后,自动测试的脚本,能够95%以上自动升级的故事。这个我们不多说了。但大家都知道这是一个困难的事情。所以我的论文开篇讲的是自动测试的消亡史。

讲到测试,我们就不得不考虑测试的方法。
所有的书上,都强调Unit test是必不可少,多么重要。

这点了解我的人都知道,我是嗤之以鼻的。

正确的事,就好比亚当.斯密的《国富论》,认为自由竞争是是经济的基石;而事实是,人们总会有想尽办法使自由竞争失效。
同样,这些看似正确的废话,只能带来灾难。软件行业的灾难性失败还少吗?这些大公司没有做单元测试吗?
以微软为例,2003年,当时我还在某为,听说微软过了CMM2级,我说了一句:微软从此再也不能开发出有完整度的软件。一语成谶。

铺垫这么多,就是想对一些人说:凡事需要考虑上下文,不要被所有的书里都认可的话所蒙蔽:所有的写书的人,大多没有在一线工作过。

单元测试VS模拟(或仿真)程序

后面我们来比较一下这二者

单元测试的适用范围

1。 相对简单的程序或产品。
2。 与设备无关的程序或产品。
3。 需求变动相对慢的程序或产品。
4。 设计良好,接口清晰,与人机界面交互不多的多线程的每个模块或层之间。
上述为一般的单元测试能取得良好效果的上下文。

单元测试的问题

对代码有依赖。

这显然是最严重的问题。
有人说,为什么我要极客编程的原因正是如此,因为以前测试与研发是相对的,因为体制要求如此,但测试发现,研发的人可以随意改代码,所以白盒测试就消亡了。
所以,管理者就想到让程序员吃自己的狗食这样的损招:自己写自己的单元测试——反正嘴一动就可以了,这多简单。他们不考虑这么做带来的后果是什么。

这是一个悲哀的时代的原因是真正的程序员,已失去是了话语权。
那么有人说,是你自己的狗食,做得不好吃是你自己的问题。
然而事实真的是这样吗?
需求变动,产品经理认了客户当干爹,他敢对干爹说不吗?
还是苦一苦程序员吧。
设计错误,所有的PMP(我不是说PMP认证,我是说拍马屁那个PMP)的组长,敢对总工说不吗?
还是苦一苦程序员吧。
接口常变动,程序员同样没有权力找横跨多个部门的技术官僚体系去说理。
还是苦一苦程序员吧。

所以,这狗食难吃,也许只有不到1%的问题,在程序员。
所以,程序员现在不仅要捏着鼻子做难吃的狗食,还要自己吃了。

当然我们需要肯定单元测试的价值

如果你有良好设计的复杂的程序,所有的模块相对独立,接口相对稳定,
并且这个程序是多线程程序,那么单元测试是能发挥出极大的价值的。
如果再加上我写的论文里描述的,当被测对象发生改变时,自动测试脚本也能自动升级,显然对程序员是有利的。
当然,这是永恒正确的废话。
因为分工是你程序员浇水,官僚体系吃桃子。
呕,我忘了说,这种分工很公平:一棵树,一人一半,你要下面,我要上面。你一直浇水,我一直吃桃子,对了,老吃桃子也很累人的,你们浇水人不会懂我们的痛苦的。一人一半,很公平,放称上称称,一定一样重的。。。
或者说,除非这项目是你一个人在写。
多数情况,单元测试害处多于利益。
原因很简单,导致这种情况的官僚体系,是无人问责的(单向向上体系)。责权不对等。当然,他们吃桃子也很累,我也很有同理心的。

所以总结:
一个人的项目,而且项目很复杂,设计可控,接口清晰,需求清楚,而且你要对被测的对象非常了解,才可以。

模拟(或仿真)程序

当然一般我们是指模拟程序。除非有条件(作设备仿真)。
人们有个误解,认为互联网程序代表程序员,这显然是错到离谱,离了大谱。
广大的程序员,是需要与设备或硬件打交道的。
所以,模拟或仿真程序,是至关重要的。
原因是绝大多数公司,无法提供足够的硬件给程序员。

程序员的困难在于,有困难无处去说,比如说,我需要行拿到设备,才能逐渐的了解它的习性;
但领导却坚持认为,你是懂的,你非常懂。
等你刚懂,这个项目完事了,新的设备又到了。
所以,程序开发是个动态过程,这些话,领导是无法理解的,因为中国的情况,目前的领导都是硬件出身,麻麻不懂。而且也不讲道理。我这么说是有依据的。

在这样的情况下,写单元测试,是相当离谱的。

但是,写模拟程序却是非常必要的。

这是从技术开发和技术管理两个视角来看的。

因为模拟程序的仿照对象仅仅是我们的target,而unit的服务对象却是我们的程序。
这个你稍微理解一下就懂了。一个是对哈雷彗星,另一个是对哈雷将军。

也就是说,我们自己写程序,是最不可信的,因为你在信息的最后一道工序,没人在乎你。
但设备不同。
所以,不论你如何改代码,都不会影响simulator。
这是最关键的要点。与unit test不同。
我常说,第一点占75%以上。
但是后面的不重要的理由我们也要说说。

资产保值性

资产保值这件事,也是有水分的。因为你得是“资产”,才有必要保值。
一堆垃圾代码,它就不是资产。
单元测试的代码,往往如此。因为它要测的对象如果是个垃圾,它就一定是垃圾。

可是,simulator却不是这样的。
因为它mirror的对象是真实的设备。
随着公司工程的一年一年的积累,这个simulator会变成emulator的一部分,最后会变成产品的一部分,最后,会比产品更好。

以ABB的机器人为例,了解过的人都知道它的simulator有多强。FPGA的程序,DSP的程序,直能能跑。机器人也是三维CAD动画模拟出来的。
用户不需要买robot就能完全与买了一样给机器人编程。

这个算是15%?

管理角度

利用分工,也就是说,大公司,可以专门派专人写simulator,这点其实非常有价值的。注意是专岗。
如果有公司这么做,说明这老板有水平。
尽管中国大多是垃圾公司,管理极为垃圾。
但如果你的老板有这水平,恭喜你。尽量多干几年。
啊对了,你不可能设立专岗写unit test。前面这我解释得好多了。

后记

可千万不要以为,单元测试不重要。
其实我也写的。
因为我能做到可控。
因为是我一个人在干。我对我的能力也相当自信。所以我用。
但我尽最大可能,会集中精力写模拟程序,因为太必要了。


http://www.ppmy.cn/ops/163489.html

相关文章

【C#】检查已有窗口,防止重复打开

winform项目只允许打开一个窗口 在 WinForms 项目中,如果 希望 程序只允许打开一个主窗口,可以使用 单实例模式,防止用户重复启动应用程序。 ✅ 方法 1:检查已有窗口,防止重复打开(推荐) 如果 …

[arXiv 2025]BP-GPT: Auditory Neural Decoding Using fMRI-prompted LLM

论文网址:BP-GPT: Auditory Neural Decoding Using fMRI-prompted LLM 论文代码:https://github.com/1994cxy/BP-GPT 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现…

Ai-web 1.0靶场通关攻略

1.环境 虚拟机:kali 靶机:ai-web-1.0 2.获取靶机ip 确认靶机ip为192.168.13.160 3.获取绝对路径 用御剑扫描发现两个路径 http://192.168.13.160/robots. txt和http://192.168.13.160/index.html 发现一些路径 用kali的dirb扫描发现一个info.php文件…

Spring Cloud Alibaba学习 4- Spring Cloud Gateway入门使用

Spring Cloud Alibaba学习 4- Spring Cloud Gateway入门使用 中文文档Spring Cloud Gateway 中文文档 一. 基本使用 1. Predicate配置 1.1 配置参数介绍 直接通过官方给的application.yml介绍,这里就不介绍简写方式了,直接介绍完整方式 spring:clo…

Jedis、Lettuce和Redisson性能设计

一、Jedis源码级学习要点 1. 线程模型与连接管理 阻塞式I/O设计:通过Socket直接建立连接,每个命令发送后线程会阻塞等待响应25连接池实现:JedisPool管理物理连接,避免线程安全问题,核心类GenericObjectPool实现连接复…

Skynet入门(一)

概念 skynet 是一个为网络游戏服务器设计的轻量框架。但它本身并没有任何为网络游戏业务而特别设计的部分,所以尽可以把它用于其它领域。 设计初衷 如何充分利用它们并行运作数千个相互独立的业务。 模块设计建议 在 skynet 中,用服务 (service) 这…

中科大 计算机网络组成原理 1.4 接入网和物理媒体 笔记

一、接入网核心功能与架构 ‌核心作用‌ 接入网是连接用户终端与核心网络的桥梁,承担用户身份认证、带宽分配、数据加密等功能,直接影响网络服务的可靠性和用户体验。例如,杭州电视台的数字人主播通过光纤专线实现零失误新闻播报,…

Unity插件-Mirror使用方法(五)组件介绍(​Network Identity)

目录 一、插件介绍 二、主要组件 Network Manager Network Manager HUD 三、Network Identity 1、组件介绍 2、核心功能 网络唯一标识 同步生命周期 权限管理 组件依赖 3、关键属性与配置 4、基础使用方法 1. 添加与配置 2. 脚本中的访问 5、高级功能与示例 1…