Unit tests

The scope of unit testing is to test individual modules (classes/functions) of the service. These are generally supported by a variety of frameworks (most of which are language-specific). Golang has a very powerful, in-built testing framework, as we saw in Chapter 1, Building Big with Go. Also, even though it is a strongly-typed language, packages such as reflect (reflect.DeepEqual) allow one to do a deep comparison of arbitrary data, such as expected versus got.

The units tests need two accompanying frameworks:

  • Mock/Stub: When testing a specific module, we need other downstream-dependent components to fulfill behavior. Sometimes calling the live component may not be possible (sending an email via a live email service may not be an option, as we want to avoid annoying customers with spam). We should either mock or stub out the dependent modules so that we can exercise the code through various interesting paths. There is a subtle difference between mocks and stubs: mocks generally take a specification of what output to generate based on specific input. Stubs, on the other hand, are just canned answers. In the case of Golang, we saw in Chapter 2, Packaging Code, these can be done via service mocks or build flags. Another way to do it is using the go-mock package (https://github.com/golang/mock_). This package inspects source code and generates mock implementations for them.
  • Automation: These should be automated so that they can be run on every commit, thereby solving bugs at the earliest possible stage. The Golang testing package (https://golang.org/pkg/testing/) provides comprehensive support for automated tests.

Your unit tests should run very fast. On normal developer machines, you can easily run thousands of unit tests within a few minutes. It is important to keep each test focused on small pieces of code, running in isolation.

Test-driven development (TDD) encourages taking this to the next level by writing unit tests even before writing code. The UTs guide the developer on what is missing during the development sprints.

A common issue with unit tests is they are tightly coupled to the implementation of the tested function that is implemented. This means that slight changes in the code need changes in the unit tests. The behavior-driven development (BDD) test tries to address this problem by focusing tests on behavior rather than implementation. BDD tests are written in a domain-specific language (DSL), which is more of the English prose style than other types of tests. GoConvey (http://goconvey.co/) is an excellent package for Go-based BDD tests. It builds on Go's native testing and coverage frameworks and adds a new layer of expressive DSL to write tests cases. It also has a UI for a better visualization of test results:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset