AskGolang: Testing related packages

agolangf · · 513 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>I have an app that has the following related packages: Preprocessor -&gt; Parser -&gt; Scanner -&gt; Lexer</p> <p>I&#39;d like to know for testing, if it&#39;s recommended to keep them separate, or combine them into a single package.</p> <p>The lexer is only used by the scanner, the scanner only by the parser and parser only by the preprocessor.</p> <p>I&#39;m currently using the philosophy that public functions should be tested directly, where private functions should not (instead they are tested indirectly as a result of testing the public functions).</p> <p>Separating the app into different packages, I can directly test their public functions. However, that leads to duplication as any test of the preprocessor also indirectly tests each package below it.</p> <p>But, combining those packages into 1, the parser, scanner and lexer functions would become private (as they are only used by the preprocessor), and therefore, a failed Preprocessor test could be the result of anything below it.</p> <p>Is there a best practice for testing / organizing code like this?</p> <hr/>**评论:**<br/><br/>jerf: <pre><p>First, when the dogma about not testing internal code becomes a problem, jettison it.</p> <p>It&#39;s possible that&#39;s enough to answer your question, in which case I&#39;d say that&#39;s a really powerful argument in favor of not worrying about testing internal functions.</p> <p>Second, there&#39;s still a case to be made that they should be separate, not because they &#34;need&#34; to be separate, but because it helps keep you disciplined. I&#39;d consider using an <code>internal</code> package they can all reach to hold the types they all need together (or make it public if that makes sense, depends on your use case), and then test the entire pipeline starting from the preprocessor. If you cover that one well, then you can move on to the next, and assume that bugs found in the next phase are the fault of that phase. If investigation turns up that a bug was actually in the previous layer, go add a test there. As you go along in this manner you minimize the risks of uncovering something in stage 4 that was actually a bug in stage 1. Not eliminate, of course, because you can&#39;t really do that with anything short of proofs, but minimize.</p> <p>On the topic of &#34;cover&#34;, this sort of code is a prime candidate for 100% coverage-based testing.</p></pre>everdev: <pre><p>Thanks, this is helpful.</p> <p>I built most of the features backwards, like the lexer first, then the scanner, etc. So I have tests for all of them already. I feel like they&#39;re more elegantly combined into a single package as unexported functions.</p> <p>But, I end up testing the lexer 4x, the scanner 3x, the parser 2x and the preprocessor 1x, since each level also tests all the way down the chain. But, when I add new features, they typically enter into the lexer and parser, so it could be hard to develop without trying to test them individually as well.</p> <p>Is this type of testing redundancy typical or is there a better way to test these items in isolation?</p></pre>jerf: <pre><p>I tend not to sweat this kind of problem. Rather than thinking about what code paths are being tested, I tend to think of it as &#34;if a test fails, what does it tell me?&#34; If a test fails at stage 3 but not stage 2, well... where to start looking is obvious.</p> <p>Also you&#39;ll naturally tend to focus on what really needs testing; it can easily be the case that while the stage 3 test is testing stages 2 and 1 that it is <em>very</em> incompletely testing stage 1 even so. This isn&#39;t necessarily the best case because in a compiler you&#39;ll probably end up with pretty complete tests, but in other cases where I&#39;m layering tests together, if the lower levels are well tested it lets me not try to puzzle out how to test layers 2 and 1 at the same time, from layer 2. I consider this a good thing overall.</p></pre>everdev: <pre><p>OK, sounds good. That&#39;s the track I&#39;m on then and the testing certainly feels comprehensive. Thanks.</p></pre>kl9va: <pre><p>there is no &#34;private&#34; in Go , it is either exported on unexported. Each package is exported , types or values inside a package might or might not be. If only one package is meant to be used by a client then your library should be only one package. </p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

513 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传