Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

You Don't Have Enough Tests and You Never Will!

DZone's Guide to

You Don't Have Enough Tests and You Never Will!

You'll never have enough tests to catch everything that could possibly go wrong — but with the right testing strategy and design, you can produce good quality software.

· DevOps Zone
Free Resource

Download the blueprint that can take a company of any maturity level all the way up to enterprise-scale continuous delivery using a combination of Automic Release Automation, Automic’s 20+ years of business automation experience, and the proven tools and practices the company is already leveraging.

Ask any software developer if their app has enough tests and chances are they’ll say no. Often, they’ll feel they have to justify this lack of testing.

Why is this the norm, and what should we do about it?

The Problem of Testing

Software teams are increasingly facing the pressure of having to deliver quality software while still staying ahead of their competition. Release buggy software and users will be quick to switch away — but lack the features your competitors provide and you will have trouble attracting new users.

Buggy software

The traditional view of software testing is that the earlier you can find a bug, the cheaper it is to fix. If a developer finds a bug shortly after writing the code, they can quickly fix it; if the bug is found in production it needs to be diagnosed, fixed and the software re-verified and released which can be an expensive process.

Whether you are performing unit testing, integration testing, or system testing, a balance has to be struck between the cost and the value testing provides.

Unit Testing

Unit testing seeks to break code into small, logical units and then test that functionality in isolation from the rest of the code. It is typically performed by the developer and allows them to verify that their code works as they expect, as well as testing boundary cases which are difficult to produce in later stages of testing.

Many software teams put high importance on writing a lot of unit tests as catching bugs early can save time and money later on. However, these tests are time-consuming to write, often difficult to understand and maintain, and are too low-level to catch logical bugs across the codebase.

Integration Testing

Individual modules of an application can be integrated together and tested as a group - this is integration testing. At this level, whole features can be tested in context and logical bugs discovered. Integration tests can be brittle when the code is refactored and can take a lot of effort to fix. As with unit tests, they are expensive to write and are not necessarily well suited to finding edge cases.

System Testing

System testing is performed once all the software has been written. Its aim is to ensure that the complete system behaves as expected, is usable, stable and secure. This often involves a lot of manual ad-hoc testing alongside automated testing, which makes it difficult to perform consistent testing on every release. This makes it easier for bugs to slip through the cracks.

Striking a Balance

Testing is hard and software is complex. No matter how much testing you do there will always be bugs that find their way into your releases. So, what is the best testing strategy?

A lot of software teams get caught up in trying to measure how much testing is being done; this can lead to unhelpful testing strategies like 100% line coverage in unit testing. Even if good coverage is achieved, you may be testing for the wrong behavior and the tests themselves could be buggy or not actually verifying outcomes as intended.

In order to come up with a useful testing strategy that improves the quality of your code, you first have to answer the question, “What do I want my testing to achieve?” The answer to this question can depend a lot on the context (for example a bug in your self-driving car is a lot more concerning than a bug in a game), but typically the answer is that you want few bugs experienced by the end users and no serious defects that could affect security or integrity.

Self driving car bug

The following are some things you should consider when creating a testing strategy.

Focus on What’s Important

More tests does not necessarily equal fewer bugs, but targeting testing effort in the right places can make a real difference to code quality. Here are some examples of areas where testing can make a difference:

  • Complex logic. Bugs in areas where the logic is very complex or convoluted can be subtle and hard to diagnose, with regressions being hard to spot. These areas should be tested more exhaustively.
  • Publicly accessible interfaces. Ensure that interfaces which can be reached publicly do only what they are intended to do. This includes verifying that requests are appropriately validated to avoid interfaces returning more information than intended or modifying data in unintended ways.
  • High impact code. Focus testing in areas that have the greatest impact on your users. A feature used by a small percentage of users may be less important to test than core functionality.

Design for Damage Control

Ultimately bugs will happen, but when they do you want to control the impact. You can do this at the code level, for example handling exceptions where appropriate, or at the design level, for example using transactions when modifying databases. Thinking about what happens when things go wrong can help reduce the severity of bugs when they do occur.

Monitor Bugs

Once your software is in the wild, how do you know if your testing strategy is working and how can you monitor the experience your users are getting? Error monitoring (such as Bugsnag) allows you to see errors that are occurring and make decisions about what needs to be fixed based on how much of an impact a particular bug is having. You can focus on fixing the edge cases that actually matter in production, which can be difficult to discover during testing.

Monitoring bugs

You can use error monitoring to get an early warning when things are going wrong, which means you can either fix things before they become too disruptive to users or even roll back a release if the impact appears significant.

Bugs in software are inevitable, but being able to get immediate feedback on how your software is performing post-release is a valuable last line of defense in an effective testing strategy.

Final Thoughts

Software is a complicated, collaborative exercise, and trying to produce it with as few defects as possible is time-consuming and costly. You will never have enough tests to catch everything that could possibly go wrong, but with the right testing strategy and design, you will be able to produce good quality software — without being bogged down by writing and maintaining too many tests. Special thanks to Becky Hayling for the illustrations! 

Download the ‘Practical Blueprint to Continuous Delivery’ to learn how Automic Release Automation can help you begin or continue your company’s digital transformation.

Topics:
software testing ,unit testing ,integration testing ,system testing ,devops

Published at DZone with permission of William Starling. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}