6 Test quality

 

This chapter covers

  • Measuring test coverage
  • Writing testable code
  • Investigating test-driven and behavior-driven development
  • Introducing mutation testing
  • Testing in the development cycle

I don’t think anybody tests enough of anything.

--James Gosling

In the previous chapters, we introduced testing software, began to explore testing with JUnit, and presented different test methodologies. Now that you are writing test cases, it is time to measure how good these tests are by using a test-coverage tool to report what code is executed by the tests and what code is not. This chapter will also discuss how to write code that is easy to test and finish by taking a first look at test-driven development (TDD).

6.1 Measuring test coverage

Writing unit tests gives you the confidence to change and refactor an application. As you make changes, you run tests, which give you immediate feedback about new features under test and whether changes break the existing tests. The issue is that these changes may still break untested functionality.

To resolve this issue, you need to know precisely what code runs when you or the build invoke tests. Ideally, your tests should cover 100% of your application code. This section examines test coverage in detail.

6.1.1 Introduction to test coverage

6.1.2 Tools for measuring code coverage

6.2 Writing testable code

6.2.1 Understanding that public APIs are contracts

6.2.2 Reducing dependencies

6.2.3 Creating simple constructors

6.2.4 Following the Law of Demeter (Principle of Least Knowledge)

6.2.5 Avoiding hidden dependencies and global state

6.2.6 Favoring generic methods

6.2.7 Favoring composition over inheritance