当前位置: 首页 > news >正文

中国网站名建设部监理工程师网站

中国网站名,建设部监理工程师网站,模板设计图,河南有名的做网站公司有哪些Go 语言并发编程 及 进阶与依赖管理_软工菜鸡的博客-CSDN博客 03 测试 回归测试一般是QA(质量保证)同学手动通过终端回归一些固定的主流程场景 集成测试是对系统功能维度做测试验证,通过服务暴露的某个接口,进行自动化测试 而单元测试开发阶段#xff0c;开发者对单独的函数… Go 语言并发编程 及 进阶与依赖管理_软工菜鸡的博客-CSDN博客 03 测试 回归测试一般是QA(质量保证)同学手动通过终端回归一些固定的主流程场景 集成测试是对系统功能维度做测试验证,通过服务暴露的某个接口,进行自动化测试 而单元测试开发阶段开发者对单独的函数、模块做功能验证 层级从上至下测试成本逐渐减低而测试覆盖率确逐步上升所以单元测试的覆盖率一定程度上决定着代码的质量。 3.1.0 单元测试 单元测试主要包括输入测试单元输出以及校对 单元的概念比较广包括接口函数模块等用最后的校对来保证代码的功能与我们的预期相符 单侧一方面可以保证质量在整体覆盖率足够的情况下一定程度上既保证了新功能本身的正确性又未破坏原有代码的正确性。 另一方面可以提升效率在代码有bug的情况下通过编写单测可以在一个较短周期内定位和修复问题。 3.1.1 单元测试-规则 基本规范以 _test.go结尾这样从文件上就很好了区分源码和测试代码 以Test开头且连接的第一个字母大写 TestMain的m.run()会跑这个package下的所有单测 3.1.2 单元测试-例子 HelloTom() 由于代码逻辑的错误没有输出Tom 接下来进行测试TestHelloTom() 3.1.3 单元测试-运行 输出结果错误 3.1.4 单元测试-assert import 了testify/assert 的Equal函数 3.1.5 单元测试-覆盖率 这是一个判断是否及格的函数超过60分返回true否则返回false 右边是对输入为70 的单元测试我们执行右边的单侧 通过指定go test [] --cover参数我们看输出了 覆盖率为66.7。 一共三行我们的单测试执行了2行所以为66.7 下一步就是提升覆盖率我们可以增加一个不及格的测试case重新执行所有单侧最终覆盖率为100%。 也就是说我们通过不断对各个分支的测试保证了覆盖率和完备性。 3.1.6 单元测试-Tips 在实际项目中一般的要求是50%~60% 覆盖率而对于资金型服务覆盖率可能要求达到80% 我们做单元测试测试分支相互独立全面覆盖则要求函数体足够小这样就比较简单的提升覆盖率也符合函数设计的单一职责。 3.2 单元测试-依赖 工程中复杂的项目一般会依赖数据库、缓存等而我们的单测需要保证稳定性和幂等性 稳定是指相互隔离能在任何时间任何环境运行测试。 幂等是指每一次测试运行都应该产生与之前一样的结果。而要实现这一目的就要用到mock机制。 3.3 单元测试-文件处理 下面举个例子打开文件读入 将文件中的第一行字符串中的11替换成00执行单测测试通过而我们的单测需要依赖本地的文件如果文件被修改或者删除测试就会fail。 为了保证测试case的稳定性我们对读取文件函数进行mock屏蔽对于文件的依赖。 3.4 单元测试-Mock monkey是一个开源的mock测试库可以对method或者实例方法的方法进行mock(打桩) 打桩指的是用一个函数A 替换函数BB作为原函数A作为打桩函数 Mock Patch(原函数需要打桩的函数) 的作用域在 Runtime Unpatch(打桩函数)打桩结束后把原函数卸载掉 monkey主要是在运行时通过 Go 的 unsafe 包能够将内存中函数的地址替换为运行时函数的地址在测试中调用的就是运行时的打桩函数B地址。 下面是一个mock的使用样例通过patch对Readfineline进行打桩mock默认返回line110这里通过defer卸载mock这样整个测试函数就摆脱了本地文件的束缚和依赖。 3.5 基准测试 Go 语言还提供了基准测试框架基准测试是指测试一段程序的运行性能及耗费 CPU 的程度。 而我们在实际项目开发中经常会遇到代码性能瓶颈为了定位问题经常要对代码做性能分析这就用到了基准测试。使用方法类似于单元测试 3.5.1 基准测试-例子 这里举一个服务器负载均衡的例子首先我们有10个服务器列表每次随机(rand包)执行select函数随机选择一个执行。 3.5.2 基准测试-运行 基准测试以Benchmark开头,入参是testing.B, 用b中的N值反复递增循环测试对一个测试用例的默认测试时间是 1 秒当测试用例函数返回时还不到 1 秒那么 testing.B 中的 N 值将按 1、2、5、10、20、50……递增并以递增后的值重新进行用例函数测试 Resttimer重置计时器我们在reset之前做了init或其他的准备操作这些操作不应该作为基准测试的范围 runparallel()函数是多协程并发测试执行 2个基准测试发现代码在并发情况下存在劣化主要原因是rand为了保证全局的随机性和并发安全持有了一把全局锁。 3.5.3 基准测试-优化 GitHub - bytedance/gopkg: Universal Utilities for Go 而为了解决这一随机函数性能问题开源了一个高性能随机数方法fastrand上面有开源地址我们这边再做一下基准测试性能提升百倍。主要的思路是牺牲了一定的数列的一致性在大多数场景是适用的同学在后面遇到随机的场景可以尝试用一下。 4 项目实践 4.0需求背景 大家应该都是从掘金的 社区话题入口报名的都看到过这个页面页面的功能包括话题详情回帖列表支持回帖点赞和回帖回复 我们今天就以此为需求模型开发一个该页面交涉及的服务端小功能。 4.1 需求描述 下面是需求的详细描述Ok如果该功能由同学自己实现如何去做模型设计可以拿笔和纸简单画一下然后打开ide争取我们一起完成这个实现后面跟不上也不要着急代码已经托管到github大家可以自行下载查看GitHub - Moonlight-Zhao/go-project-example 4.2 需求用例 我们从用例分析一步步拆解实现主要涉及的功能点用户浏览消费涉及页面的展示包括话题内容和回帖的列表其实从图中我们应该会抽出2个实体的而实体的属性有哪些他们之间的联系又如何 大家想一下可以先定义一下结构体 4.3 ER 图 4.4 分层结构 整体分为三层 repository数据层service逻辑层controoler视图层 数据层关联底层数据模型也就是这里的model封装外部数据的增删改查我们的数据存储在本地文件通过文件操作拉取话题帖子数据 数据层面向逻辑层对service层透明数据层屏蔽下游数据差异也就是不管下游是文件还是数据库还是微服务等对service层的接口模型是不变的。 Servcie逻辑层处理核心业务逻辑接收数据层数据 计算打包业务实体entiy对应我们的需求就是话题页面包括话题和回帖列表并上送给视图层 Controller视图层负责处理和外部的交互逻辑以view视图的形式返回给客户端对于我们需求封装json格式化的请求结果api形式访问就好 4.5 组件工具 下面介绍下开发涉及的基础组件和工具 首先是gin高性能开源的go web框架我们基于gin 搭建web服务器在课程手册应该提到了这里我们只是简单的使用主要涉及路由分发不会涉及其他复杂的概念。 因为我们引入了web框架所以就涉及go module依赖管理如前面依赖管理课程内容讲解我们首先通过go mod是初始化go mod管理配置文件然后go get下载gin依赖这里显示用了V1.3.0版本。 有了框架依赖我们只需要关注业务本身的实现 从下至上reposity--service--controller,我们一步步实现。希望大家能跟上我的节奏从0~1 实现这个项目如果时间问题大家可以一步步copy一下主要是走一下开发思路。 4.6 Repository数据层 首先是reposity我们可以根据之前的er图先定义struct文件中每行的格式如图所示 那如何实现QueryTopicById(话题)QueryPostsByParentId(帖子) 4.6 Repository-index 一方面查询我们可以用全扫描遍历的方式但是这虽然能达到我们的目的但是并非高效的方式 所以这里引出索引的概念索引就像书的目录可以引导我们快速查找定位我们需要的结果 这里我们用map实现内存索引在服务对外暴露前利用文件元数据初始化全局内存索引这样就可以实现01的时间复杂度查找操作。 下面是具体的实现首先是os.Open打开文件基于file 初始化scanner通过迭代器方式遍历scanner数据行转化为结构体Topic存储至内存map这就是初始化话题内存索引。 4.6 Repository-查询 有了内存索引下一步就是实现查询操作就比较简单了 直接根据查询key获得map中的value就好了这里用到了sync.once,主要适用高并发的场景下只执行一次的场景这里的基于once的实现模式就是我们平常说的单例模式减少存储的浪费。 有了topic的查询代码大家可以照猫画虎 自行实现一下根据话题id查询回帖列表的查询方法 func (*PostDao) QueryPostByParentId(parentId int64) ([]*Post, error) {var posts []*Posterr : db.Where(parent_id ?, parentId).Find(posts).Errorif err ! nil {util.Logger.Error(find posts by parent_id err: err.Error())return nil, err}return posts, nil } 4.7 Service逻辑层 有了reposity层以后下面我们开始实现service层首先我们定义servcie层实体PageInfo包括Topic和PostList 下面是具体的servcie流程编排 通过err控制流程退出正常会返回页面信息err为nil func (f *QueryPageInfoFlow) Do() (*PageInfo, error) {if err : f.checkParam(); err ! nil {//简单的id校验return nil, err}if err : f.prepareInfo(); err ! nil {return nil, err}if err : f.packPageInfo(); err ! nil {return nil, err}return f.pageInfo, nil } 关于prepareInfo方法话题和回帖信息的获取都依赖topicid这样2个流程没有相互依赖 这就可以并行执行提高执行效率。 WaitGroup Add(2);(2个并行的协程)wait等待两个协程的信息从数据层返回 大家在后期做项目开发中一定要思考流程是否可以并行通过压榨CPU降低接口耗时不要一味的串行实现浪费多核cpu的资源 Paramcheck 和pack这里就不讲了给大家一点时间 编码 copy代码 4.8 Controller视图层 这里我们定义一个view对象通过code msg打包业务状态信息用data承载业务实体信息输入 4.9 Router 最后是web服务的引擎配置path映射到具体的controller。通过path变量传递话题id 4.10 运行 最后执行go run 本地启动web服务通过curl命令请求服务暴露的接口当然平时写代码不可能像我讲的这么顺畅难免有bug大家要做好完备的单元测试快速定位问题解决问题。 鼠鼠出bug了捏 好的以上就是对社区话题页面需求的整个实现流程这样我们从项目拆解代码设计落地最后测试运行就跑通了整个的项目流程为大家后期实现项目提供了一定的开发思路。当然实际项目较我们实现的需求会复杂很多不过大家也不必担心可以通过大拆小的思路将大需求拆解为小需求的思路来分析解决遇到问题各个击破同时做好充分的测试。 课后作业 非常感谢您阅读到这里如果这篇文章对您有帮助希望能留下您的点赞 关注 收藏 评论感谢支持
http://www.sadfv.cn/news/417580/

