Book Image

Test-Driven Java Development, Second Edition - Second Edition

By : Viktor Farcic, Alex Garcia
Book Image

Test-Driven Java Development, Second Edition - Second Edition

By: Viktor Farcic, Alex Garcia

Overview of this book

Test-driven development (TDD) is a development approach that relies on a test-first procedure that emphasizes writing a test before writing the necessary code, and then refactoring the code to optimize it.The value of performing TDD with Java, one of the longest established programming languages, is to improve the productivity of programmers and the maintainability and performance of code, and develop a deeper understanding of the language and how to employ it effectively. Starting with the basics of TDD and understanding why its adoption is beneficial, this book will take you from the first steps of TDD with Java until you are confident enough to embrace the practice in your day-to-day routine.You'll be guided through setting up tools, frameworks, and the environment you need, and we will dive right into hands-on exercises with the goal of mastering one practice, tool, or framework at a time. You'll learn about the Red-Green-Refactor procedure, how to write unit tests, and how to use them as executable documentation.With this book, you'll also discover how to design simple and easily maintainable code, work with mocks, utilize behavior-driven development, refactor old legacy code, and release a half-finished feature to production with feature toggles.You will finish this book with a deep understanding of the test-driven development methodology and the confidence to apply it to application programming with Java.
Table of Contents (18 chapters)
Title Page
Packt Upsell
Contributors
Preface
9
Refactoring Legacy Code – Making It Young Again
Index

Testing


Even though the main objective of TDD is the approach to code design, tests are still a very important aspect of TDD and we should have a clear understanding of two major groups of techniques, as follows:

  • Black-box testing
  • White-box testing

Black-box testing

Black-box testing (also known as functional testing) treats software under test as a black box without knowing its internals. Tests use software interfaces and try to ensure that they work as expected. As long as the functionality of interfaces remains unchanged, tests should pass even if internals are changed. The tester is aware of what the program should do, but does not have the knowledge of how it does it. Black-box testing is the most commonly used type of testing in traditional organizations that have testers as a separate department, especially when they are not proficient in coding and have difficulties understanding it. This technique provides an external perspective on the software under test.

Some of the advantages of black-box testing are as follows:

  • It is efficient for large segments of code
  • Code access, understanding the code, and ability to code are not required
  • It offers separation between users and developers perspectives

Some of the disadvantages of black-box testing are as follows:

  • It provides limited coverage, since only a fraction of test scenarios is performed
  • It can result in inefficient testing due to tester's lack of knowledge about software internals
  • It can lead to blind coverage, since testers have limited knowledge about the application

If tests are driving the development, they are often done in the form of acceptance criteria that is later used as a definition of what should be developed.

Note

Automated black-box testing relies on some form of automation, such as behavior-driven development (BDD).

White-box testing

White-box testing (also known as clear box testing, glass box testing, transparent box testing, and structural testing) looks inside the software that is being tested and uses that knowledge as part of the testing process. If, for example, an exception should be thrown under certain conditions, a test might want to reproduce those conditions. White-box testing requires internal knowledge of the system and programming skills. It provides an internal perspective on the software under test.

Some of the advantages of white-box testing are as follows:

  • It is efficient in finding errors and problems
  • Required knowledge of internals of the software under test is beneficial for thorough testing
  • It allows finding hidden errors
  • It encourages programmer's introspection
  • It helps in optimizing the code
  • Due to the required internal knowledge of the software, maximum coverage is obtained

Some of the disadvantages of white-box testing are as follows:

  • It might not find unimplemented or missing features
  • It requires high-level knowledge of internals of the software under test
  • It requires code access
  • Tests are often tightly coupled to the implementation details of the production code, causing unwanted test failures when the code is refactored

White-box testing is almost always automated and, in most cases, take the form of unit tests.

Note

When white-box testing is done before the implementation, it takes the form of TDD.

The difference between quality checking and quality assurance

The approach to testing can also be distinguished by looking at the objectives they are trying to accomplish. Those objectives are often split between quality checking (QC) and quality assurance (QA). While QC is focused on defects identification, QA tries to prevent them. QC is product-oriented and intends to make sure that results are as expected. On the other hand, QA is more focused on processes that assure that quality is built-in. It tries to make sure that correct things are done in the correct way.

Note

While QC had a more important role in the past, with the emergence of TDD, acceptance test-driven development (ATDD), and later on BDD, focus has been shifting towards QA.

Better tests

No matter whether one is using black-box, white-box, or both types of testing, the order in which they are written is very important.

Requirements (specifications and user stories) are written before the code that implements them. They come first so they define the code, not the other way around. The same can be said for tests. If they are written after the code is done, in a certain way, that code (and the functionalities it implements) is defining tests. Tests that are defined by an already existing application are biased. They have a tendency to confirm what code does, and not to test whether a client's expectations are met, or that the code is behaving as expected. With manual testing, that is less the case since it is often done by a siloed QC department (even though it's often called QA). They tend to work on test definition in isolation from developers. That in itself leads to bigger problems caused by inevitably poor communication and the police syndrome, where testers are not trying to help the team to write applications with quality built in, but to find faults at the end of the process. The sooner we find problems, the cheaper it is to fix them.

Note

Tests written in the TDD fashion (including its flavors such as ATDD and BDD) are an attempt to develop applications with quality built in from the very start. It's an attempt to avoid having problems in the first place.