IT 技术博客

编码,才是戴着镣铐的跳舞

couttast: 轻量级单元测试扩展静态库演化思路

七阶子
34 min, 6602 words

couttast: 轻量级单元测试扩展静态库演化思路

作为一名 Linux C++ 程序员,我自己手搓了个单元测试库轮子,来辅助与满足日常开发 的单元测试需求。从只有一个 tinytast.hpp 头文件开始,后面逐渐添加了一些外围功 能,觉得不一定适合坚持 header-only 库的原则,就将非核心的功能写在单独的 *.cpp 源文件中,编译为静态库。代码开源在 github ,国内的 gitee 也有备份。

我觉得编写单元测试的问题可以从以下几个层次来讲,从微观到宏观。

  1. 断言语句;
  2. 单元测试用例设计;
  3. 单元测试用例运行与管理;
  4. 单元测试库、框架与集成的设计;
  5. 可测试程序的一般原则。

下面,我将结合个人开发 couttast 这个单元测试库的思路,谈谈本人对这些单元测试 问题的理解。重点是前三点。

题外话,我在前公司是使用过 gTest 的。几年前来到现公司尴尬地发现没有单元测试 的风气,且当初项目对集成第三方库的管理一言难尽,就想从省事角度不想多引入三方库 增加构建的麻烦。加之之前在使用 gTest 时也遇到一些痛点与不便,就决定自己手搓 一个单元测试库或框架吧,根据自己实际遇到的需求逐步加料。

关于 tast 这个词的命名,原是从尝试 (taste) 删减一个字母以便与 test 等长而 来。

Read More

make 不干编译事的清奇妙用:子命令模式脚本

七阶子
48 min, 9596 words

引言

说起 make ,大家的印象想必都是 Linux 下用于编译构建 C/C++ 项目的原始工具。后来 随着 cmake 及其他多种构建工具的发展与流行,手搓 makefile 的情况应该越来越少 了。而且除了 cmake ,有些构建工具是根本不必生成 makefile 就直接自己处理依赖编 译项目了,这比借助 makefile 路径依赖还更高效些。于是 make 在构建系统的作用与地 位就逐渐淡出了。

不过再追溯一下 make 本源,它似乎并不是专为编译构建而诞生的。早期 Linux 的许多 经典工具都只有简单到令人吃惊的小功能,贯彻着“一个程序只做好一件事”的哲学思想。 所以 make 的核心功能也非常简单,就只是检测目标与依赖(文件)的关系,当依赖有更 新时,执行相应的命令让目标也得以更新。而这个功能,明面上完全看不出来它与用 gcc 编译 C/C++ 项目有什么必然联系。只过在 Linux 上工作的程序员先驱们,竟然能在这么 简单的 make 基础上,发展出完备而复杂的构建系统,也是令我们后学惊叹的。

所以我有时在想,在如今不一定需要用 make 来构建 C/C++ 项目的时代,利用 make 的 核心功能与思想,还能否玩出其他有趣的花样?本文就介绍笔者在实际工作中遇到的一个 常用场景,利用 make 来组织一堆简单小脚本,提供统一命令行用法,让 make 命令华丽 转身,活像个能带自定义子命令的命令行工具。而子命令模式,正是当前流行的命令行工 作方式,像 git docker systemctl 等强大的流行工具就是子命令模式。

Read More

深入浅出理解 rapidjson 与实践

七阶子
60 min, 11966 words

众所周知,JSON 是通用对象表示法。原全称是 JavaScript Object Notation ,是从 javascript 语言流行开来的。json 在 javascript 源码中就是合法的对象字面量表示, 可认为是后者的一个子集,语法更严格,但也更简单,基本可望文生义。后来也有人提出 json5 的扩展语法,能支持注释等,更接近 javascript 的语法(但仍不完全一样),但 也不如标准 json 那样流行,简单够用。

如今,几乎所有流行与不流行的编程语言都支持 json ,能将 json 文本串解析为各自语 言内部的对象模型表示。这是通过库来实现的,不能像 javascript 那样直接将 json 粘 贴到源代码中就是合法对象(一般可用在 = 作右值常量),虽然有的语言可能有语法 糖能在源代码中通过对 json 串作少量的修饰而转化为内部对象,但本质上也是经过了库 解析。而事实上,对于大对象,长 json 串,即使 javascript 也不会直接嵌在源代码中, 而是先从外部读入字符串,再通过 JSON 库将其解析为对象。

