<p>Do you guys test for coverage when you pass an error along?</p>
<p>For a specific example say I'm using database/sql with a driver and I know the driver returns errors. I want to pass those errors along to the caller but I feel that testing these is really testing the driver implementation. </p>
<p>Am I wrong in that? Should I test the errors and improve my coverage? </p>
<p>See: <a href="http://imgur.com/9Rn9Yu9" rel="nofollow">coverage.</a></p>
<hr/>**评论:**<br/><br/>cameronjerrellnewton: <pre><p>The go view point is to treat errors as part of your code and program around and with them, so yes you should treat and test it just like you would any other code.</p></pre>droneprime: <pre><p>Yeah I guess I just wanted to hear that from someone else. This means that I will have to setup and teardown a database within my local mysql installation then delete and create a table to test these two little error handlers. </p>
<p>As this is a personal project, I find this exercise valuable. Thanks for the response. </p></pre>MonkeeSage: <pre><p>I'm not a professional go programmer but in other languages the general idea would be to use a mock object for anything where you want to test the edges of your program that need to interact, without testing the underlying implementation.</p>
<p>A quick google turned up this library: <a href="https://github.com/DATA-DOG/go-sqlmock" rel="nofollow">https://github.com/DATA-DOG/go-sqlmock</a></p></pre>droneprime: <pre><p>HA! Brilliant. I'm using <a href="https://github.com/jarcoal/httpmock" rel="nofollow">httpmock</a> for some request tests, but it didn't occur to me to look for a sql mock. Thank you very much. </p></pre>Growlizing: <pre><p>If it is an api, I generally find it more valuable to spend your time testing the api surface, whether it be a package API or a web API.</p>
<p>These fine grained tests are very brittle, and comes at increased cost when refactoring (ie. is costly to maintain), so I would think twice on being too hard on test coverage when testing such code.</p>
<p>Likewise, all code is not created equal, and some parts deserve better coverage than others.</p></pre>dchapes: <pre><p>Do you care how your program behaves when there is a fault somewhere else in the system? E.g. Do you care about what the program does if the database exists but doesn't have the correct/any schema; if the network connect to the database server suddenly goes away while the program is doing something; etc.</p>
<p>The answer is probably yes since you are checking for and returning errors. That is the behaviour your linked <code>Store</code> function appears to claim to have. Therefore you should test that the <code>Store</code> function does what you think it does in such situations. E.g. by using a stub test database that returns errors at various points of interest.</p>
<p>Is this the most important and first part of your program you should make sure you test first? Probably not.</p>
<p> </p>
<p>P.S.: Don't call <code>sql.Open</code> inside functions like <code>Store</code>. Database connections are meant to be long lived and opened once, not opened per-fuction call. From <a href="https://golang.org/pkg/database/sql/#Open" rel="nofollow"><code>sql.Open</code></a>:</p>
<blockquote>
<p>The returned DB is safe for concurrent use by multiple goroutines and maintains its own pool of idle connections. Thus, the Open function should be called just once. It is rarely necessary to close a DB.</p>
</blockquote></pre>droneprime: <pre><p>Hey thanks for the reply. Would an init for the package be a better place to sql.Open()?</p></pre>davebrophy: <pre><p>I answered a similar question just 10 minutes ago, so I'll copy+paste:</p>
<p>My theory goes that you should only enforce test coverage where the error actually originates from. When you're just returning an error from another function, you should assume that function is properly tested. That's why I created courtney, which:</p>
<ul>
<li>Runs tests in multiple packages with coverage</li>
<li>Merges the coverage files</li>
<li>Excludes blocks with panics</li>
<li>Excludes blocks that return an error that has been tested to be non-nil (see the readme for more details about how this works)</li>
<li>Excludes blocks annotated with a "notest" comment</li>
</ul>
<p>What you're left with is the really critical code-paths, and once you reach 100% code coverage you can add the -e (enforce) flag to the courtney command - this will throw an error if there's any code without coverage.</p>
<p>Let me know what you think: <a href="https://github.com/dave/courtney" rel="nofollow">https://github.com/dave/courtney</a></p></pre>davebrophy: <pre><p>Here's an example of a bunch of error returns being excluded by courtney: <a href="https://codecov.io/gh/dave/jennifer/src/master/jen/comments.go#L77" rel="nofollow">https://codecov.io/gh/dave/jennifer/src/master/jen/comments.go#L77</a></p></pre>droneprime: <pre><p>That is excellent. Thank you for the effort. What tool are you using to visualize coverage? When you say 'merge coverage files' I wrote a script that does that for all my tests and passes it along to the golang HTML coverage viewer. Your tool looks a bit different. </p>
<p>Courtney seems to address my exact concern. </p></pre>SeerUD: <pre><p>The similar question that <a href="/u/davebrophy" rel="nofollow">/u/davebrophy</a> is referring to is this one of mine, you might find some other insights in there: <a href="https://www.reddit.com/r/golang/comments/6972sy/testing_expected_unreachable_errors/?utm_content=title&utm_medium=user&utm_source=reddit" rel="nofollow">https://www.reddit.com/r/golang/comments/6972sy/testing_expected_unreachable_errors/?utm_content=title&utm_medium=user&utm_source=reddit</a></p></pre>jimijiim: <pre><p>IF you are writing unit tests and you seek better test coverage the answer is yes, you should test error code paths. </p>
<p>If you are testing something tied to a DB driver you are not unit testing at first place. You should mock dependencies. </p>
<p>Somehow this specific sub thinks that good practices don't apply to go because "simplicity". Go is object oriented BECAUSE it support message passing through struct methods and polymorphism through interfaces. The only way to unit test objects is to mock its collaborators. </p></pre>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传