Sharing tests between packages while retaining test context?

xuanbao · · 406 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>So a common issue i run into is that i want to configure tests very differently and reuse them between packages. Example being, maybe for unit tests i just use mock DBs, but for integration tests there&#39;s an already running real DB and Real API that i want to test against. Same test, different endpoints and setup/teardown.</p> <p>The problem is that by default with <code>go test</code>, the tests lose context and anything out of the package ends up with no line numbers and no filenames. Eg:</p> <pre><code> --- FAIL: TestExampleFixture/TestFail (0.00s) fixture.go:121: Test: (*ExampleFixture).TestFail() (0): /foo.../go/src/bar.../api/api_test.go:39 Expected &#39;this&#39;ll fail&#39; to contain substring &#39;yup&#39; (but it didn&#39;t)! FAIL </code></pre> <p>vs</p> <pre><code> --- FAIL: TestExampleFixture/TestFail (0.00s) fixture.go:121: Test: .() Expected &#39;this&#39;ll fail&#39; to contain substring &#39;yup&#39; (but it didn&#39;t)! FAIL </code></pre> <p>Has anyone seen a solution to this &#34;problem&#34;? I&#39;d love to be able to reuse my tests across packages, but it seems impossible currently.</p> <hr/>**评论:**<br/><br/>0xjnml: <pre><p>Do not pass <code>testing.T</code> to code outside of the package. Instead let it return <code>err</code> and then do <code>t.Fail(err)</code> locally.</p></pre>throwlikepollock: <pre><p>If that&#39;s the method used, then you have no idea what line/etc the imported tests failed on.</p> <p>I think what needs to be done if you want importable tests, is to ignore <code>go test</code> functionality entirely and make an assertion library that prints lines the assertion failed on itself.</p> <p>You can still use <code>go test</code>, but <code>go test</code> has no data outside of the source test file :/</p></pre>0xjnml: <pre><blockquote> <p>If that&#39;s the method used, then you have no idea what line/etc the imported tests failed on.</p> </blockquote> <p>Nothing prevents <code>err</code> to say that ;-)</p></pre>earthboundkid: <pre><p>See e.g. <a href="https://github.com/pkg/errors" rel="nofollow">https://github.com/pkg/errors</a></p></pre>eduncan911: <pre><p>I&#39;ve been addressing sharing tests across packages by organizing my code into a sharable package itself.</p> <p>Having tests I want to duplicate across multiple packages smells.</p> <p>Just break out the code to a package, with its test coverage, and include that package into your multiple projects.</p> <p>If your project code, that uses the shared package, requires duplicate test code, I&#39;d say your code is too tightly coupled to the package and to interface it instead. That way your Project tests stays focused on your Project, not how the shared package effects your project.</p> <p>Lastly, I do have duplicate test code in some packages, yes. You typically let go of DRY with go with the lack of generics, in order to keep the code and tests legible.</p></pre>TheMerovius: <pre><p>I&#39;m not totally clear on the issue you are having, but <a href="https://github.com/golang/proposal/blob/master/design/4899-testing-helper.md" rel="nofollow">this proposal</a> will probably land in 1.9 and might address your issue?</p></pre>epiris: <pre><p>I think it&#39;s okay to let testing.T cross package boundaries on occasion when it makes sense. Try not to call t.Fatal and use t.errorf in the external package and return if you can&#39;t continue instead, then you can check Failed after.</p> <pre><code>if testpkg.Run(t); t.Failed() { t.Fatal(&#34;failed common test pkg validation&#34;) } </code></pre> <p>You will have the errorf failures in your test log and a exact failure point. But you can often get away with well named subtests instead and not have to worry about errorf or Fatalf calls. I do this more often:</p> <pre><code>t.Run(&#34;Common&#34;, func(t *testing.T) { somepkg.Run(t); } </code></pre> <p>It has the advantage of giving a nice canonical presentation in failed test names allowing you to chain your T through multiple shared tests like &#34;Request/Common/Validation&#34; &#34;SomethingElse/Common/Validation&#34;. </p> <p>Basically I use subtests as often as possible for context on where failure occurs, I use messages for WHY failure occurs.</p></pre>

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

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