How to structure large libraries with regards to testing

xuanbao · · 552 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hello! Sorry if this is a bad question, I searched online and couldn&#39;t find people discussing this or any good best practices blog posts surrounding this question. My team is learning Go and starting to port some of our production libraries to it, and I&#39;m curious about testing.</p> <p>From what I&#39;ve seen online, it seems that you place x_test files next to the files they&#39;re testing, in the same package... and then go test does all the magic for you. That&#39;s all fine, but is this the best structure for large libraries? If I have, say, 20+ packages within a complex folder structure, it seems like the test files would be</p> <ol> <li><p>Hard to find at a glance, and yet</p></li> <li><p>Burdensome to look at all the time.</p></li> </ol> <p>In other languages, the norm seems to be a completely separate testing project that mimics the folder structure of the code you&#39;re testing, but this seems like a huge hassle in Go. </p> <p>I don&#39;t mind just having a _test file next to each code file, but I just want to make sure I&#39;m not going to bite myself later and there is a different industry standard way to do such a thing.</p> <hr/>**评论:**<br/><br/>jerf: <pre><blockquote> <p>the norm seems to be a completely separate testing project that mimics the folder structure of the code you&#39;re testing, but this seems like a huge hassle in Go. </p> </blockquote> <p>It&#39;s worse than a huge hassle, it means you can no longer test via the private interfaces of the library, and <code>go test</code> doesn&#39;t do what people expect anymore.</p> <p>You basically have no choice, you have to do it in the Go way.</p> <p>In practice, I don&#39;t find it a problem. Which is probably why you don&#39;t find any discussion about it... nobody is having trouble with it.</p> <p>By contrast, do not be surprised if you write some specific <em>code</em> that you realize you don&#39;t really know how to test. Be sure to ask <a href="/r/golang" rel="nofollow">/r/golang</a>. (Be as specific as you can be about the problem without violating corporate policy.) IMHO Go is one of the best conventional languages for writing solid test code in (the implicitly-satisfied interfaces are <em>awesome</em>), <em>but</em> there is a certain art to it, and I have some anecdotal evidence that without a few hints some people experience Go as being extra <em>hard</em> to test. (Since in fact I write very good tests with high coverage attained on heavily IO-driven code, I <em>know</em> it isn&#39;t impossible to test. But if you try to figure it all out from scratch it can be a challenge. The big hint is to remember that you can write an interface for <em>any</em> object or subset of an object that you like...)</p></pre>TheMerovius: <pre><blockquote> <p>It&#39;s worse than a huge hassle, it means you can no longer test via the private interfaces of the library</p> </blockquote> <p>You can always do</p> <pre><code>// +build test package foobar var ExportedFunc = unexportedFunc </code></pre></pre>TheMerovius: <pre><p>Or, of course, just name the file foobar_test.go and export your private interfaces there.</p></pre>jerf: <pre><p>While you can export functions that way, you can&#39;t export structs:</p> <pre><code>type private struct { ... } type Public struct { private } </code></pre> <p>isn&#39;t even remotely the same as having private in your scope. You also can&#39;t implement private members of interfaces from a remote module. You also may be able to export local private functions but if it takes a private type you may still not be able to use it.</p> <p>Basically, this only covers 20% of the use cases, and the strong module boundaries in Go mean that there&#39;s not much you can do about the other 80%. (In particular, Go&#39;s module boundaries are unusually strong because you can not import a module and re-export its types, and while you can sort of re-export Interfaces, it&#39;s not quite the same thing as a true reexport as there are visible differences.)</p> <p>In general, I&#39;m not a fan of using variables to hold functions like that... I&#39;m yet to see a situation when it&#39;s the best choice. Usually you&#39;re better off with a mix of structs, interfaces, and values passed around rather than globals.</p></pre>peterhellberg: <pre><p>Havind a complex folder structure might be an indicator that the library is doing too much to begin with.</p> <p>But having the tests in *_test.go is the expected way to do it.</p></pre>

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

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