Previously, we talked about the importance of code quality culture for yourself as an individual developer and for engineering teams. Code coverage is an essential part of building that culture of quality. Before we dig deeper into quality culture, we want to take a moment to step back and look at the basics. This is our perspective of code testing and coverage and why we believe it is important.
What is Testing?
No discussion of code coverage can begin without a discussion of what testing is and why tests are important to your ongoing workflow.
Conceptually, tests are fairly self explanatory. Regardless of the kinds of tests you’re performing (e.g., unit testing, end-to-end testing, regression testing), You are fundamentally working to ensure that your code behaves how you expect it to behave. For example, if a developer writes a function, a unit test seeks to determine whether the outcome of the function is what the developer intended. Typically this is achieved by creating inputs for the function and seeing whether the expected output occurs. If the expected output is confirmed, then the function has passed the unit test.
Testing is important because when code is functioning as expected (i.e., the tests are passing), the focus is not on the code itself, but on whether or not the code solves the problem for which it was written. The engineer can move beyond worrying about the correctness of individual lines of code to instead focusing on how those lines of code affect the product.
In addition, good tests will also let developers know when changes break particular code flows. For example if a change is made that causes the output of a function to change, a unit test failure will bring that change to the attention of the developer. This means that developers aren’t waiting for things to break in the product before addressing certain issues. Instead, those issues can be identified and fixed early, leading to a better experience for end users.
What is Code Coverage?
While tests won’t necessarily ensure a good product on their own, they contribute in vital ways. Because of this, having eyes on your tests at all times is incredibly beneficial for ensuring a quality codebase. However, as a codebase scales to hundred and thousands of lines of code, keeping eyes on each individual test to ensure that they are all passing becomes difficult and time consuming.
Rather than checking each line manually, code coverage is intended to programatically look at all the tests being run and provide an easy to digest metric regarding what percentage of lines are covered by tests.
By tracking and understanding a project’s test coverage, developers and teams are able to see where the gaps in test coverage are in order to prevent issues from arising in the future. Stated differently, the only way to tell if code uncovered by a test is broken is to run into the bug created as a result while using the product. Thus, by pushing for high coverage rates, an engineering team can reduce the chance that bugs will appear in the future.
Code coverage can also make it easier to judge the quality of code moving forward. Coverage metrics and unit tests cannot replace subjective methods for measuring quality such as code review. Instead, tests can provide a level of confidence that code which was previously reviewed is stable, so that when reviewing new code, the purpose of functions already in place is known and there is a reasonable amount of certainty that those functions are acting as intended.
We believe that great products begin with solid code. Ensuring that each line of code is acting as intended is essential to determining the quality of code. Our goal then, is to further the cause of quality code and the great products powered by quality code through providing the best possible code coverage metrics for a given repository.
Every pull request affects the overall code coverage by adding new logic and modifying previous work. By providing a view of not only the effect of new code on the full codebase, but also the effect of individual, incremental changes, we can provide deeper insight into how testing and, ultimately, each covered line of code is performing. This allows for identifying potential problems quickly and solving them early.
Ultimately, the better insights we can give to developers on how their functions are performing, the more we can empower them to focus their attention on creating world changing products.
To learn more about our best in class code coverage solution, click here.