Sponsored Link •
|
Summary
Automated tests can make demands on an API that are not made by any other client of the API. For example, you may find yourself wanting to add methods to a class that are not needed by any other, non-test clients. To what extent do you feel automated tests should be allowed change the API being tested?
Advertisement
|
Writing tests can help improve the usability design of an API, because when you write tests, you put on the shoes of a client trying to use your API. The simple act of writing a test can help you see problems with the usability of your API design, which encourages you to improve the design. But tests can also influence API designs in less desirable ways, because tests can make demands on the API that aren't made by any other client. For example, you may find yourself making private methods package access just so you can test them.
I always felt a bit dirty when making changes to an API solely to accomodate tests. I felt that the tests should be testing the API that would exist if there were no tests, because that's the "true" API. That's the API that serves the "real" clients. However, recently I started questioning that attitude. Should I consider tests as first class citizens of the application? Should I see tests as just another client that needs to be served, equal in status to other, non-test clients?
A couple months ago I was writing tests for a Java class called Merger
, which contains a Velocity template name and a context Map
. Instances of this class are returned by the controllers in Artima's new architecture. Merger
s contain a merge
method that renders the named Velocity template with the contained Map
. I was writing tests that verified that the template name and context Map
returned from our controllers were as expected. I first added get
methods that allowed the tests to grab the template name and context Map
. The tests were the only client that needed access to these private fields, so I didn't feel quite right about adding the get methods. But I did it anyway, because I wanted these tests. I soon found myself creating helper methods in the test class for comparing two context Map
s and two template names.
After finding I needed to call the helper methods from a different test class, I started feeling the object-oriented urge to move the helper methods into the Merger
class itself and get rid of the get
methods I had added before. This would move the code that's using Merger
's private data into class Merger
, where the data resides. I struggled with this a while, then finally decided to go ahead and do it. Now there are no get
methods, but there are two verify
methods (formerly the helper methods) in the public API of class Merger
. These verify
methods are called only by tests.
To what extent do you feel automated tests should be allowed change the API being tested? What would you say in a design review of class Merger
?
Have an opinion? Readers have already posted 57 comments about this weblog entry. Why not add yours?
If you'd like to be notified whenever Bill Venners adds a new entry to his weblog, subscribe to his RSS feed.
Bill Venners is president of Artima, Inc., publisher of Artima Developer (www.artima.com). He is author of the book, Inside the Java Virtual Machine, a programmer-oriented survey of the Java platform's architecture and internals. His popular columns in JavaWorld magazine covered Java internals, object-oriented design, and Jini. Active in the Jini Community since its inception, Bill led the Jini Community's ServiceUI project, whose ServiceUI API became the de facto standard way to associate user interfaces to Jini services. Bill is also the lead developer and designer of ScalaTest, an open source testing tool for Scala and Java developers, and coauthor with Martin Odersky and Lex Spoon of the book, Programming in Scala. |
Sponsored Links
|