Applying a Java Unit Testing Framework
Applying a Java Unit Testing Framework

Most software developers have heard about the benefits of Java unit testing frameworks, and may have implemented unit testing at a previous job; but tight schedules leave little time for such initiatives; and isn't it Quality Assurance's job to identify bugs?

In fact, identifying and correcting bugs as early as possible in the development cycle reduces overall bugs, freeing developers for more creative work. It also improves team cohesion and minimizes the frustration and anxiety common with an endless cycle of bug fixing.

The Cost of Bad Code
From a global business perspective, software bugs are epidemic:

  • According to the Washington D.C. National Institute of Standards and Testing (NIST), software errors cost the U.S. economy $60 billion per year.1
  • The Standish Group estimates that 30 percent of all software projects are cancelled, almost 50 percent are over budget, and 60 percent are considered failures due to software coding errors, bugs and failure to meet deadlines.2
  • The relative cost of maintaining software and managing its evolution now represents more than 90 percent of its total cost.3
What does this mean to Java developers? On a day-to–day level, this data typically manifests itself in quality of life issues such as:
  • Frustration caused by poorly documented code
  • Bugs pouring in from unhappy customers
  • Marketing setting unrealistic release schedules
  • Management demanding better code faster
Bad code often means poor or no documentation, making it difficult to fix and enhance, forcing other developers to spend a great deal of time trying to decipher it. A change to one area of code can easily damage another, resulting in cascading bugs, even worse than before.

It's a well-known fact that the cost of fixing a bug significantly increases the further along in the release cycle it is detected. Doesn't it make sense, then, to implement development methodologies that prevent bugs from being created in the first place? But what are these methodologies, how can they help, and how can they be most successfully applied?

Software Development Trends
Gone are the days when a team of lone developers only gathered at code or design reviews, or at product review meetings. Developers are working in teams now; and a shortage of skilled developers means that any team will have a mix of different skill and experience levels.

Within any development team there are a variety of skill sets, with the least skilled often taking a great deal of everyone else's valuable time.

What's worse, more junior developers can potentially delay or halt the entire project by contributing buggy or poorly tested code.

Many Java teams are turning to agile software development techniques, an iterative and incremental approach to software development that is performed in a highly collaborative manner. One agile software development practice is to test early and often, with the focus on test-driven development, where teams work in short cycles writing tests for a piece of code first, then writing the code to be tested. The key is to write tests before the code, with the objective of getting as close as possible to 100 percent test coverage.4

Unit Testing: What Good Is It?
But why is testing so important during actual code development? Part of the reason goes back to team effort. If all developers practiced unit testing, not only would it improve the entire code set, but it would also simplify maintenance and significantly reduce debug time for the entire team.

However, in real life, almost the only significant metric that is commonly applied to the software development process is whether or not a team is hitting its deadlines. Under pressure to deliver, most developers will focus on getting their code written, and let the Quality Assurance (QA) team uncover any bugs. And there will be bugs. Yet, the purpose of QA is not really intended to be finding bugs. They are responsible for:

  • Functional tests – assures that business requirements have been met
  • Integration tests – confirms that components work well together
  • Acceptance tests – confirms that an application does what the customer expects it to do
Developers should be responsible for testing their code before it goes to QA; which is where unit testing comes in—discovering problems as they are created. A unit test is highly localized. A unit test class only tests within a single package. It does not test the interaction between one package and another. That is the job of functional testing.

Most developers have heard about unit testing and agree that it should be done; but claim that they can never find the time, and that management doesn't consider it a priority. Some developers, faced with tight deadlines, can't comprehend the possibility of starting to introduce unit tests to an existing body of code. Along with documentation, it is the least important item on their list. Testing code is boring, especially when it's someone else's code.

So why should developers change the way they work? Why should they take the time to unit test? For years, unit testing was relegated to the "I know I should be doing it" category; but now it has become an important part of a top-notch Java developer's toolkit. Unit testing gives developers the confidence that their code works and that they can change it at a moments notice, without fearing that it will break.

