IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发测试 -> 圈复杂度及降低示例 -> 正文阅读

[开发测试]圈复杂度及降低示例

圈复杂度

定义

圈复杂度 (Cyclomatic complexity) 是一种代码复杂度的衡量标准,也称为条件复杂度或循环复杂度,它可以用来衡量一个模块判定结构的复杂程度,数量上表现为独立现行路径条数,也可理解为覆盖所有的可能情况最少使用的测试用例数。简称 CC 。其符号为 VG 或是 M 。

计算规则

for +1; if +1; else +1; switch has n cases +n; || +1; && +1

降低圈复杂度手段

1、类型判断、转换

if (visibleFlag) {
    visible = 1;
} else {
    visible = 0;
}
改为(如:在数据库保存时无法自动转换数据类型):
visible = visibleFlag + 0

2、独立函数调用

postTitle = postTitle ? postTitle.trim() : '';
改为:
postTitle = util.trim(xss.sanitize(postTitle))

3、多条件合并为一个:转为数组的include等操作

if (action === 'create' || action === 'edit') {...}
改为:
if (['create', 'edit'].includes(action)) {...}

4、空值判断简化

if (page !== undefined && page !== ''){...}
改为
if (!page) {...}

5、嵌套if简化

if (x) {
    if (y) {...} else {...}
} else {
    ...
}
改为:
if (x && y) {...} else {...}

6、复杂if改为使用正则(通配符)

if (/^1[34578]\d{9}$/i.test(phone)) {...}

7、重复判断剥离并复用:赋值给变量、常量,减少二次判断

if (postStatus === 'draft' || postStatus === 'auto-draft') {...}
...
if (postStatus === 'draft' || postStatus === 'auto-draft') {...} else {...}
改为:
const postDraft = postStatus === 'draft' || postStatus === 'auto-draft';
if (postDraft) {...}

降低圈复杂度示例

阈值5。下面这种if判空后赋值有九处(4+5),加上两个err判断,使得原代码圈复杂度为12

func (p *Pipe) getVersionDetails(ctx *context.Context, app *asc.App, version *asc.AppStoreVersion) error {
  // *asc.AppInfoLocalizationResponse error  类型
	appLocalizationResp, err := p.Client.GetAppLocalizations(ctx, app.ID)
	if err != nil {
		return err
	}
  // Name Subtitle ... 是*string类型
	if appLocalizationResp.Data.Attributes.Name != nil {
    // AppStoreVersionDetail是model.MarketReleaseIosReq类型
		ctx.AppStoreVersionDetail.App = *appLocalizationResp.Data.Attributes.Name
		log.Info("ctx.AppStoreVersionDetail.App:", ctx.AppStoreVersionDetail.App)
	}
	if appLocalizationResp.Data.Attributes.Subtitle != nil {
		ctx.AppStoreVersionDetail.SubTitle = *appLocalizationResp.Data.Attributes.Subtitle
		log.Info("ctx.AppStoreVersionDetail.Subtitle:", ctx.AppStoreVersionDetail.SubTitle)
	}
  ...
  ...

	return nil
}

修改

func (p *Pipe) getVersionDetails(ctx *context.Context, app *asc.App, version *asc.AppStoreVersion) error {

	log.Infof("getting app localizations")
	appLocalizationResp, err := p.Client.GetAppLocalizations(ctx, app.ID)
	if err != nil {
		return err
	}
	InitAppVersionDetailAppInfo(ctx, appLocalizationResp)

	...

	return nil
}

// InitAppVersionDetailAppInfo 初始化ctx.AppStoreVersionDetail
func InitAppVersionDetailAppInfo(ctx *context.Context,
	appLocalizationResp *asc.AppInfoLocalizationResponse) {
	InitProp(ctx.AppStoreVersionDetail, "App", appLocalizationResp.Data.Attributes.Name)
	InitProp(ctx.AppStoreVersionDetail, "PrivacyPolicyURL", appLocalizationResp.Data.Attributes.PrivacyPolicyURL)
	InitProp(ctx.AppStoreVersionDetail, "Subtitle", appLocalizationResp.Data.Attributes.Subtitle)
	InitProp(ctx.AppStoreVersionDetail, "PrivacyPolicyText", appLocalizationResp.Data.Attributes.PrivacyPolicyText)
}
// 赋值功能核心
// 结构体是值类型,用指针类型才会改变值。不用指针是传对象的副本,在函数外访问是没变化的。
func InitProp(appStoreVersionDetail *model.MarketReleaseIosReq,
	ctxPropertyName string, respAttribute *string) {
	if respAttribute == nil {
		return
	}
	detail := reflect.Indirect(reflect.ValueOf(&appStoreVersionDetail)).Elem()
	typeOfT := detail.Type()
	for i := 0; i < detail.NumField(); i++ {
		if typeOfT.Field(i).Name == ctxPropertyName {
			detail.FieldByName(ctxPropertyName).Set(reflect.ValueOf(respAttribute).Elem())
			break
		}
	}
	log.Infof("ctx.AppStoreVersionDetail.%+v:%+v", ctxPropertyName, reflect.ValueOf(respAttribute).Elem())
}
  开发测试 最新文章
pytest系列——allure之生成测试报告(Wind
某大厂软件测试岗一面笔试题+二面问答题面试
iperf 学习笔记
关于Python中使用selenium八大定位方法
【软件测试】为什么提升不了?8年测试总结再
软件测试复习
PHP笔记-Smarty模板引擎的使用
C++Test使用入门
【Java】单元测试
Net core 3.x 获取客户端地址
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 12:23:20  更:2021-08-07 12:24:04 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 6:50:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码