Json 的字符串文本表示,也叫对象的序列化,而将 json 文本转为语言内部对象的工作 叫反序列化。各大语言的 json 库的基本功能或主要功能就是这两个方面。本文将讨论的 C++ ,更是有许多不同的 json 库。笔者使用最多的是 rapidjson 库,这是个老牌的经 典 json 库,在 modern C++11 之前就存在的高性能 json 库,至今也在一众 C++ 常见 json 库的前一梯队。所以笔者强烈推荐这个 C++ 开源库,它是 head-only 库,只要下载 头文件,很容易集成进自己项目就发挥作用。

Read More

C++ 命名空间理解与践行

七阶子
61 min, 12077 words

众所周知,C++ 算是 C 的超集,提供了非常丰富的高级特性。对一般 C++ 开发者而言, 并不要求精通 C++ 的每个特性,而应该按需学习与强化。在众多特性中,也许命名空间 是很不起眼,平平无奇那个。但假如做个思想实验,摒弃 C++ 绝大部分特性,只保留一 个特性加到 C 语言中,哪个最有助于改善 C 语言项目的开发体验与维护体验?

我觉得不是类(虽然 C with class 也是 C++ 的一种实用范式),也不是模板,或其他 奇淫巧技,而是命名空间。就因为 C 语言中几乎只有一个全局的命名空间,所有函数、 结构体等类型,以及可能必要的全局变量,都塞在同一个空间,对维护大型项目而言 太拥挤太可怕了,很容易出现命名冲突。C++ 的命名空间(namespace)就是为解决这个 问题设计的,后现代大多数语言都有的模块(module)或包(package)的一个作用也能 解决命名冲突,但更主要的作用是从项目整体宏观上抽象出模块的分组与组织。

Read More

归类: 程序设计

标签: C++

用 perl 统计分析日志应用实战

七阶子
14 min, 2719 words

文本处理还是 perl 强,这是它发家的基本盘。我自学会 perl 后,每当有文本处理需求, 第一想到的还是 perl 。比如现在我在日常工作中就会用它来做如下的事情:

  • 代码生成
  • 配置格式转换
  • 日志分析

本文讲一下用 perl 进行简单日志分析的实战。

背景问题:大凡服务都会写日志,当我们发现在生产日志上发现某行错误日志频繁打印时, 就要引起警惕。最初的观察可能只要用 grep 类工具抽取相应日志行,有个直观的印象。 但如果要提取每行日志的关键信息,比如订单号、客户号或设备号之类,并根据该关键字 统计频度呢?那简单的 grep 工具可能就不好使了。

Read More

归类: 脚本运用

标签: perl

vim 笔记插件 vnote 设计反思

七阶子
13 min, 2457 words

几年前,刚转行为专职程序员不久时,出于对 vim 的喜爱与信仰,自己开发了一个 vim 插件,以支持在 vim 环境内记笔记及管理笔记。我知道市面上有不少笔记软件,但记笔 记这事是很个性化的东西,而且很多吹成云笔记的产品,把个人笔记上传到人家服务器上, 怎么都觉得有点敏感。所以我决定就用 vim 在本地写 markdown 文本笔记,要怎么上传 至 github 托管仓库,也是自己能完全控制的。基于这个出发点,我自行设计并开发 vnote 插件,虽然基本只是给自己用吧,当初也乐此不疲。

但是再过几年回头再看,这个插件软件可能设计的不尽如人意。

Read More

归类: 程序设计

标签: C++ vim

couttast: 轻量级单元测试框架介绍

七阶子
35 min, 6967 words

笔者在之前一家公司的项目中曾经规范使用过 google test 作为单元测试。只是在实践 使用过程中也偶有不便,于是开始着手再造个轮子,从自己的习惯用法写个轻量级单 元测试框架(库)。

项目地址 https://github.com/lymslive/couttast 。 初版是仅有 500 余行的头文件(head-only lib),无依赖,也不要求 C++11 ,自以为麻雀虽小, 五脏俱全。

取名源于两个单词拼接:cout 就是 C++ 众所周知的那个 std::couttaste 却不是 test 。在软件工程中,“测试”可能是个严肃的专业术语,但“尝试”不妨轻 松点,不必望而生畏。又为了与 test 这母长度相同,误写成了 tast

Read More