- 最好用的C++圈复杂度分析工具:pip install lizard,没想到它解析C++的函数块超级快,可以用来作为建立进一步的代码片分析的基础,完胜其他所有工具。
- 我花了1天多将一个C++模块测试覆盖率做到100%,对于代码如何才具有良好可测试性有了直观的经验,从测试的角度看代码的设计是否简洁是一个非常合理的角度。
- 如果代码的可测试性很好,那么AI也能非常容易的处理它,可见未来的代码,不是要写的复杂,就是写的直接简洁,实际上就是要保持线性。
如何将一个难以测试的类改进为易于测试的类?
例子1,切分辅助的纯函数
让这个类的构造依赖的参数简单,简单不一定是参数个数少,而是这些参数的构造本身的依赖不要有太多深度。
以前有一个痛点问题是,一个类的内部有一些成员变量不好修改,于是不好再测试的时候控制函数内部的分支行为。解决方式是:将控制复杂行为的函数实现拆分,拆分为调用几个辅助函数,这几个辅助函数是纯函数,依赖的参数都通过函数参数传递(即使这个参数是类成员变量就有的),这样这个辅助函数就容易被测试,因为是一个纯函数,因为都通过函数参数传递状态。
例子:
class A{
public:
void run(){
if(config.enable_xxx){
do_something();
}
}
void dosomthing(){
status.value = ...
}
private:
Config config;
Status status;
}
这个run就不好测试,因为测试方不好控制Config的状态。修改如下:
class A{
public:
void run(){
do_something(config, status);
}
bool do_somthting(const Config& config, const Status& status){
if(!config.enable_xxx){
return false;
}
status.value = ...
}
private:
Config config;
Status status;
}
这个时候就可以对 do_something 做测试了,因为do_somthting依赖的对象,和修改的对象,都是通过函数参数传递的,是一个纯函数。那么测试函数和A::run 对于do_somthting来说都是同等的访问能力。
例子2: 处理内部的返回值问题
下面的类,内部对于某个API请求对结果做处理,但是测试方不易于控制API请求的结果,不好测试到对应分支。
class A{
public:
void run(){
xxx v;
bool ret = receiver.pop(v);
if(ret){
....
}
}
}
解决方式是把获取数据和处理数据完全的分开成两个部分:
class A{
public:
void run(){
xxx v;
bool ret = receiver.pop(v);
on_receive_v(ret, v);
}
bool on_receive_v(bool ret, const xxx& v){
if(!ret){
return false;
}
...
}
}
这样分支跑到 on_receive_v 里面去,而 on_receive_v 是一个易于通过参数控制分支测试的函数。
标签:do,run,函数,复杂度,ret,测试,config From: https://www.cnblogs.com/math/p/18105611/testable-code