当前位置:网站首页>Talk about go code coverage technology and best practices

Talk about go code coverage technology and best practices

2020-11-08 16:10:00 InfoQ

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"\" Talk about dry goods \""}]}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Coverage technology basis "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" By the end of Go1.15.2 before , About the underlying implementation of coverage technology , You should know the following :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"go The language is in the form of plug-in source code , Instead of waiting for the binary to execute breakpoints. This leads to the current go Test coverage collection technology , It must be intrusive , Will modify the source code of the target program . Once upon a time, some students would ask , Can the binary with the stake be put on the line , So it's better not to ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" What exactly is \" Pile insertion \"? This question is very important . You can find any one go file , Try to order "},{"type":"codeinline","content":[{"type":"text","text":"go tool cover -mode=count -var=CoverageVariableName xxxx.go"}]},{"type":"text","text":", See what the output file is ?"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The author takes this document as an example "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"https://github.com/qiniu/goc/blob/master/goc.go"}]},{"type":"text","text":", The following results are obtained :"}]},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e9/e9db85d547914df99c6d84bcac7bbf29.png","alt":null,"title":"","style":[{"key":"width","value":"100%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" You can see , After execution , There's more in the source code "},{"type":"codeinline","content":[{"type":"text","text":"CoverageVariableName"}]},{"type":"text","text":" Variable , It has three key attributes :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Count"}]},{"type":"text","text":" uint32 Array , Each element in the array represents the corresponding basic block (basic block) The number of times it was executed "},{"type":"codeinline","content":[{"type":"text","text":"CoverageVariableName"}]},{"type":"text","text":" The variable sets counters in each execution logical unit , such as "},{"type":"codeinline","content":[{"type":"text","text":"CoverageVariableName.Count[0]++"}]},{"type":"text","text":", And this is the so-called pile insertion . Through this counter, it is easy to calculate whether the code has been executed to , And how many times it has been implemented . I believe you have seen it before go Coverage results in coverprofile data , It's like this : "},{"type":"codeinline","content":[{"type":"text","text":"github.com/qiniu/goc/goc.go:21.13,23.2 1 1"}]}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" The content here is through variables like the above "},{"type":"codeinline","content":[{"type":"text","text":"CoverageVariableName"}]},{"type":"text","text":" obtain . Its basic meaning is \""},{"type":"text","marks":[{"type":"strong"}],"text":" file : Start line . Start column , End line . End column The number of statements in the basic block The number of times the basic block has been executed "},{"type":"text","text":"\""}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"Pos"}]},{"type":"text","text":"  Represents the location of the basic blocks in the source file , Three in a group . Like here "},{"type":"codeinline","content":[{"type":"text","text":"21"}]},{"type":"text","text":" Represents the starting line number of the basic block ,"},{"type":"codeinline","content":[{"type":"text","text":"23"}]},{"type":"text","text":" Represents the number of end lines ,"},{"type":"codeinline","content":[{"type":"text","text":"0x2000d"}]},{"type":"text","text":" More interesting , Before that 16 Bits represent the number of ending columns , after 16 Bits represent the number of starting columns . A point can be uniquely identified by rows and columns , And through the starting and ending points , Can accurately express the physical scope of a basic block in the source file "}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"codeinline","content":[{"type":"text","text":"NumStmt"}]},{"type":"text","text":"  Represents how many statements are in the scope of the corresponding basic block (statement)"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Depending on go Language official powerful tool chain , We can do single test coverage collection and statistics very conveniently . But collective testing /E2E It's not so convenient . But the good thing is that we have https://github.com/qiniu/goc."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" Collection coverage rate collection tool - Goc principle "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" About the single measurement , thorough go Source code , We will find that "},{"type":"codeinline","content":[{"type":"text","text":"go test -cover"}]},{"type":"text","text":" The command will automatically generate a "},{"type":"codeinline","content":[{"type":"text","text":"_testmain.go"}]},{"type":"text","text":"  file . This document will Import The bags that have been pegged , So you can read the instrumentation variables directly , To calculate the test coverage . actually "},{"type":"codeinline","content":[{"type":"text","text":"goc"}]},{"type":"text","text":" It's a similar principle (PS: About why not use "},{"type":"codeinline","content":[{"type":"text","text":"go test -c -cover"}]},{"type":"text","text":"  programme , You can refer to here : "},{"type":"link","attrs":{"href":"http://mp.weixin.qq.com/s?__biz=Mzg5NDEzNzk3OQ==&mid=2247483688&idx=1&sn=ddb905febdd9adfe5769b5b82d70a2e0&chksm=c025623cf752eb2abf7d2378ccd0054758c505cae7799bcd518dd149888ccec0479b34d1e784&scene=21#wechat_redirect","title":null},"content":[{"type":"text","text":" Open source | go Language system test coverage collection tool goc"}]},{"type":"text","text":"."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" But when it comes to collective testing , The object under test is usually a complete product , Involving multiple long running Back end services . therefore goc It's designed to be automated, and it injects HTTP API, And through the service registry "},{"type":"codeinline","content":[{"type":"text","text":"goc server"}]},{"type":"text","text":" To manage all the services under test . Such words , You can do this at run time , Through the command "},{"type":"codeinline","content":[{"type":"text","text":"goc profile"}]},{"type":"text","text":" Get the coverage results of the whole cluster in real time , It's really convenient ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" For the overall structure, see :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/7a/7ac8b0998f6e9f35ea7c28a923472014.png","alt":null,"title":null,"style":null,"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":" Best practices for code coverage "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Technology needs to serve enterprise value , Or you're playing rogue . You can see , Currently playing coverage , There are mainly the following directions :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Measure - Depth measurement , All kinds of bags , file , Methods measure , All belong to the system . The value behind it lies in feedback and discovery . What is the level of feedback testing , Identify deficiencies or risks and improve them . For example, it is commonly used as an assembly line access standard , Release access control and so on . Measurement is the foundation , But it can't stop at data . The ultimate goal of coverage , It's about increasing test coverage , Especially the coverage of automation scenarios , And stick to it . So based on this , In the industry, we see , A valuable landing pattern is a measure of incremental coverage .goc diff  combination Prow The platform has a similar capability , If you also use Kubernetes, Try it . Of course, the same type of well-known commercial services , Also have CodeCov/Coveralls etc. , However, most of them are limited in the field of single test ."}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Accurate test direction - It's a big direction , The value logic behind it is clear , It's about building two-way feedback from business to code , It is used to improve the accuracy and efficiency of test behavior . But there's a paradox here , Students who understand the code , Probably not without brain feedback ; Students who can't go deep into the code , You give code level feedback , It doesn't work well . So the landing position is very important here . At present, the industry has not seen a good example of practice , Most of them solve problems in specific situations , There are certain limitations ."}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Compared to the landing direction , As the majority of R & D students , The following best practices may be more valuable to you :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" High code coverage does not guarantee high product quality , But the low code coverage must indicate that most of the logic is not automatically measured . The latter usually increases the risk of problems left online , When it comes to attention ."}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" There is no universal strict coverage standard for all products . In fact, it should be the business or technical leaders based on their own domain knowledge , The importance of code modules , Modification frequency and other factors , Set your own standards in the team , And promote the team consensus ."}]}]},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Low code coverage is not terrible , Be able to take the initiative to analyze the parts that are not covered , And assess whether the risk is acceptable , It will make more sense . In fact, I think , As long as this submission is better than the last one , It's all worth encouraging ."}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Google has a blog ( See references ) mention , Its experience shows that , Teams that value code coverage are often more likely to foster a culture of excellence in Engineers , Because these teams think about testability at the beginning of the product design , In order to achieve the test goal more easily . And these measures, in turn, encourage engineers to write higher quality code , More emphasis on modularity ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Last , Welcome to join qiniuyun Goc Communication group , Let's talk about goc, Talk about R & D efficiency ."}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" Reference material :"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"https://testing.googleblog.com/2020/08/code-coverage-best-practices.html"}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":" Series articles "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https://xie.infoq.cn/article/0d1b06597b8345708606fc073","title":""},"content":[{"type":"text","text":"https://xie.infoq.cn/article/0d1b06597b8345708606fc073"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" I think it's good , Welcome to the official account : Great Carr "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic"}],"text":"                                      Point a praise 、 Watching and forwarding is the biggest support "}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