相关文章:

  • 工商银行与建设银行网站对比手机网站开发需要哪些人才
  • dz论坛做分类网站厦门外贸网页设计服务
  • 响应式英文网站建设wordpress登陆页面logo
  • 哪个网站可以做围棋作业网站建设与营销
  • 西安市住房和城乡建设局门户网站网络销售是什么
  • 晋城做网站企业网站维护工作计划
  • 网站建设用户登录小城天长网站建设
  • 哈尔滨市建设安全网站无锡建设企业网站
  • wordpress公众号导航主题关键词seo是什么意思
  • 常德地区网站建设山东网站建设电话
  • 怎么黑入网站便捷网站建设公司
  • 个人网站名称大全有一个做搞笑英语视频网站
  • 公司网站做么做百度排名高端网站建设专业
  • 做网站诱导网站开发大型网站
  • 做调查赚钱的网站又哪些设计之家logo设计
  • 美容行业网站建设多少价格网站后台基本功能
  • 德州鲁企动力网站优化中心wordpress主题 dux主题5.3
  • 建网站专用网站购物网站设计理念
  • python网站开发入门网站体验调查问卷怎么做
  • 域名买卖违法吗沈阳seo按天计费
  • 超市网站建设策划书网络系统管理大赛样题
  • 免费建立自己的网站代码网站如何提高流量
  • 珠海网站建设培训学校冒用公司名做网站
  • 网站建设和运营装修采购网
  • 网站建设3a模型是什么前端ui设计图
  • 网站空间服务站电话网站制作公司制作网站的流程是怎样的呢
  • 门户网站的流程长链接转短链接
  • 北方明珠网站建设企业计划书
  • 连锁公司网站源码下载安装
  • 网站制作和推广lv官网世界工厂网官网下载