A Few Signs That Your Project May Be In Some Serious Trouble

  1. Lack of leadership in developer operations
  2. A lack of reporting of improvements in code reuse, coverage, test cases, and stability.
  3. Underutilization of frameworks and libraries used within the project.
  4. Lack of disposable runtime environments [for development and testing].
  5. Build times are unknown.
  6. Long and detailed documentation is required to build your product.
  7. Dead code is left in the code base to rot for years.
  8. Bugs are being reproduced as unit tests.
  9. Third Party dependencies are not being upgraded.
  10. Code is badly organized. Models are placed anywhere, packages aren’t organized, etc.

The Pitfalls of Testing

For the most part, testing is a great thing that is a surefire way to improve software quality. However, I’ve found that there can be three minor pitfalls when it comes to testing. I’m sure there are more, but these are the ones that I’ve experienced.

When running the tests, your current runtime environment is based off the testing class path. This means that when you are using refactoring, the classes that the test cases are contained within can appear to be valid packages within your application. For example, when recursively searching for a listing of classes by using reflection, the test classes will show up. This is an important thing to note, and to remove the test classes in your cases, when you’re confirming the results of this process. In addition, it is possible to use reflection to see and initiate test cases from the application logic, something that should not be a valid operation in unit testing. For example: If you had a Factory class to initiate only the classes within your JAR file, you could pass in a reference to a test class, and it would initiate it. This would produce undesired behavior.

IDEs consider test cases to be a usage of code. This makes it more difficult to spot dead code in your project. Dead code slows down production time, tends to be non-conforming with the current code base/philosophy, and may be used by an ill-informed developer later.

As of the current JUnit version (4.11), there is no way to disable a test and have a warning created for this state. The only two options for this are to let the unused test case fail intentionally, or to use the ignore annotation. Intentional test case breakages performed by an intentional fail method within the test case, or leaving the functionality broken. Unfinished test cases [which would warrant this situation], should not be left blank, they will show up as a passed test case. Empty test cases should be shown as an error, but are not. This StackOverflow question discusses the Ignore annotation more; however using @Ignore leaves unused test cases, which the developer is responsible for keeping up with. Having a broken test case inflates the failed test case count, and may cause valid test failures to be overlooked.

Review: “Test-Driven Development” by Kent Beck [The creator of JUnit]

It is always interesting to read a book about a technical topic from its creator. They tend to better identify the motivating factors and history that went into creating the product than other authors could possibly try. Kent Beck is the creator of JUnit, and happens to be the author of this book. The book is designed for people who are new to unit testing and Test-Driven Development. For anyone in the current software development industry, this is very few people.

The book is divided into three separate sections. The first being a walk-through with JUnit (by example), xUnit, and then a “best practices guide.” The JUnit section, the majority of the content of this book, is focused on developing a currency class. While there were some interesting design decisions, this part irritated me the most. The first section produced blatant errors, just to create a test that would fail. I would have preferred if these errors had been described rather than presented to the reader. The currency example was a good example, however adding another example would have been better. The xUnit section of the book focused on creating a test environment for Python. I am not a Python developer, but I have written a very small amount of code. I was not a fan of this section. However, I was pleased with the best practices section. The only issue I had with the last section is that I do not recall that the best practices section went into why the recommendations are better than what they replace. If my memory serves me correctly, it did not.

This is a great resource for developers who have never heard of TDD. It may even be a great book for students that have just completed half of a class in Java. However, it is not such a great book for people who have worked with Test Driven Development.  For those who have already worked with TDD, a Manning Press’s “In Action” series may be more suitable. Although their resource on JUnit looks to be a bit dated. Manning Press’s dated JUnit book includes information on integrations with other frameworks, which are slightly harder to test against [J2EE, XML, Servlets, EJB, DBs….].

In summary, I was probably looking for another book similar to “Pragmatic Unit Testing in Java with JUnit” (Hunt and Davis). Their approach was more focused on how to try to find trouble spots, and improve existing code.

Given that this was written in 2002, the following is not exactly fair criticism, but it should be mentioned by anyone that is claiming that TDD is beneficial. I would have liked to see more support [research/studies] on why Test Driven Development is beneficial. Every TDD-related article/publication/book that I have read always attempts to convince the reader that it’s necessarily with marketing-speak. The claim is that it is good for “high stress environments,” or it reduces defects. However, I have never seen evidence supporting the claim mentioned. I, personally, have found that TDD to be a significant improvement in development. However, I have never been able to quantify how much of an improvement it has made. What is the amount of time saved by TDD? Has it made today’s software more reliable than before? Has it affected the developer job market? [Increased/Decreased] Has it made the users of the products using TDD happier? Most importantly, has test-driven development reduced the stress of software development?