{"id":79965,"date":"2018-07-20T20:11:32","date_gmt":"2018-07-20T20:11:32","guid":{"rendered":"https:\/\/www.red-gate.com\/simple-talk\/?p=79965"},"modified":"2021-04-27T13:58:12","modified_gmt":"2021-04-27T13:58:12","slug":"go-unit-tests-tips-from-the-trenches","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/devops\/testing\/go-unit-tests-tips-from-the-trenches\/","title":{"rendered":"Go Unit Tests: Tips from the Trenches"},"content":{"rendered":"<div id=\"toc_container\">\n<h2 class=\"toc_title\">Contents<\/h2>\n<ol class=\"toc_list\">\n<li><a href=\"#Go_Unit_Tests\">Go Unit Tests: Tip from the Trenches<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844646\">Mindset<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844647\">Unit tests as a Contract<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844648\">Write Tests for Humans<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844649\">Tests are Software, Too<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844650\">Working with Tests in Go<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844651\">Foundations of a Test<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844652\">Running tests<\/a>\n<ol>\n<li><a href=\"#post-79965-_Toc519844664\">Running tests in VSCode<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844665\">Running tests on the Command Line<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844666\">Debugging tests<\/a><\/li>\n<\/ol>\n<\/li>\n<li><a href=\"#post-79965-_Toc519844653\">Organizing Tests with Subtests<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844654\">Setup and Teardown<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844655\">Test Files and Test Packages<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844656\">Test Data: Constant, Fake, or Random?<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844657\">Fake Data in Practice<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844658\">Code Coverage<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844659\">Test Quality<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844660\">Putting Coverage All Together<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844661\">The Awesome Sauce<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844662\">Summary<\/a><\/li>\n<li><a href=\"#post-79965-_Toc519844663\">References<\/a><\/li>\n<\/ol>\n<\/div>\n<h2 id=\"Go_Unit_Tests\">Go Unit Tests: Tips from the Trenches<\/h2>\n<p>Unit tests are crucial to long-term success of a project yet almost never taught formally. We are expected to learn by osmosis, but often we end up dooming ourselves from the start, due to misconceptions or gaps in knowledge. I hope to fill in some of those gaps and provide a broad swath of ideas to tackle unit tests in Go, the language I am currently using on a daily basis. What you will find within are both concepts and practices, drawing from my experience across several languages, showing how to enrich your Go unit tests.<\/p>\n<p>Why write unit tests? Conventional wisdom says so you can refactor or otherwise modify your code with a safety net. While true, that just scratches the surface. Here are some key benefits of unit tests:<\/p>\n<ul>\n<li>Provide a safety net when refactoring<\/li>\n<li>Can help identify dead code<\/li>\n<li>Provide a measure of confidence for management<\/li>\n<li>Can sometimes find missed use cases<\/li>\n<li>Define a contract<\/li>\n<li>Helps produce higher quality code<\/li>\n<\/ul>\n<p>Of course, there are costs associated with writing unit tests as well:<\/p>\n<ul>\n<li>Time\/effort to write<\/li>\n<li>Time\/effort to maintain<\/li>\n<li>False sense of security (poor coverage, duplicate tests, testing the wrong thing, poorly written tests)<\/li>\n<\/ul>\n<p>I submit that when done well, unit tests save time rather than cost time. You get higher quality code by several measures: tighter code, cleaner code, and easier to maintain code. Here are some of the key concepts and practices you will learn from this article:<\/p>\n<ul>\n<li>Unit tests as a contract: your requirements written in code.<\/li>\n<li>How both breadth (for coverage) and depth (for protection against fragility) of test coverage are equally vital for ensuring robustness.<\/li>\n<li>Crafting unit tests is as much about the tests you don\u2019t need as those you do: test just enough but no more.<\/li>\n<li>Concise and effective patterns for writing Go unit tests.<\/li>\n<li>Interactive and just-in-time testing.<\/li>\n<li>Perspective on SOLID principles with regards to unit tests.<\/li>\n<li>What\u2019s in a name? How to communicate well with test names.<\/li>\n<li>Parameterizing unit tests; making effective use of DRY principles.<\/li>\n<li>How Go helps you test behavior, not implementation\u2014but only if you opt-in!<\/li>\n<\/ul>\n<h2 id=\"post-79965-_Toc519844646\">Mindset<\/h2>\n<p>What is more important than your code? Unit tests! Lose your code (for whatever reason) and you can recreate it from your unit tests (not saying it is trivial, but it&#8217;s possible). But lose your unit tests and you are left with fragile, difficult to maintain, and immediately questionable code as soon as you make a change.\u00a0<\/p>\n<p>Go, being a newer language, has surprisingly good support for unit tests. Tests are both (a) <em>vital<\/em> and (b) <em>practical<\/em> in Go. Some might add (c) <em>easy<\/em> to that list but, as in any language, writing good unit tests is\u00a0<em>hard<\/em>. It is more of an art than a science.\u00a0<\/p>\n<p>And, of course, writing unit tests takes time, a very finite resource given the fast pace demanded by today\u2019s market. You don\u2019t have infinite time to write tests or, for that matter, to run tests. After all, to test all possible inputs takes an unrealistically large amount of time for any but the most trivial function.<\/p>\n<h2 id=\"post-79965-_Toc519844647\">Unit tests as a Contract<\/h2>\n<p>When reviewing code, where do you start?<\/p>\n<p>The code? No.<\/p>\n<p>The tests? No.<\/p>\n<p>The test\u00a0<em>names<\/em>.<\/p>\n<p>Test names alone can reveal a lot about the quality of the code. Test names should correspond to the low-level requirements. You may or may not be an advocate of TDD (test-driven development). If you are I submit that you want to start the same way: write out the names of the necessary tests as you tackle each requirement. Consider this example requirement:<\/p>\n<pre class=\"lang:c# theme:vs2012\">Extraneous whitespace around the category name should be ignored.<\/pre>\n<p>Corresponding unit test names might be:<\/p>\n<pre class=\"lang:c# theme:vs2012\">HandleCategory trims LEADING spaces\r\nHandleCategory trims TRAILING spaces\r\nHandleCategory trims LEADING and TRAILING spaces<\/pre>\n<p>How do you know if these represent the correct set of unit tests?<\/p>\n<ol>\n<li>every requirement is covered by one or more unit tests;<\/li>\n<li>the unit tests for a given requirement exhaustively cover that requirement; and<\/li>\n<li>every unit test is present to meet a requirement.<\/li>\n<\/ol>\n<p>In the above example, (1) and (3) are satisfied. Point (2) is more interesting. Any code coverage tool would report 100% coverage for that particular functionality. But point (2) above does not ask for 100% coverage; it asks for exhaustive coverage, which means it is asking for more than 100% coverage! This touches upon broad coverage vs. deep coverage, discussed later.<\/p>\n<h3>Unit Test Names are Important<\/h3>\n<p>The style of test name I like is:<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;ItemUnderTest&gt; &lt;expected behavior&gt; &lt;under what state or condition&gt;<\/pre>\n<p>Mapping these to the first test name in the previous example:<\/p>\n<pre class=\"lang:c# theme:vs2012\">&lt;ItemUnderTest&gt; =&gt; \"HandleCategory\"\r\n&lt;expected behavior&gt; \"trims LEADING spaces\"\r\n&lt;under what state or condition&gt; ??<\/pre>\n<p>I see a lot of Go unit tests without the condition, just a list of expectations (or contrariwise, just a list of states without expectations). Either way, it can easily lead to blind spots, things you are not testing that you should be. Let&#8217;s revise the three tests above to include both condition and expectation:<\/p>\n<pre class=\"lang:c# theme:vs2012\">HandleCategory trims LEADING spaces from valid category\r\nHandleCategory trims TRAILING spaces from valid category\r\nHandleCategory trims LEADING and TRAILING spaces from valid category<\/pre>\n<p>Immediately upon reading those, I bet you noticed we are missing some tests (and\/or requirements!). What happens if we give an empty category? Or an invalid category? What constitutes a valid category?<\/p>\n<h2><a id=\"post-79965-_Toc519844648\"><\/a>Write Tests for Humans<\/h2>\n<p>A large portion of code we write does not have performance requirements down to microseconds. Write for humans not for computers. Computers will understand your code no matter how convoluted you make it. Humans, not so much. In the immediate context, write tests to make them as clear and obvious as possible. Two things to look at here: the test\u00a0<em>name<\/em> and the test\u00a0<em>body<\/em>.<\/p>\n<p>You have already seen what I like to do with test names: highlight (via ALL_CAPS) what is unique or important about a test. Looking at the three test names above, it is immediately clear what distinguishes each test from the others.<\/p>\n<p>As to the body, here is an example you will see again a bit later. This test uses the\u00a0<strong>Arrange-Act-Assert<\/strong>\u00a0design pattern. Organize your test into three sections of code separated by a blank line to add visual separation.\u00a0<strong>Arrange<\/strong>\u00a0what you need in the first section to be able to test your function.\u00a0<strong>Act<\/strong>\u00a0upon that function in the second section. And in the final section\u00a0<strong>Assert<\/strong>\u00a0one or more conditions that you expect to be true.\u00a0<\/p>\n<p>When first getting started, I encourage developers to literally include the comments with those labels, but once you and your teammates get acclimated to the pattern those can be omitted. But do not omit the blank lines between sections&#8211;those make it easier for the eye to separate the pieces.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"261\" height=\"179\" class=\"wp-image-79966\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image-pn-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image.png\" \/><\/p>\n<h2><a id=\"post-79965-_Toc519844649\"><\/a>Tests are Software, Too<\/h2>\n<p>Tests are software, too, so apply software principles in a test-meaningful way.<\/p>\n<p>The\u00a0<strong>Single Responsibility Principle<\/strong>\u00a0(SRP) says that a class or a function should be focused, not doing unrelated tasks.\u00a0Similarly, a given test should only test one thing. Note that that does\u00a0<em>not<\/em>\u00a0always mean just a single assertion. It is fine to use multiple assertions if that is what it takes to validate that something occurred.<\/p>\n<p>The\u00a0<strong>Don&#8217;t Repeat Yourself<\/strong>\u00a0principle (DRY) says that if you repeat the same lines of code over and over, extract them into a function, then just call that function in each place instead. Of course, that applies \u2018as is\u2019 in test code as well. But there is more in the realm of tests: do not test the same thing in multiple tests.\u00a0Ideally when something breaks in your system you want exactly one test to fail. That lets you find the source of the problem much quicker. If 5 or 20 or 100 tests fail at the same time, you have a lot more hunting to do.<\/p>\n<h2><a id=\"post-79965-_Toc519844650\"><\/a>Working with Tests in Go<\/h2>\n<p>Let&#8217;s start with the basics. You may already know much of this, but I know in my own experience it is important to make sure you have a good foundation before launching into more complex topics, so bear with me. And you may find a few things to surprise you here!<\/p>\n<p>The first step is (a) knowing what constitutes a valid test file and (b) how to know if you&#8217;ve got one. (OK, you could argue that is two steps!)<\/p>\n<p>This looks like a perfectly valid Go test file&#8211;but it is\u00a0<em>invalid<\/em>.\u00a0<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"422\" height=\"263\" class=\"wp-image-79967\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image1-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(1).png\" \/><\/p>\n<p>This is almost identical&#8211;but this one is valid. The reason I know that is because my IDE (integrated development environment) tells me so, in the guise of the active controls I have indicated with the arrows. (I use VSCode with the aptly named &#8220;Go&#8221; plugin from Microsoft.)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"425\" height=\"289\" class=\"wp-image-79968\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image2-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(2).png\" \/><\/p>\n<p>The requirements for a\u00a0<strong>valid<\/strong>\u00a0test file in Go are just these:<\/p>\n<ol>\n<li>File name ends in\u00a0<strong>_test.go<\/strong>.<\/li>\n<li>Include a <strong>package<\/strong> declaration in the file.<\/li>\n<\/ol>\n<p>That&#8217;s it! So if I create a correctly named file with just a package declaration, VSCode materializes the controls above line 1 here:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"442\" height=\"110\" class=\"wp-image-79969\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image3-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(3).png\" \/><\/p>\n<p>Now that you know the rules, it is easy to determine the subtle difference between the two files above: the filename in the first ends in <strong>_tst.go<\/strong>, so it fails rule 1!<\/p>\n<p>Of course, the one-line file above, while valid, won&#8217;t do much&#8211;it has no tests to run! So the minimally\u00a0<strong>useful<\/strong>\u00a0test file is something more akin to this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"350\" height=\"213\" class=\"wp-image-79970\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image4-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(4).png\" \/><\/p>\n<p>The requirements for a\u00a0<strong>useful<\/strong>\u00a0test file:<\/p>\n<ol>\n<li>File name ends in\u00a0<strong>_test.go<\/strong>.<\/li>\n<li>Include a <strong>package<\/strong> declaration in the file.<\/li>\n<li>Include one or more test functions (e.g. line 6) with a name of the form\u00a0<strong>Test<\/strong><em>Something<\/em>.\u00a0<em>Something<\/em>\u00a0must start with an uppercase character.\u00a0<\/li>\n<li>Include a single argument of type\u00a0<strong>*testing.T<\/strong>\u00a0in each such function.<\/li>\n<li>Do some stuff and assert that things match your expectations with the\u00a0<strong>assert<\/strong>\u00a0function.<\/li>\n<\/ol>\n<h2><a id=\"post-79965-_Toc519844651\"><\/a>Foundations of a Test<\/h2>\n<p>Strip a unit test down to its core and what you have left are one or more assertions you wish to validate. You can do this with \u201craw\u201d code, for example, like this:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-80054\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/ms1.png\" alt=\"\" width=\"381\" height=\"122\" \/><\/p>\n<p>But then you would likely want to extract that <strong>t.ErrorF<\/strong> into a separate function so that all your tests could call it, producing uniformly styled error messages. Then you will likely find other patterns in your test code that are common. Like many things in programming, there is no need to \u2018reinvent the wheel.\u2019 A good library that provides support for these kinds of fundamental assertions is <a href=\"https:\/\/godoc.org\/github.com\/stretchr\/testify\">testify<\/a><strong>. <\/strong>Testify provides\u00a0<strong>assert<\/strong>\u00a0and\u00a0<strong>require<\/strong>\u00a0packages, which should be your lingua franca of testing. Almost every test or subtest should be using them. Use\u00a0<strong>assert<\/strong>\u00a0to accomplish the objective of a test&#8211;verify that something is as you expect it to be. Use\u00a0<strong>require<\/strong>\u00a0to make sure everything is in a reasonable state before\u00a0<strong>assert<\/strong>ing your test objectives. They look and act much the same, except\u00a0<strong>assert<\/strong>\u00a0reports failure and\u00a0<em>continues<\/em>\u00a0while\u00a0<strong>require<\/strong>\u00a0reports failure and\u00a0<em>stops<\/em>.<\/p>\n<p>That does not sound like much of a difference, but\u00a0<strong>require<\/strong>\u00a0makes your code much more streamlined, shown below. At left is a common pattern I had seen throughout a large code base. Converting that to use <strong>require<\/strong> obviates the need for messy nested conditionals (1 below) and makes clearer the objective of the test&#8211;where the actual result data is examined for shape and content (2 below).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"643\" height=\"284\" class=\"wp-image-79972\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image5-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(5).png\" \/><\/p>\n<h2><a id=\"post-79965-_Toc519844652\"><\/a>Running tests<\/h2>\n<p>You can run tests within VSCode or from the command-line. Both have their place.<\/p>\n<h3><a id=\"post-79965-_Toc519844664\"><\/a>Running tests in VSCode<\/h3>\n<p>When you are writing code in VSCode, it is valuable that you can just execute tests right from the editor window; you do not have to switch to a separate external console or even VSCode&#8217;s built-in console. Just\u00a0click on any of the active controls embedded in your file by the Go plugin, which you saw above:<\/p>\n<ul>\n<li>run package tests<\/li>\n<li>run file tests<\/li>\n<li>run test<\/li>\n<li>debug test<\/li>\n<\/ul>\n<p>Test results from these appear in VSCode&#8217;s\u00a0<strong>Output<\/strong>\u00a0panel. Personally, I favor the ability to do continuous testing in an IDE. This is available for some IDEs and some languages. The best I have used is <strong>NCrunch<\/strong> in Visual Studio .NET-land when I worked in that realm. Currently I use <strong>Wallaby.js<\/strong> for front-end development, which also does a fine job. Both of those provide <strong>test-on-<em>type<\/em><\/strong>, i.e. as you type your affected unit tests are re-run automatically. The Go plugin does not support test-on-type but it does support the next best thing, <strong>test-on-<em>save<\/em><\/strong>. So each time you save your file, it re-executes tests automatically. This is turned off by default; just edit your user settings and set\u00a0<strong>go.testOnSave\u00a0<\/strong>to true.<\/p>\n<p>One curious artifact about the Go plugin: The Go test engine does not execute a test file if its name begins with underscore or dot. However, the Go plugin still displays\u00a0the\u00a0<strong>run file tests<\/strong>\u00a0and\u00a0<strong>run test<\/strong>\u00a0controls in those files.<\/p>\n<h3><a id=\"post-79965-_Toc519844665\"><\/a>Running tests on the Command Line<\/h3>\n<p>On the command line, the simplest command executes all test files in your current directory (excluding any file name beginning with underscore or dot):<\/p>\n<p>\u00a0 \u00a0\u00a0<strong>go test\u00a0<\/strong>shows\u00a0just failure details plus a final result.<\/p>\n<p>\u00a0 \u00a0\u00a0<strong>go test -v\u00a0<\/strong>shows\u00a0<em>all<\/em>\u00a0test details plus a final result.<\/p>\n<p>Here is a simple example:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"430\" height=\"272\" class=\"wp-image-79973\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image6-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(6).png\" \/><\/p>\n<p>The above, no-argument form of\u00a0<strong>go test<\/strong>\u00a0has two characteristics to note: it executes test files in your current directory, and it always runs all the tests found. This is called\u00a0<strong>local directory<\/strong>\u00a0mode. For any but the most trivial project you probably will want to use\u00a0<strong>package list<\/strong>\u00a0mode instead. Package list mode provides two benefits:<\/p>\n<ol>\n<li>It executes just test files in the package(s) specified in the argument.<\/li>\n<li>It caches results, only re-running tests affected by code you have changed.<\/li>\n<\/ol>\n<p>You can give as simple an argument as a single dot, signifying the current directory,<\/p>\n<p>and then only test files in the current directory that have changed will be retested.\u00a0<\/p>\n<pre class=\"lang:c# theme:vs2012\">\u00a0\u00a0 \u00a0go test .<\/pre>\n<p>But even better: use the triple-dot wildcard (&#8230;) to test everything in your file tree at or below a specified directory. This canonical form starts with a single dot to root it at the current directory:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\u00a0\u00a0 \u00a0go test .\/...<\/pre>\n<p><a id=\"post-79965-_gjdgxs\"><\/a> As to the caching aspect, Go is not just watching for changes to know whether to run tests in a given file. It is watching for changes\u00a0<em>it has not seen before<\/em>, like a true cache. So if you test a file with contents\u00a0<em>x<\/em>, then change it slightly to have\u00a0<em>x&#8217;<\/em>,\u00a0<strong>go test .\/&#8230;\u00a0<\/strong>will re-test. But change it back to\u00a0<em>x<\/em>\u00a0and then\u00a0<strong>go test .\/&#8230;\u00a0<\/strong>will not re-test\u2014it reports results from the cache. This can be quite a time saver!<\/p>\n<p>Even with Go&#8217;s test cache, if you know which tests you care about at a particular time, you can apply filtering to make testing go even faster. You can apply filtering by\u00a0<em>file name<\/em>\u00a0or filtering by\u00a0<em>test name<\/em>.<\/p>\n<p>To filter by file name, just specify a single file or, with file globbing, multiple file as arguments to\u00a0<strong>go test<\/strong>:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\u00a0 \u00a0go test subdir\/fixture3_test.go -v<\/pre>\n<p>To filter by test name, use the <strong>-run<\/strong> flag followed by a regular expression. Keep in mind that you are matching test function names, not file names. For illustration, say you had functions TestBasic1, TestBasic2, etc., up to 10. You could run a subset of those like this:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\u00a0\u00a0 \u00a0go test -run Basic[3-5] \u2013v<\/pre>\n<p>To see what tests your regex will match without actually running the tests use the\u00a0<strong>-list<\/strong>\u00a0flag instead of the\u00a0<strong>-run<\/strong>\u00a0flag:<\/p>\n<pre class=\"lang:c# theme:vs2012\">\u00a0\u00a0 \u00a0go test -list Basic[3-5]<\/pre>\n<p>You can combine filtering and caching for even more peppy execution, e.g.<\/p>\n<pre class=\"lang:c# theme:vs2012\">\u00a0\u00a0 \u00a0go test .\/... -run Basic \u2013v<\/pre>\n<div class=\"note\">\n<p><em>Note that as of Go 1.9 (<a href=\"https:\/\/golang.org\/doc\/go1.9#vendor-dotdotdot\">https:\/\/golang.org\/doc\/go1.9#vendor-dotdotdot<\/a>),\u00a0<strong>go test<\/strong>\u00a0automatically skips vendor directories.\u00a0You used to have to manually filter those out with something like the code shown below, but it is no longer necessary.<\/em><\/p>\n<\/div>\n<pre class=\"lang:c# theme:vs2012\">for f in $(go list .\/... | grep -v vendor); do\r\n\u00a0 \u00a0 go test $f\r\ndone<\/pre>\n<h3><a id=\"post-79965-_Toc519844666\"><\/a>Debugging tests<\/h3>\n<p>From VSCode, with the Go plugin and the delve debugger, debugging is easy. You have seen the <strong>debug test<\/strong> control right alongside the <strong>run test<\/strong> control provided in the editor. Just set some breakpoints and use the debug test button to step into your code, where you can examine variables, the call stack, etc.<\/p>\n<p>You can also use the delve debugger from the command-line, if command-line is your preference. See its user guide for commands.<\/p>\n<p>Important note on delve and MacOS: As of this writing, delve has an incompatibility with version 9.3 and 9.4 of Xcode command line tools. The remedy for some time was to downgrade your Xcode version to 9.1 or 9.2. But as of a couple weeks ago (June 2018), a beta for version 10 has been released and that seems to have fixed the issue. The symptom for the problem is that delve reports \u2018could not launch process: EOF.\u2019 If you encounter that, check your XCode version. Plentiful details on the issue are available at <a href=\"https:\/\/github.com\/derekparker\/delve\/issues\/1015\">https:\/\/github.com\/derekparker\/delve\/issues\/1015<\/a>.<\/p>\n<p>Finally, the test runner also supports good ol\u2019 console logging, in the guise of <strong>t.Log<\/strong> and t.<strong>Logf<\/strong> functions with which you can instrument your code. Say you have a test failure (as in 1 below). Go back and instrument your code with a logging statement (2). The <strong>f<\/strong> on the end of <strong>Logf<\/strong> is supposed to signal to you that this version uses <strong>sprintf<\/strong>-style formatting codes, like the <strong>%d<\/strong> you see included. When you run your test, your logging output will be interspersed with test results (3). Note that <strong>Log<\/strong> and <strong>Logf<\/strong> only display output if the test containing them fails or the <strong>\u2013v<\/strong> flag has been passed to <strong>go test<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"686\" height=\"495\" class=\"wp-image-79974\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-image-png-3.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\Image.png\" \/><\/p>\n<h2><a id=\"post-79965-_Toc519844653\"><\/a>Organizing Tests with Subtests<\/h2>\n<p>You can certainly get by with all your tests as top-level tests. Some shops do this. For instance, I grabbed this from one random, real project (grpcurl):<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"502\" height=\"199\" class=\"wp-image-79975\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image7-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(7).png\" \/><\/p>\n<p>But subtests can often provide more useful organization. Here is the same set of tests re-organized with subtests.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"391\" height=\"217\" class=\"wp-image-79976\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image8-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(8).png\" \/><\/p>\n<p>And yet another variation adding further hierarchy:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"421\" height=\"218\" class=\"wp-image-79977\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image9-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(9).png\" \/><\/p>\n<p>Use subtests to:<\/p>\n<ol>\n<li>share common setup\/teardown,<\/li>\n<li>create hierarchical test structure, and<\/li>\n<li>give more useful names to tests.<\/li>\n<\/ol>\n<p>Here is a full example of how to define subtests under\u00a0<strong>TestBasics<\/strong>. The\u00a0<strong>t.Run<\/strong>\u00a0method takes 2 arguments, a test\u00a0<em>name<\/em>\u00a0and a test\u00a0<em>function<\/em>. For brevity I have shown just a single assertion in each subtest but, of course, you can put as much as you need in each.\u00a0<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"423\" height=\"290\" class=\"wp-image-79978\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image10-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(10).png\" \/><\/p>\n<p>Consider a more practical, larger set of tests. Without subtests, you get a handy list in VSCode&#8217;s outline-view to instantly navigate to any of your tests. Clicking on any test in the outline view (1 below) brings that test into view in the editor (2 below). You can then run that test with the\u00a0<strong>run test<\/strong>\u00a0or\u00a0<strong>debug test<\/strong>\u00a0controls just above it. However, you are only able to run one test at a time that way. Your only other option is to run all the tests in the file or in the package (either with the controls at the top of the file or via a VSCode command).<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"620\" class=\"wp-image-79979\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image11-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(11).png\" \/><\/p>\n<p>If, on the other hand, you organize your test file with subtests you can now act on groups of tests as one. So not only do you get a shorter list in the code outline, but in the editor the\u00a0<strong>run test<\/strong>\u00a0and\u00a0<strong>debug test<\/strong>\u00a0controls apply to the whole group of subtests&#8211;one click runs the group.\u00a0<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"838\" height=\"620\" class=\"wp-image-79980\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image12-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(12).png\" \/><\/p>\n<h2><a id=\"post-79965-_Toc519844654\"><\/a>Setup and Teardown<\/h2>\n<p>One more benefit to using subtests segues into this next topic of setup and teardown. Some languages support\u00a0<strong>Setup<\/strong>\u00a0or\u00a0<strong>BeforeEach<\/strong>\u00a0functions that run before each test, group of test, or package of tests. Most commonly seen:<\/p>\n<ol>\n<li>Setup code before each suite\/package\/group of tests<\/li>\n<li>Setup code\u00a0before each test<\/li>\n<li>Teardown code\u00a0after each test<\/li>\n<li>Teardown code\u00a0after each suite\/package\/group of tests<\/li>\n<\/ol>\n<p>Subtests provide an easy way to do (1) and (4) for a group of tests. (But read on; don&#8217;t do it this way!)<\/p>\n<p>\u00a0 <img loading=\"lazy\" decoding=\"async\" width=\"385\" height=\"253\" class=\"wp-image-79981\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image13-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(13).png\" \/><\/p>\n<p>A more robust and Go-flavored way to do this (with thanks to\u00a0Kare Nuorteva at <a href=\"https:\/\/stackoverflow.com\/a\/40748810\">https:\/\/stackoverflow.com\/a\/40748810<\/a>\u00a0) is shown next. This has several advantages.<\/p>\n<ul>\n<li>It keeps the setup and teardown\u00a0<em>definitions<\/em>\u00a0very intimately tied (L7-L9), helping to ensure you do teardown what you setup.<\/li>\n<li>It keeps the\u00a0setup and teardown\u00a0<em>calls<\/em>\u00a0together (L15-16), helping ensure you don&#8217;t forget to invoke the teardown.<\/li>\n<li>It guarantees (via\u00a0<strong>defer<\/strong>) to run the teardown, even if a panic occurs.<\/li>\n<\/ul>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"414\" height=\"459\" class=\"wp-image-79982\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image14-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(14).png\" \/><\/p>\n<p>Another way to do setup\/teardown for a group of tests is via <em>table-driven<\/em> (or <em>data-driven<\/em>) tests. This also is quite amenable to doing setup\/teardown for <em>each<\/em> test&#8211;that is (2) and (3) from the above list. You define multiple tests in a data set but with only a single test body, so any code you within that body is&#8211;by definition&#8211;setup or teardown If it is outside the for loop, it is the group setup\/teardown. Inside the <strong>for<\/strong> loop is the individual setup\/teardown. ( Example from\u00a0<a href=\"https:\/\/medium.com\/@matryer\/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742\">https:\/\/medium.com\/@matryer\/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742<\/a>\u00a0)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"527\" height=\"610\" class=\"wp-image-79983\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image15-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(15).png\" \/><\/p>\n<p>Looking at the package level next, Go 1.4 introduced the\u00a0<strong>TestMain<\/strong>\u00a0hook, which lets you do setup and teardown at the package level (\u00a0<a href=\"https:\/\/golang.org\/pkg\/testing\/#hdr-Main\">https:\/\/golang.org\/pkg\/testing\/#hdr-Main<\/a>\u00a0). If a test files contains a\u00a0<strong>TestMain<\/strong>\u00a0function, that function will be called rather than executing your tests directly.\u00a0<strong>TestMain<\/strong>\u00a0then needs to invoke\u00a0<strong>m.Run()<\/strong>\u00a0to run the tests within the package, and return its result to\u00a0<strong>os.Exit()<\/strong>. Here is a basic structure for a\u00a0<strong>TestMain<\/strong>\u00a0function. Create the\u00a0<strong>packageSetup<\/strong>\u00a0and\u00a0<strong>packageTeardown<\/strong>\u00a0functions to do whatever you need. More info on\u00a0<strong>TestMain<\/strong>\u00a0is available at\u00a0<a href=\"http:\/\/cs-guy.com\/blog\/2015\/01\/test-main\/\">http:\/\/cs-guy.com\/blog\/2015\/01\/test-main\/<\/a>\u00a0.<\/p>\n<pre class=\"lang:c# theme:vs2012\">func TestMain(m *testing.M) {\r\n\u00a0 \u00a0 packageSetup()\r\n\u00a0 \u00a0 resultCode\u00a0:= m.Run()\r\n\u00a0 \u00a0 packageTeardown()\r\n\u00a0\u00a0\u00a0 os.Exit(resultCode)\r\n}<\/pre>\n<p>That technique &#8212; including both setup and teardown &#8212; is great when you need to be thoughtful about resources (setting up then cleaning up a database, for example). But sometimes you just need to setup some conditions, states, or the like, and do not need a complementary teardown. The\u00a0<strong>init<\/strong>\u00a0function provides this and is simpler than\u00a0<strong>TestMain\u00a0<\/strong>(\u00a0<a href=\"https:\/\/golang.org\/doc\/effective_go.html#init\">https:\/\/golang.org\/doc\/effective_go.html#init<\/a>\u00a0). The only thing you need to do is add a niladic\u00a0<strong>init<\/strong>\u00a0function in your test file. If this function is present, it is automatically run before any of the tests in that file<\/p>\n<pre class=\"lang:c# theme:vs2012\">func init() {\r\n\u00a0 \/\/ do your package setup here\r\n}<\/pre>\n<p>Take heed, though, what Peter Bourgon advocates (<a href=\"https:\/\/peter.bourgon.org\/blog\/2017\/06\/09\/theory-of-modern-go.html\">https:\/\/peter.bourgon.org\/blog\/2017\/06\/09\/theory-of-modern-go.html<\/a>) : no package level variables and no\u00a0<strong>init<\/strong>\u00a0function. I think it is more useful to adhere to that advice in mainline (non-test code); I find it somewhat less \u2018sinful\u2019 to include\u00a0<strong>init<\/strong>\u00a0in test code.<\/p>\n<h2><a id=\"post-79965-_Toc519844655\"><\/a>Test Files and Test Packages<\/h2>\n<p>Within a single folder, all Go files must be in the same package. The one exception is test files: those with a\u00a0<strong>_test.go<\/strong>\u00a0suffix.\u00a0<\/p>\n<p>There is a really good reason for that: your test files should always be in a\u00a0<strong>different<\/strong>\u00a0package. (So for package\u00a0<strong>xyz<\/strong>, put your test files in package\u00a0<strong>xyz_test<\/strong>.) Why do this? Because it forces you to test\u00a0<em>behavior<\/em>\u00a0rather than\u00a0<em>implementation<\/em>, as good unit tests do. If you are in a different package, you only have access to the API of the package; you do not have access to internal state. So you are forced to treat the package as a black box, which is a good thing. That way, you are free to change internals without breaking tests as long as the API does not change.<\/p>\n<p>By the way, don&#8217;t always believe everything you hear\/read! One spot in the go docs advises to use a separate package for test code while another portion of the docs suggests not using a separate package.<\/p>\n<p>In reality, though, there are situations where you cannot unit test everything just from the external API. So when you really need to test package internals, use the same package as the code under test (e.g.\u00a0<strong>xyz<\/strong>) but name your test file with the\u00a0<strong>_internal_test.go<\/strong>\u00a0suffix (so\u00a0<strong>xyz_internal_test.go<\/strong>)\u00a0to make it explicit and clear that you know these tests are more brittle. (Not sure if Mat Ryer originated this idea, as I have seen it used in several projects, but he wrote about it at\u00a0<a href=\"https:\/\/medium.com\/@matryer\/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742\">https:\/\/medium.com\/@matryer\/5-simple-tips-and-tricks-for-writing-unit-tests-in-golang-619653f90742<\/a>.)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"432\" height=\"97\" class=\"wp-image-79984\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/word-image-154.png\" \/><\/p>\n<h2><a id=\"post-79965-_Toc519844656\"><\/a>Test Data: Constant, Fake, or Random?<\/h2>\n<p>Here is a test with constant data&#8211;what is wrong with this test?<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"256\" height=\"112\" class=\"wp-image-79985\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image16-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(16).png\" \/><\/p>\n<p>The shortest answer&#8211;this function makes the test pass:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"261\" height=\"68\" class=\"wp-image-79986\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image17-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(17).png\" \/><\/p>\n<p>If you practice TDD, writing the above test, followed by the above function, might actually be what you do first. And all is good to that point. But your function needs to evolve to handle other values, too. You could write a few more tests that supply different constants to satisfy yourself that the function actually acts on the input. How many would give you a good confidence level in the underlying code? Well, you could enumerate all seven valid values, plus an invalid one and an empty one, so perhaps nine would do. And do that with a table-driven test, even better. Easy. But what if the function takes a second argument&#8211;is it practical to do all combinations? Or what if the enumerated set is a lot larger, say days of the month? If just a single variable, do you do 31 tests? Maybe. How about time zone names? Not sure if there is a global standard, but one list I saw has almost 600 entries. Do you test each of those? Do you need to? I hope not!\u00a0<\/p>\n<p>What if you could do one test that covers all valid days of the week? Or all valid time zones? How? The test just picks one at random. You don&#8217;t care which one. Or perhaps it picks a few at random. Let it pick a different one each time you run the test so hard-coding an answer, as shown earlier, would not pass the test. Unless you hard-code a giant switch statement; but then you have problems beyond the scope of this article to worry about! Now this value could be\u00a0<em>fake<\/em>\u00a0or it could be\u00a0<em>random<\/em>. My distinction is that fake data provides a value from a\u00a0<em>valid<\/em>\u00a0set of choices, while random data, on the other hand, provides a value from an\u00a0<em>unconstrained<\/em>\u00a0set.<\/p>\n<p>Random has its uses. It is good to make sure routines that accept user input do not blow up no matter what you feed them. I have seen web pages aplenty that choke if you happen to type an ampersand in a sentence! It is the job of those routines on the front line to untaint the data before passing it along to all your other routines. That should give all those other routines \u00a0some level of comfort that they will only receive valid inputs, a much more constrained set of values to worry about. Interesting commentary on monkey testing \/ fuzz testing:\u00a0<a href=\"https:\/\/stackoverflow.com\/questions\/32458\/random-data-in-unit-tests\">https:\/\/stackoverflow.com\/questions\/32458\/random-data-in-unit-tests<\/a> .<\/p>\n<p>Certainly you should test invalid values for\u00a0<em>user-facing\u00a0<\/em>routines, but randomly picking invalid values is not the best approach. (More at <em>Test Quality<\/em> below.) However, testing valid values (with arbitrary fake data) does make sense. If you can let your test roam over a wide range of valid values without you having to code that explicitly, that gives a much better confidence level in your code correctness.<\/p>\n<p>But with\u00a0<em>non-user-facing<\/em>\u00a0routines&#8211;those receiving untainted data from the front lines and typically comprising the bulk of one&#8217;s code base&#8211;your main focus should be valid, yet arbitrary, inputs.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"594\" height=\"391\" class=\"wp-image-79987\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image18-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(18).png\" \/><\/p>\n<p>Many languages have libraries to generate fake data, at different levels of maturity. The one I have found useful in Go is fairly new, but it provides a good foundation for improving your unit tests.<\/p>\n<h2><a id=\"post-79965-_Toc519844657\"><\/a>Fake Data in Practice<\/h2>\n<p>Let&#8217;s return to the example above, now with fake data generation.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"460\" height=\"449\" class=\"wp-image-79988\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image19-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(19).png\" \/><\/p>\n<p>Here we:<\/p>\n<ol>\n<li>Bring in the library.<\/li>\n<li>Create an empty struct containing slots for data we want to fake (in this case a\u00a0<strong>DayString<\/strong>) and fill it up.<\/li>\n<li>Slight change to the call to our code under test to reference the target property.<\/li>\n<li>And now a generalized test assertion that can be satisfied for any valid value; we do not know or care which one we actually got.<\/li>\n<li>The coolest thing about this library from Iman Tumorang is that it knows a nice selection of standard data types, including what a day of the week is. And all you have to do to leverage that is tag your structure field as shown here.<\/li>\n<\/ol>\n<p>The faker library also supports email address, mac addresses, IP addresses, credit card types &amp; numbers, phone numbers, time zones, sentences, and more!<\/p>\n<p>Here is a more elaborate example&#8211;I&#8217;ve copied this structure from the library author&#8217;s page:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"418\" height=\"263\" class=\"wp-image-79989\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image20-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(20).png\" \/><\/p>\n<p>And here&#8217;s a test I wrote to demonstrate the validity of some of its content. This shows that the library nicely handles arbitrarily nested data structures.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"416\" height=\"391\" class=\"wp-image-79990\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image21-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(21).png\" \/><\/p>\n<p>The above <strong>faker<\/strong> library is, of course, just one way to approach feeding data to tests. Another approach might be a <a href=\"https:\/\/en.wikipedia.org\/wiki\/QuickCheck\">QuickCheck<\/a>-style library, which derives a set of test cases for you from a set of assertions you write about a given function. <a href=\"https:\/\/github.com\/leanovate\/gopter\">Gopter<\/a> (the <strong>GO<\/strong>lang <strong>P<\/strong>roperty <strong>T<\/strong>est<strong>ER<\/strong>) is one such package for use in the Go ecosystem.<\/p>\n<h2><a id=\"post-79965-_Toc519844658\"><\/a>Code Coverage<\/h2>\n<p>So you&#8217;ve done all these unit tests. How&#8217;s your coverage? Go gives you some easy tools to find out.<\/p>\n<p>Report code coverage summary to the console:<\/p>\n<pre class=\"lang:c# theme:vs2012\">go test .\/... \u2013cover<\/pre>\n<p>OR: generate code coverage profile&#8230;<\/p>\n<pre class=\"lang:c# theme:vs2012\">go test .\/... -coverprofile=cover.out<\/pre>\n<p>&#8230; so you can view graphical details in your browser:<\/p>\n<pre class=\"lang:c# theme:vs2012\">go tool cover -html=cover.out<\/pre>\n<p>That gives you a nice color-coded visual as to what is covered or not I&#8217;ve blurred the text here to focus just on the colors-note the color key at the top of the image:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"844\" height=\"734\" class=\"wp-image-79991\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image22-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(22).png\" \/><\/p>\n<p>That end result is somewhat nice&#8230; but three steps removed from your editor. Fear not, for with \u00a0VSCode, you can actually get coverage highlighting in situ! With the Go plugin for VSCode installed, enable coverage highlighting with <em>Go: Toggle Test Coverage in Current Package<\/em>.<\/p>\n<p>Then run tests&#8211;at the\u00a0<em>package<\/em>\u00a0level&#8211;to trigger coverage highlighting in the code under test. Note that any other way to run tests&#8211;individual test functions, test files, or run-tests-on-save&#8211;will\u00a0<em>not<\/em>\u00a0trigger highlighting.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"749\" height=\"462\" class=\"wp-image-79992\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image23-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(23).png\" \/><\/p>\n<h2><a id=\"post-79965-_Toc519844659\"><\/a>Test Quality<\/h2>\n<p>Code coverage on my last picture was about 97%. Great, right? Well, the answer to that is not &#8220;yes&#8221;. Nor is it &#8220;no&#8221;. It is, in fact, &#8220;I do not know.&#8221; Most people&#8211;and most code coverage tools&#8211;think about unit tests in terms of\u00a0<em>breadth<\/em>\u00a0of coverage&#8211;how many lines of code do your tests touch? But\u00a0<em>depth<\/em>\u00a0of coverage is just as important. My definition of depth is:\u00a0<em>how meaningfully are you touching a line?<\/em>\u00a0As you might guess, that is hard to programmatically measure. But I know it when I see it. How? Equivalence class\u00a0partitioning &amp; boundary-value analysis.<\/p>\n<p><strong>Equivalence class partitioning<\/strong>\u00a0is a $2 word for a 5-cent concept. An equivalence class is nothing more than a set of values that you could potentially pass into a test all of which answer the same question, which means that you only need to pass in\u00a0<em>one<\/em>\u00a0of them to get the benefit for\u00a0<em>all<\/em>\u00a0of them! Say we have a function that takes a list of integers and returns the largest value numerically. For our first test, we pass a list of five elements. Would it make a difference if the list had six elements, or if it had 17 elements?\u00a0In particular cases, perhaps, but in the vast majority, no; you do not gain any more or any less confidence in the code\u2019s correctness by varying that list size a bit, so all of those values (5, 6, and 17) are in the same equivalence class. Furthermore, this also implies that you do not have to test every value in the equivalence class; just pick one representative and you\u2019ve covered the equivalence class.<\/p>\n<p>Another example: consider a function that transforms lowercase ASCII characters to uppercase characters. Other characters should undergo an identity transformation, i.e. remain unchanged. Here is one possible breakdown into equivalence classes:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"606\" height=\"131\" class=\"wp-image-79993\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image24-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(24).png\" \/><\/p>\n<p>Pick one from each class: that gives you 4 tests instead of 128 (sum of the last column)<\/p>\n<p><strong>Boundary value analysis<\/strong>\u00a0recommends a slight refinement: essentially it suggests that not every member of an equivalence class is, well, equivalent. That is, values at boundaries should also be considered worthy of a test case in their own right. (One easy justification for this is the infamous\u00a0<a href=\"http:\/\/en.wikipedia.org\/wiki\/Off-by-one_error\">off-by-one error<\/a>!) Thus, for each equivalence class you could have 3 test inputs. Looking at the input domain above&#8211;and with some knowledge of ASCII values&#8211;I might come up with these test case inputs:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"359\" height=\"112\" class=\"wp-image-79994\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image25-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(25).png\" \/><\/p>\n<p>(As soon as you get more than 3 boundary values that suggests you might want to rethink your original equivalence class delineations, but this was simple enough that I did not go back to revise them.)<\/p>\n<p>So that is 17 cases giving deep(er) coverage, compared to the full set of 128&#8211;quite a savings!<\/p>\n<h2><a id=\"post-79965-_Toc519844660\"><\/a>Putting Coverage All Together<\/h2>\n<p>The best way to get deep test coverage is with data driven tests. You saw a simple example above for Fibonacci numbers. In practice, though, most code is not just pure mathematical functions. So data-driven tests should include a test name along with test parameters and test expectations.\u00a0<\/p>\n<p>Here is a simple, canonical example.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"491\" height=\"641\" class=\"wp-image-79995\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image26-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(26).png\" \/><\/p>\n<p>Create a set of test cases in a map (1) to enumerate your equivalence classes. The key of each map entry is the test name; the value is a structure containing parameters for the test along with an expected output. For brevity, I put each test case (2) on a single line but normally I would spread them out vertically to show proper structure. The body of the test (3) runs all the test cases. The test body is organized with the Arrange-Act-Assert pattern, making the test easy to follow. Running the tests (4) cleanly and clearly shows what is being tested for this function.<\/p>\n<h2><a id=\"post-79965-_Toc519844661\"><\/a>The Awesome Sauce<\/h2>\n<p>So far, we have seen these keys techniques to improve test quality:<\/p>\n<ul>\n<li>Deep Coverage:\u00a0\u2714<\/li>\n<li>Data Driven Tests:\u00a0\u2714<\/li>\n<li>Include test descriptions in your data driven tests: \u2714<\/li>\n<\/ul>\n<p>Let&#8217;s consider one more technique to provide even more expressive power and clarity in your tests: make your expectations functions rather than constants.<\/p>\n<p>First, here is an example of the test proper. (There are a few helper functions that make this work, which we&#8217;ll see next.) Just as in the basic example, you first specify a single\u00a0<strong>test case definition<\/strong>, specifying the parameters for each test case and the expected result. Next you specify the\u00a0<strong>test case instances<\/strong>\u00a0(just showing one here for brevity) in the form of a map whose key is the name or description of the test and whose value is the filled out parameters and expectations object. Finally, the\u00a0<strong>test runner<\/strong>\u00a0is the engine that iterates through each of the test cases via the\u00a0<strong>tc<\/strong>\u00a0variable (L61).<\/p>\n<p>The inner loop in the test runner then iterates over each of the expectations in a test case. Here, though, these expectations are functions rather than constants, so each expectation function is invoked on L66.<\/p>\n<p>Those expectations come from the list shown in orange right in the middle. This sample test is testing a function that generates HTTP requests. There are a lot of different use cases to test (here you are just seeing one test for the happy path). And for each use case there are a variety of things we need to check, but not expressible by simple constants. So this technique provides a way to test a variable number of data-dependent expectations in a very clear and concise way.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-80055\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/ms2.png\" alt=\"\" width=\"581\" height=\"510\" \/><\/p>\n<p>There are a couple pieces of support code behind this. First, the boilerplate. L16 shows the signature of an individual test function. We&#8217;re essentially passing it two arguments, the HTTP request and the associated possible error. You&#8217;ll see this in action in L66 above. First, in L64 we run the code under test to get the\u00a0<strong>response<\/strong>\u00a0and\u00a0<strong>err<\/strong>\u00a0values. Then we loop through the list of expectations and invoke each one&#8211;which has the signature from L16&#8211;with those arguments. The list of expectations is arguably the most important piece, which is why it is highlighted in L53-56. Note that it is wrapped in L52 by the\u00a0<strong>ckRequest<\/strong>\u00a0function. That is just syntactic sugar to be just a wee bit more concise, as you can see here in L18-20. So L52 could have been <strong>[]ckReqFunc {<\/strong> but that requires 3 lexical tokens (or 4 depending on how you count) vs. just 2 tokens for <strong>ckRequest(<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"379\" height=\"93\" class=\"wp-image-79997\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image28-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(28).png\" \/><\/p>\n<p>And finally, there is the list of things you want to test. These samples are quite simple&#8211;just one-liners. In practice they could be much more elaborate, as needed. But even with just one liners it behooves using this mechanism because we&#8217;re giving a semantically meaningful name to each individual\u00a0<strong>assert<\/strong>\u00a0and\u00a0<strong>require<\/strong>\u00a0here.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" width=\"409\" height=\"274\" class=\"wp-image-79998\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/2018\/07\/c-users-ms-appdata-local-temp-enhtmlclip-image29-1.png\" alt=\"C:\\Users\\ms\\AppData\\Local\\Temp\\enhtmlclip\\Image(29).png\" \/><\/p>\n<p>Kudos to my colleague at Chef Software, Stephan Renatus, for introducing this testing technique into our team\u2019s codebase!<\/p>\n<h2><a id=\"post-79965-_Toc519844662\"><\/a>Summary<\/h2>\n<p>Software development is not black and white. (Which is to say, it is not just ones and zeroes!) There are layers upon abstractions upon principles upon techniques. And personal preference certainly comes into play. This article has presented you with a collection of techniques and approaches to assist you in some of that effort. You may not find everything useful. You may not agree with every approach. But at a minimum it should get you thinking about your testing approach. Unit tests are a but a small part of your realm of responsibility in that regard, but I would argue they provide the foundation upon which much else rests, so creating an extensive and meaningful body of tests is vital to your project&#8217;s success. I provide a list of reference material for further reading below. But a good next step is my previous article on code reviews\u2014it further emphasizes how critical unit tests are, in not just writing code, but in reviewing it. See <a href=\"https:\/\/www.red-gate.com\/simple-talk\/dotnet\/net-framework\/the-zen-of-code-reviews-the-reviewers-tale\/\">The Zen of Code Reviews: The Reviewer&#8217;s Tale<\/a>.<\/p>\n<div class=\"note\">\n<p><em>Final note: Working at Chef Software was my first exposure to working with Go (after working with another couple dozen languages over the years). A big thanks to all my colleagues at Chef for helping bring Go alive for me.<\/em><\/p>\n<\/div>\n<h2><a id=\"post-79965-_Toc519844663\"><\/a>References<\/h2>\n<p>Go Language:<\/p>\n<ul>\n<li><a href=\"https:\/\/golang.org\/pkg\/testing\/\">https:\/\/golang.org\/pkg\/testing\/<\/a><\/li>\n<li><a href=\"https:\/\/golang.org\/cmd\/go\/#hdr-Test_packages\">https:\/\/golang.org\/cmd\/go\/#hdr-Test_packages<\/a><\/li>\n<li><a href=\"https:\/\/golang.org\/cmd\/go\/#hdr-Package_lists\/https:\/\/golang.org\/cmd\/go\/#hdr-Package_lists\/\">https:\/\/golang.org\/cmd\/go\/#hdr-Package_lists<\/a><\/li>\n<li><a href=\"https:\/\/golang.org\/cmd\/go\/#hdr-Testing_flags\">https:\/\/golang.org\/cmd\/go\/#hdr-Testing_flags<\/a><\/li>\n<li><a href=\"https:\/\/golang.org\/cmd\/go\/#hdr-Testing_functions\">https:\/\/golang.org\/cmd\/go\/#hdr-Testing_functions<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/golang\/go\/wiki\/TableDrivenTests\">https:\/\/github.com\/golang\/go\/wiki\/TableDrivenTests<\/a><\/li>\n<\/ul>\n<p>The faker library:<\/p>\n<ul>\n<li><a href=\"https:\/\/hackernoon.com\/how-i-made-a-simplest-and-useful-library-in-golang-by-learning-reflections-work-6192aa7ef8cf\">https:\/\/hackernoon.com\/how-i-made-a-simplest-and-useful-library-in-golang-by-learning-reflections-work-6192aa7ef8cf<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/bxcodec\/faker\">https:\/\/github.com\/bxcodec\/faker<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>In this article, Michael Sorens describes unit testing for applications written in Go. While focused on Go, many of his recommendations and techniques can be applied to other languages as well.&hellip;<\/p>\n","protected":false},"author":221868,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[53,143519],"tags":[95506],"coauthors":[6802],"class_list":["post-79965","post","type-post","status-publish","format-standard","hentry","category-featured","category-testing","tag-automate"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79965","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221868"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=79965"}],"version-history":[{"count":22,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79965\/revisions"}],"predecessor-version":[{"id":80338,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/79965\/revisions\/80338"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=79965"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=79965"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=79965"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=79965"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}