With the trend toward agile software development, being the best programmer on the team is not enough. Agile software development is not just a fad. Its precepts of teamwork and unit testing have been shown to significantly improve code quality, affording developers more time to write code; and decreasing the time they have to spend struggling to fix or enhance bad code. The bottom line benefit is cost reduction.

Applying a Process Change Template
But how do organizations apply a testing framework to their code base, especially if that code base is extensive? What best practices are available to help them?

The following steps, that provide a template for a quality-driven development process, can be applied to unit testing to provide a manageable path to implementation:

  1. Goals and standards: Identify specific unit testing goals and/or standards
  2. Tools: Facilitate standardizations and data collection with tools
  3. Automation/repeatability: Eliminate the human factor
  4. Measurement: Collect key data from systems/tools
  5. Analytics: Analyze and interpret data to form a feedback loop
  6. Trend Analysis: Tracking trends over time and looking to the future
Organizations may find themselves at any one of these stages without having passed through the previous stage. In many cases, they might have to take a step back in order to progress further.

First, organizations need to identify where they are. Are they using a unit-testing framework? If so, what percentage of code is covered by unit tests, and what is their goal?

To facilitate trend tracking, the highest level of this template approach, each step must be built upon the last. It is not necessary, however, to halt all development in order to implement this template. Organizations with a large installed code base, for example, may want to ensure that all new work is unit tested, so that over time, code coverage steadily increases.

Standards – Level 1
The fundamental rules of unit testing are:

  • Test every line of code
  • When possible, test code in isolation
  • Software must be written with tests in mind
Consequently, the most important standard or goal for unit testing is the code coverage percentage—the percentage of code covered by unit tests relative to the code base's total lines of code. Is it 50 percent, 80 percent or 100 percent? Each development organization needs to establish their goal for this metric.

Another key metric related to unit testing is the pass rate—the unit test pass/fail ratio. Is it important that all unit tests pass? What if 100 percent of unit tests pass, yet these tests only cover 20 percent of the code base? Moving toward 100 percent for both metrics would be a better goal.

Tools – Level 2
Once an organization has defined their code coverage goals, they can implement a testing framework; or they can identify, if they already have such tools in place, their status relative to their goals.

The primary reason for using a testing framework is to make developers' lives easier, by identifying bugs early in the development cycle, when they cost less to fix. These tools do not necessarily have to be standardized across development teams, because some developers may have experience in and prefer using certain products.

Unit Testing Alternatives
There are a few alternatives to unit testing such as inserting statements into the code and using debuggers. But neither of these methods is automated, nor do they test all lines of code.

Inserting debug statements into code is a low-tech debugging method. It usually requires that you scan output manually every time you run the program to ensure that the code is doing what you expect.

Debuggers are used to step through code and inspect that the variables along the way contain the expected values. This is also a manual process that requires tedious visual inspections. Every time you change your program, you must repeat this manual process.

The most popular unit-testing framework is JUnit, written by Erich Gamma and Kent Beck. JUnit is Open Source Software, released under the Common Public License Version 1.0 and hosted on SourceForge. JUnit lets you write and run repeatable tests.

More than any other testing framework, JUnit has helped developers understand the benefits gained from consistent unit testing.

JUnit features include:

  • Assertions for testing expected results
  • Test fixtures for sharing common test data
  • Test suites for easily organizing and running tests
  • Graphical and textual test runners
JUnit is designed to work with many small tests. It executes each test within a separate instance of the test class, reporting success or failure on each test. JUnit is not intended to report on multiple failures per test. If it does, you need to reevaluate your test. It may be that you have written a functional/acceptance/customer test, or that your test is too inclusive.

The intention of a testing framework is to write tests before the code. This is called test-first programming, whereby new code is only written when an automated test fails. Good tests will show how to best design the system for its intended use.

About Java News Desk
JDJ News Desk monitors the world of Java to present IT professionals with updates on technology advances, business trends, new products and standards in the Java and i-technology space.

In order to post a comment you need to be registered and logged in.

Register | Sign-in

Reader Feedback: Page 1 of 1