3 Test coverage and optimization

 

This chapter covers

  • Measuring test coverage to see what percentage of code is tested.
  • Optimizing for performance using benchmarks and profiling.
  • Parallel testing to reduce test run time and detect data race issues.

We introduced idiomatic package design principles and testing in the last chapter and implemented and tested a package called url using the testing package and the go test tool. In this chapter, we'll measure our package's test coverage to help us identify what we still need to test. Then, we'll improve our code's performance by benchmarking and profiling. Lastly, we'll look into running parallel tests and detecting possible data race issues.

TIP

Idiomatic code is efficient and avoids unnecessary inefficiencies.

3.1 Test coverage

As radar scans for objects within a radius, test coverage examines our code to identify which parts are tested and which are not. Test coverage is a way of cross-checking to see which sections of code our tests are exercising and verifying, or in other words, covering. This section discusses test coverage. We'll measure the test coverage of our url package and see what it means to reach 100% test coverage. We'll then start fixing bugs in our code.

3.1.1 Measuring test coverage

We can measure the test coverage of the url package by using the coverprofile flag:

$ go test ./url -coverprofile cover.out  #A
coverage: 88.9% of statements

3.1.2 Perfect test coverage

3.1.3 100% test coverage != bug-free code

3.2 Benchmarking and optimization

3.2.1 Writing and running benchmarks

3.2.2 Sub-benchmarks

3.2.3 Profiling: chasing out memory allocations

3.2.4 Optimizing the code

3.2.5 Comparing benchmarks

3.3 Compiler optimizations

3.3.1 Inlining and dead-code elimination

3.3.2 The sink variable

3.3.3 A bright new future

3.4 Parallel testing

3.4.1 Running tests in parallel

3.4.2 Running subtests in parallel

3.4.3 Detecting data races

3.5 Exercises

3.6 Summary