20% more bugs? Or 20% less features? 185
People often make the argument that time to market is more important that quality. I’m not sure just what they mean by that. Do they mean that it’s ok if 20% of the features don’t work so long as they deliver quickly? If so, that’s just stupid. Why not develop 20% fewer features, and develop them well. It seems to me that choosing which 20% you are not going to develop and then choosing to develop the other 80% to a high standard of quality is a better management decision than telling the developers to work sloppily.
Developer Certification WTF? 546
Watch the following video. It will convince you that we have to do something about the horrible state of software engineering.
Bad Code from unclebob on Vimeo.
How could any team of disciplined professionals have produced a wretched mess like that? Clearly they were ignorant of good practices. Clearly they were inexperienced novices. Clearly their priorities and values were all wrong. If only they had been taught good coding practices, and good development skills. If only we could have gotten to them before they made such a horrible mess.
What we need to do is create a certification program that provides developers with the knowledge and skills that they need. This program will involve a course that teaches good development practice, and a certification that they are now knowledgeable developers. They can use that certification to prove to their employers and their fellow professionals that they are worthy of being considered true and clean software developers.
That’s what we need. Right?....
Eagle’s Entrails! Deer Droppings! and Elephant Phlatulence!
I’m sorry, am I being vague? Is my opinion not clear enough? All right then, allow me to elaborate.
What Problem does Certification solve?
Certainly there are certification organizations who have the problem of dwindling revenues. A new developer certification program would likely solve their problem.
And just as certainly there are tin-men who need hearts, lions who need courage, scarecrows who need brains, and developers who need self-esteem. A new developer certification program might just help those lackluster developers.
But who else is served by a developer certification program? Employers?
The Trials of Hercules.
Consider Doctors and Lawyers. When a medical student earns an M.D., or a law student passes the Bar, that’s an achievement. The certification, in those cases is deeply meaningful because the certification is not easily won. To get it you have to spend many years, and many tens of thousands of dollars. What’s more, you have to acquire in-depth knowledge and at least a modicum of provable skill. You have to do something significant.
If we had a developer certification like that, then employers might find it useful. But I know of no developer certification program (except for one that I’ll mention later) that offers proof that the developer has accomplished anything of significance. Most certification programs prove little more than that the “developer” paid to attend a 3-5 day course. As an employer, I’m not particularly interested in the ability of a developer to pay to attend a 3-5 day course. As an employer I want to know what the developer can do.
Michaelangelo’s Apprentice.
If you were hiring a guitarist for your band, you might be very impressed with someone who toured with Clapton. You don’t get to tour with Clapton unless you are talented. But more than just talented, you have to show up every day, you have to work well with others, you have to be willing to get the job done under pressure. Clapton doesn’t work with slouches!
A signed letter of recommendation from Clapton is a certification of significance! Not just anyone can get one of those. That letter will impress potential employers forever after.
As an employer, I want to hire people who have succeeded at working with others in the past. The more I trust those others, the better! No developer certification program that I know of (except for one that I’ll mention later) provides that kind of credible reference.
Over-promise and Under-deliver.
The certification programs that I know of (except for one that I’ll mention later) make implicit promises that they can’t hope to begin to deliver. The implied promise is that the certificant has been shown to have some significant skill, ability, or knowledge. The reality is that you have to look at the word “significant” through the wrong end of some very powerful binoculars before it matches the truth. Indeed, there are certification programs that show absolutely nothing about the certificant except that they bought a seat in a class.
Notice that I said that the promises were implicit. That’s the whole key to making lightweight certifications profitable. The goal is to imply that the benefits of certification are so huge that people will pay to get the certification. Often that implication can be as simple and subtle as the choice of words used to name the certification.
Consider, for example, the title of “Certified Development Chief” imprinted on the certificate of someone who just took a “Development Chief” course. Who wouldn’t want to be a Certified Development Chief? And if you aren’t a Certified Development Chief, then what kind of Development Chief are you?
A course, a card, and a Bridge to sell.
What significant accomplishment can a developer make by paying to attend (or even actually attending) an 3-5 day course? How credible a recommendation about any of the 20-odd students could an instructor of such a course make? I can answer both questions in two words, with apologies to SNL. “Jack” and “Cheese”. The accomplishment is miniscule, and the recommendation is meaningless.
So as an employer of developers I think you can take your course and card and show it to some other sucker. It don’t impress me much. Go away and come back later when you’ve accomplished the trials of Hercules and apprenticed under Michaelangelo. And make sure you bring letters of reference. NEXT!
The one I said I’d mention later.
I’ve got an idea for a certification program that just might work. Now, bear with me because this is a little complicated. It’s an idea so revolutionary, so different, so incredibly new that I’m getting giddy just thinking about it.
What if we asked young graduates to actually get jobs as “interns” for awhile. What if we gave out responsibility to them in small incremental measures. What if they gradually learned more and more things while working for us. What if we guided them to ever greater accomplishments. What if we slowly gave them trials of Hercules to follows, and had them work with Michaelangelos.
Of course some of our people might leave and go to greener pastures. We’ll need to replace them. Also, our company might succeed and grow, so we’ll need to hire more good developers. So what if we…
OK, now hold on to your hat because this is where it gets really tricky. You might want to get up and walk around a bit, get a diet coke, eat a twinkie, or something to get your brain working.
Ready? OK, here we go…
So what if we… interviewed ... candidate developers? What if we asked them what accomplishments they’d achieved in previous employment. What if we asked them who they used to work with. And… ok, this is even wilder ... what if we called those references and checked them out?
Are you still with me?
What if we….
Naaaaahhhhh. Dumb idea.
Honestly, I think I’ve wasted your time. It’s a stupid idea. Never mind. We should all just go get certified instead.
Software on the Cheap 261
When it comes to software, you get what you pay for.
Have you ever stopped to wonder how much a line of code costs? It ought to be easy to figure out.
In the last 14 months, I have written about 20KSLOC in FitNesse. Of course that was part time. My real job is running Object Mentor, consulting, teaching, mentoring, writing, and a whole load of other things. Programming takes up perhaps 15% of my time.
On the other hand most programmers have lots of other things to do. They go to meetings, and then they go to more meetings. When they are done with those meetings, they go to meetings. And then there are the meetings to go to. Oh yeah, and then there’s all the fiddling around with time accounting tools, and horrific source code control systems that perform like a salamander crawling through frozen mud.
So, maybe 15% isn’t such a bad ratio.
The loaded rate (Salary plus everything else) for a typical programmer is on the order of $200K. (I know that sounds like a lot, but you can look it up.) So $200K / (20KSLOC / 14mo * 12mo) = $11.66/SLOC.
Let’s look at one of those lines: StringBuffer nameBuffer = new StringBuffer();
Does that look like $11.66 to you? Would you pay that much for it? Well, don’t answer yet, because for each StringBuffer
line you buy, you get import java.lang.StringBuffer;
absolutely free!
Some factories pay their employees a “piece rate”. Would you accept $11.66 per line of code instead of a salary? Of course it couldn’t just be any old line of code. It’d have to be tested!
Hey, I bet all programmers would do TDD if we paid them a piece rate!
Down to business.
The point of that silly analysis was to demonstrate that software is expensive. Even the dumbest little app will likely require more than 1,000 lines of code; and that means it could cost $12K to write!
Imagine that you aren’t a programmer, but you have a clever idea for a new website that’ll make you a zillion dollars. You’ve storyboarded it all out. You’ve worked out all the details. Now all you need is some high-school kid to zip out the code for you. Right? Hell, you could pay him minimum wage! The little twerp would be happy to get it!
That tragic comedy is altogether too common. Too many people have borrowed money against their father’s retirement account to fund a terrible implementation of a good idea. Appalled at how much the reputable firms charge per hour ($100 or more) they go looking for a cheap solution.
“After all, this software is simple.” Or so the reasoning goes. “It’s not like we’re trying to send a rocket to the moon or anything. And, besides, those expensive guys were just out to cheat us. Software just isn’t that hard to write.” Uh huh.
So the poor schmuck finds some freshman in college, or maybe a bored housewife who read a book on HTML last year and created a cute website to show off her kittens. Have these programmers heard about TDD? Have they heard about Design Patterns? Principles? How about source code control?
Clearly they haven’t. They’re going to sling a bunch of horrific code together, without any tests, versioning, or control. The project will start well, with exciting initial results. But then it will slowly grind to a halt, while the cash continues out the door unabated.
In the end the website isn’t going to get built (and the poor schmuck’s father won’t be retiring as soon as he thought). It will be a disaster that will either be terminated, or will require double or triple the investment to get right.
The Bottom Line.
The bottom line is that, when it comes to software, you get what you pay for. If you want good software done well, then you are going to pay for it, and it will probably cost you $12/line or more. And, believe me, that’s the cheapest way to get your software done.
If you go out hunting for the cheap solution, then you’re going to end up paying more, and losing time. Software is one of those things that costs a fortune to write well, and double that to write poorly. If you go for cheap, you’re going to pay double; and maybe even triple.
Mocking Mocking and Testing Outcomes. 379
The number of mocking frameworks has proliferated in recent years. This pleases me because it is a symptom that testing in general, and TDD in particular, have become prevalent enough to support a rich panoply of third-party products.
On the other hand, all frameworks carry a disease with them that I call The Mount Everest Syndrome: “I use it because it’s there.” The more mocking frameworks that appear, the more I see them enthusiastically used. Yet the prolific use of mocking frameworks is a rather serious design smell…
Lately I have seen several books and articles that present TDD through the lens of a mocking framework. If you were a newbie to TDD, these writings might give you the idea that TDD was defined by the use of mocking tools, rather than by the disciplines of TDD.
So when should use use a mocking framework? The answer is the same for any other framework. You use a framework only when that framework will give you a significant advantage.
Why so austere? Why shouldn’t you use frameworks “just because they are there”? Because frameworks always come with a cost. They must be learned by the author, and by all the readers. They become part of the configuration and have to be maintained. They must be tracked from version to version. But perhaps the most significant reason is that once you have a hammer, everything starts to look like a nail. The framework will put you into a constraining mindset that prevents you from seeing other, better solutions.
Consider, for example, this lovely bit of code that I’ve been reviewing recently. It uses the Moq framework to initialize a test double:
var vehicleMock = Mocks.Create<IClientVehicle>()
.WithPersistentKey()
.WithLogicalKey().WithLogicalName()
.WithRentalSessionManager(rsm =>
{
var rs = Mocks.Create<IRentalSession>();
rsm.Setup(o => o.GetCurrentSession()).Returns(rs.Object);
rsm.Setup(o =>
o.GetLogicalKeyOfSessionMember(It.IsAny<string>(),
It.IsAny<int>())).Returns("Rental");
})
.AddVehicleMember<IRoadFactory>()
.AddVehicleMember<IRoadItemFactory>(rf => rf.Setup(t =>
t.CreateItems(It.IsAny<IRoad>())).Returns(pac))
.AddVehicleMember<ILegacyCorporateRental>()
.AddVehicleMember<IRentalStation>(
m => m.Setup(k => k.Facility.FacilityID).Returns(0))
.AddVehicleMember<IRoadManager>(m=>
m.Setup(k=>k.GetRoundedBalanceDue(25,It.IsAny<IRoad>())).Returns(25));
Some of you might think I’m setting up a straw-man. I’m not. I realize that bad code can be written in any language or framework, and that you can’t blame the language or framework for bad code.
The point I am making is that code like this was the way that all unit tests in this application were written. The team was new to TDD, and they got hold of a tool, and perhaps read a book or article, and decided that TDD was done by using a mocking tool. This team is not the first team I’ve seen who have fallen into this trap. In fact, I think that the TDD industry as a whole has fallen into this trap to one degree or another.
Now don’t get me wrong. I like mocking tools. I use them in Ruby, Java, and .Net. I think they provide a convenient way to make test-doubles in situations where more direct means are difficult.
For example, I recently wrote the following unit test in FitNesse using the Mockito framework.
@Before
public void setUp() {
manager = mock(GSSManager.class);
properties = new Properties();
}
@Test
public void credentialsShouldBeNullIfNoServiceName() throws Exception {
NegotiateAuthenticator authenticator =
new NegotiateAuthenticator(manager, properties);
assertNull(authenticator.getServerCredentials());
verify(manager, never()).createName(
anyString(), (Oid) anyObject(), (Oid) anyObject());
}
The first line in the setUp
function is lovely. It’s kind of hard to get prettier than that. Anybody reading it understands that manager
will be a mock of the GSSManager
class.
It’s not too hard to understand the test itself. Apparently we are happy to have the manager
be a dummy object with the constraint that createName
is never called by NegotiateAuthenticator
. The anyString()
and anyObject()
calls are pretty self explanatory.
On the other hand, I wish I could have said this:
assertTrue(manager.createNameWasNotCalled());
That statement does not require my poor readers to understand anything about Mockito. Of course it does require me to hand-roll a manager mock. Would that be hard? Let’s try.
First I need to create a dummy.
private class MockGSSManager extends GSSManager {
public Oid[] getMechs() {
return new Oid[0];
}
public Oid[] getNamesForMech(Oid oid) throws GSSException {
return new Oid[0];
}
public Oid[] getMechsForName(Oid oid) {
return new Oid[0];
}
public GSSName createName(String s, Oid oid) throws GSSException {
return null;
}
public GSSName createName(byte[] bytes, Oid oid) throws GSSException {
return null;
}
public GSSName createName(String s, Oid oid, Oid oid1) throws GSSException {
return null;
}
public GSSName createName(byte[] bytes, Oid oid, Oid oid1) throws GSSException {
return null;
}
public GSSCredential createCredential(int i) throws GSSException {
return null;
}
public GSSCredential createCredential(GSSName gssName, int i, Oid oid, int i1) throws GSSException {
return null;
}
public GSSCredential createCredential(GSSName gssName, int i, Oid[] oids, int i1) throws GSSException {
return null;
}
public GSSContext createContext(GSSName gssName, Oid oid, GSSCredential gssCredential, int i) throws GSSException {
return null;
}
public GSSContext createContext(GSSCredential gssCredential) throws GSSException {
return null;
}
public GSSContext createContext(byte[] bytes) throws GSSException {
return null;
}
public void addProviderAtFront(Provider provider, Oid oid) throws GSSException {
}
public void addProviderAtEnd(Provider provider, Oid oid) throws GSSException {
}
}
“Oh, ick!” you say. Yes, I agree it’s a lot of code. On the other hand, it took me just a single keystroke on my IDE to generate all those dummy methods. (In IntelliJ it was simply command-I to implement all unimplemented methods.) So it wasn’t particularly hard. And, of course, I can put this code somewhere where nobody had to look at it unless they want to. It has the advantage that anybody who knows Java can understand it, and can look right at the methods to see what they are returning. No “special” knowledge of the mocking framework is necessary.
Next, let’s’ make a test double that does precisely what this test needs.
private class GSSManagerSpy extends MockGSSManager {
public boolean createNameWasCalled;
public GSSName createName(String s, Oid oid) throws GSSException {
createNameWasCalled = true;
return null;
}
}
Well, that just wasn’t that hard. It’s really easy to understand too. Now, let’s rewrite the test.
@Test
public void credentialsShouldBeNullIfNoServiceNameWithHandRolledMocks() throws Exception {
NegotiateAuthenticator authenticator = new NegotiateAuthenticator(managerSpy, properties);
assertNull(authenticator.getServerCredentials());
assertFalse(managerSpy.createNameWasCalled);
}
Well, that test is just a load easier to read than verify(manager, never()).createName(anyString(), (Oid) anyObject(), (Oid) anyObject());
.
“But Uncle Bob!” I hear you say. “That scenario is too simple. What if there were lots of dependencies and things…” I’m glad you asked that question, because the very next test is just such a situation.
@Test
public void credentialsShouldBeNonNullIfServiceNamePresent() throws Exception {
properties.setProperty("NegotiateAuthenticator.serviceName", "service");
properties.setProperty("NegotiateAuthenticator.serviceNameType", "1.1");
properties.setProperty("NegotiateAuthenticator.mechanism", "1.2");
GSSName gssName = mock(GSSName.class);
GSSCredential gssCredential = mock(GSSCredential.class);
when(manager.createName(anyString(), (Oid) anyObject(), (Oid) anyObject())).thenReturn(gssName);
when(manager.createCredential((GSSName) anyObject(), anyInt(), (Oid) anyObject(), anyInt())).thenReturn(gssCredential);
NegotiateAuthenticator authenticator = new NegotiateAuthenticator(manager, properties);
Oid serviceNameType = authenticator.getServiceNameType();
Oid mechanism = authenticator.getMechanism();
verify(manager).createName("service", serviceNameType, mechanism);
assertEquals("1.1", serviceNameType.toString());
assertEquals("1.2", mechanism.toString());
verify(manager).createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, mechanism, GSSCredential.ACCEPT_ONLY);
assertEquals(gssCredential, authenticator.getServerCredentials());
}
Now I’ve got three test doubles that interact with each other; and I am verifying that the code under test is manipulating them all correctly. I could create hand-rolled test doubles for this; but the wiring between them would be scattered in the various test-double derivatives. I’d also have to write a significant number of accessors to get the values of the arguments to createName
and createCredential
. In short, the hand-rolled test-double code would be harder to understand than the Mockito code. The Mockito code puts the whole story in one simple test method rather than scattering it hither and yon in a plethora of little derivatives.
What’s more, since it’s clear that I should use a mocking framework for this test, I think I should be consistent and use if for all the tests in this file. So the hand-rolled MockGSSManager
and ManagerSpy
are history.
“But Uncle Bob, aren’t we always going to have dependencies like that? So aren’t we always going to have to use a mocking framework?”
That, my dear reader, is the real point of this blog. The answer to that salient questions is a profound: “No!“
Why did I have to use Mockito for these tests? Because the number of objects in play was large. The module under test (NegotiateAuthenticator
) used GSSName
, GSSCredential
, and GSSManager
. In other words the coupling between the module under test and the test itself was high. (I see lightbulbs above some of your heads.) That’s right, boys and girls, we don’t want coupling to be high!
It is the high coupling between modules and tests that creates the need for a mocking framework. This high coupling is also the cause of the dreaded “Fragile Test” problem. How many tests break when you change a module? If the number is high, then the coupling between your modules and tests in high. Therefore, I conclude that those systems that make prolific use of mocking frameworks are likely to suffer from fragile tests.
Of the 277 unit test files in FitNesse, only 11 use Mockito. The reason for small number is two-fold. First, we test outcomes more often than we test mechanisms. That means we test how a small group of classes behaves, rather than testing the dance of method calls between those classes. The second reason is that our test doubles have no middle class. They are either very simple stubs and spies or they are moderately complex fakes.
Testing outcomes is a traditional decoupling technique. The test doesn’t care how the end result is calculated, so long as the end result is correct. There may be a dance of several method calls between a few different objects; but the test is oblivious since it only checks the answer. Therefore the tests are not strongly coupled to the solution and are not fragile.
Keeping middle-class test doubles (i.e. Mocks) to a minimum is another way of decoupling. Mocks, by their very nature, are coupled to mechanisms instead of outcomes. Mocks, or the setup code that builds them, have deep knowledge of the inner workings of several different classes. That knowledge is the very definition of high-coupling.
What is a “moderately complex fake” and why does it help to reduce coupling? One example within FitNesse is MockSocket
. (The name of this class is historical. Nowadays it should be called FakeSocket
.) This class derives from Socket
and implements all its methods either to remember what was sent to the socket, or to allow a user to read some canned data. This is a “fake” because it simulates the behavior of a socket. It is not a mock because it has no coupling to any mechanisms. You don’t ask it whether it succeeded or failed, you ask it to send or recieve a string. This allows our unit tests to test outcomes rather than mechanisms.
The moral of this story is that the point at which you start to really need a mocking framework is the very point at which the coupling between your tests and code is getting too high. There are times when you can’t avoid this coupling, and those are the times when mocking frameworks really pay off. However, you should strive to keep the coupling between your code and tests low enough that you don’t need to use the mocking framework very often.
You do this by testing outcomes instead of mechanisms.
Dependency Injection Inversion 1812
Dependency Injection is all the rage. There are several frameworks that will help you inject dependencies into your system. Some use XML (God help us) to specify those dependencies. Others use simple statements in code. In either case, the goal of these frameworks is to help you create instances without having to resort to new
or Factories.
I think these frameworks are great tools. But I also think you should carefully restrict how and where you use them.
Consider, for example, this simple example using Google’s Guice framework.
public class BillingApplication {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BillingModule());
BillingService billingService = injector.getInstance(BillingService.class);
billingService.processCharge(2034, "Bob");
}
}
My goal is to create an instance of BillingService
. To do this, I first get an Injector
from Guice. Then I use the injector
to get an instance of my BillingService
class. What’s so great about this? Well, take a look at the constructor of the BillingService
class.
class BillingService {
private CreditCardProcessor processor;
private TransactionLog transactionLog;
@Inject
BillingService(CreditCardProcessor processor, TransactionLog transactionLog) {
this.processor = processor;
this.transactionLog = transactionLog;
}
public void processCharge(int amount, String id) {
boolean approval = processor.approve(amount, id);
transactionLog.log(
String.format("Transaction by %s for %d %s",
id, amount, approvalCode(approval)));
}
private String approvalCode(boolean approval) {
return approval?"approved":"denied";
}
}
Oh ho! The BillingService
constructor requires two arguments! A CreditCardProcessor
and a TransactionLog
. How was the main
program able to create an instance of BillingService
without those two arguments? That’s the magic of Guice (and of all Dependency Injection frameworks). Guice knows that the BillingService
needs those two arguments, and it knows how to create them. Did you see that funky @Inject
attribute above the constructor? That’s how it got connected into Guice.
And here’s the magic module that tells Guice how to create the arguments for the BillingService
public class BillingModule extends AbstractModule {
protected void configure() {
bind(TransactionLog.class).to(DatabaseTransactionLog.class);
bind(CreditCardProcessor.class).to(MyCreditCardProcessor.class);
}
}
Clever these Google-folk! The two bind
functions tell Guice that whenever we need an instance of a TransactionLog
it should use an instance of DatabaseTransactionLog
. Whenever it needs a CreditCardProcessor
it should use an instance of MyCreditCardProcessor
.
Isn’t that cool! Now you don’t have to build factories. You don’t have to use new
. You just tell Guice how to map interfaces to implementations, and which constructors to inject those implementations in to, and then call Injector.getInstance(SomeClass.class);
and voila! You have your instance automatically constructed for you. Cool.
Well, yes it’s cool. On the other hand, consider this code:
public class BillingApplicationNoGuice {
public static void main(String[] args) {
CreditCardProcessor cp = new MyCreditCardProcessor();
TransactionLog tl = new DatabaseTransactionLog();
BillingService bs = new BillingService(cp, tl);
bs.processCharge(9000, "Bob");
}
}
Why is this worse? It seems to me it’s better.
But Uncle Bob, you’ve violated DIP by creating concrete instances!
True, but you have to mention concrete instances somewhere. main
seems like a perfectly good place for that. Indeed, it seems better than hiding the concrete references in BillingModule
.
I don’t want a bunch of secret modules with bind
calls scattered all around my code. I don’t want to have to hunt for the particular bind
call for the Zapple
interface when I’m looking at some module. I want to know where all the instances are created.
But Uncle Bob, You’d know where they are because this is a Guice application.
I don’t want to write a Guice application. Guice is a framework, and I don’t want framework code smeared all through my application. I want to keep frameworks nicely decoupled and at arms-length from the main body of my code. I don’t want to have @Inject
attributes everywhere and bind
calls hidden under rocks.
But Uncle Bob, What if I want to get an instance of BillingService
from deep in the bowels of my application? With Guice I can just say injector.getInstance(BillingService.class);
.
True, but I don’t want to have createInstance
calls scattered all through my code. I don’t want Guice to be poured all over my app. I want my app to be clean, not soaked in Guice.
But Uncle Bob, That means I have to use new
or factories, or pass globals around.
You think the injector
is not a global? You think BillingService.class
is not a global? There will always be globals to deal with. You can’t write systems without them. You just need to manage them nicely.
And, no, I don’t have to use new
everywhere, and I don’t need factories. I can do something as simple as:
public class BillingApplicationNoGuice {
public static void main(String[] args) {
CreditCardProcessor cp = new MyCreditCardProcessor();
TransactionLog tl = new DatabaseTransactionLog();
BillingService.instance = new BillingService(cp, tl);
// Deep in the bowels of my system.
BillingService.instance.processCharge(9000, "Bob");
}
}
But Uncle Bob, what if you want to create many instances of BillingService
rather than just that one singleton?
Then I’d use a factory, like so:
public class BillingApplication {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new BillingModule());
BillingService.factory = new BillingServiceFactory(injector);
// Deep in the bowels of my code.
BillingService billingService = BillingService.factory.make();
billingService.processCharge(2034, "Bob");
}
}
But Uncle Bob, I thought the whole idea was to avoid factories!
Hardly. After all, Guice is just a big factory. But you didn’t let me finish. Did you notice that I passed the Guice injector into the factory? Here’s the factory implementation.
public class BillingServiceFactory extends AbstractModule {
private Injector injector;
public BillingServiceFactory(Injector injector) {
this.injector = injector;
}
protected void configure() {
bind(TransactionLog.class).to(DatabaseTransactionLog.class);
bind(CreditCardProcessor.class).to(MyCreditCardProcessor.class);
}
public BillingService make() {
return injector.getInstance(BillingService.class);
}
}
I like this because now all the Guice is in one well understood place. I don’t have Guice all over my application. Rather, I’ve got factories that contain the Guice. Guicey factories that keep the Guice from being smeared all through my application.
What’s more, if I wanted to replace Guice with some other DI framework, I know exactly what classes would need to change, and how to change them. So I’ve kept Guice uncoupled from my application.
Indeed, using this form allows me to defer using Guice until I think it’s necessary. I can just build the factories the good old GOF way until the need to externalize dependencies emerges.
But Uncle Bob, don’t you think Dependency Injection is a good thing?
Of course I do. Dependency Injection is just a special case of Dependency Inversion. I think Dependency Inversion is so important that I want to invert the dependencies on Guice! I don’t want lots of concrete Guice dependencies scattered through my code.
BTW, did you notice that I was using Dependency Injection even when I wasn’t using Guice at all? This is nice and simple manual dependency injection. Here’s that code again in case you don’t want to look back:
public class BillingApplicationNoGuice {
public static void main(String[] args) {
CreditCardProcessor cp = new MyCreditCardProcessor();
TransactionLog tl = new DatabaseTransactionLog();
BillingService bs = new BillingService(cp, tl);
bs.processCharge(9000, "Bob");
}
}
Dependency Injection doesn’t require a framework; it just requires that you invert your dependencies and then construct and pass your arguments to deeper layers. Consider, for example, that the following test works just fine in all the cases above. It does not rely on Guice, it only relies on the fact that dependencies were inverted and can be injected into BillingService
public class BillingServiceTest {
private LogSpy log;
@Before
public void setup() {
log = new LogSpy();
}
@Test
public void approval() throws Exception {
BillingService bs = new BillingService(new Approver(), log);
bs.processCharge(9000, "Bob");
assertEquals("Transaction by Bob for 9000 approved", log.getLogged());
}
@Test
public void denial() throws Exception {
BillingService bs = new BillingService(new Denier(), log);
bs.processCharge(9000, "Bob");
assertEquals("Transaction by Bob for 9000 denied", log.getLogged());
}
}
class Approver implements CreditCardProcessor {
public boolean approve(int amount, String id) {
return true;
}
}
class Denier implements CreditCardProcessor {
public boolean approve(int amount, String id) {
return false;
}
}
class LogSpy implements TransactionLog {
private String logged;
public void log(String s) {
logged = s;
}
public String getLogged() {
return logged;
}
}
Also notice that I rolled my own Test Doubles (we used to call them mocks, but we’re not allowed to anymore.) It would have been tragic to use a mocking framework for such a simple set of tests.
Most of the time the best kind of Dependency Injection to use, is the manual kind. Externalized dependency injection of the kind that Guice provides is appropriate for those classes that you know will be extension points for your system.
But for classes that aren’t obvious extension points, you will simply know the concrete type you need, and can create it at a relatively high level and inject it down as an interface to the lower levels. If, one day, you find that you need to externalize that dependency, it’ll be easy because you’ve already inverted and injected it.
Saying "NO". 787
I saw this cartoon in a tweet today. It’s the story of how a boss corrupts the work of a professional. It’s a funny cartoon, and a sad story that happens all too often in our profession. But who, exactly, was at fault?...
The difference between a laborer and a professional is that a laborer takes orders from his boss, and a professional provides input to his superiors. Laborers are hired to take direction. Professionals are hired to ensure that the direction chosen makes sense.
Imagine this conversation between a patient and a doctor:
Patient: “My arm hurts.” Doctor: “What would you like me to do about it?” Patient: “Make my arm stop hurting.” Doctor: “Do you want me to cut it off?, I can do that.” Patient: “No, I just want it to stop hurting.” Doctor: “I could cut all the nerves to your arm. That’ll stop it.” Patient: “Isn’t there something less drastic you could do?” Doctor: “Ooops, sorry, time for my break.”
Clearly we don’t expect doctors to behave this way. Even though the patient is the boss, the patient expects the doctor to have the answers and help set the direction.
Here’s another version of the conversation:
Patient: “I want you to cut my arm off.” Doctor: “What’s wrong with your arm?” Patient: “It hurts. I’m tired of it. Just cut it off.” Doctor: “Let me see your arm. Hmmm. Looks like you’ve got a sprain or perhaps a hairline fracture. We should take some X-Rays.” Patient: “No, just cut it off.” Doctor: “Sir, I do not cut off healthy arms.” Patient: “But I’m paying you. You have to do what I say!” Doctor: “No, sir, I don’t. Cutting off your arm would violate my oath.”
Which of these two doctors would you rather be? Now project these two doctors into your own profession, and which would you rather be?
Programmers are professionals. They know more about designing and implementing software systems than their bosses do. Indeed, they are hired for this knowledge and expertise. And they have a solemn duty to prevent their managers from doing things that would be harmful.
All this boils down to one simple thing. Professionals are willing to say “No”. When their managers come to them with direction that makes no sense, a professional programmer will refuse the direction.
Is this risky? Sure. But part of being a professional is the willingness to stand on principle. There are lines that a professional will not cross.
Of course saying “No.” is only one side of the coin. Professionals are also expected to explain their positions, and come up with viable alternatives. Professionals negotiate with their superiors until both parties are satisfied with the chosen direction.
The poor web-designer schmuck in that cartoon was not behaving as a professional. He was behaving as a laborer. The fiasco at the end was his fault. He should have said “No.” and started a negotiation with his customer instead of just doing everything the customer said.
The cartoonist painted the web-designer as a wise but impotent victim, and the boss as the overbearing dufus. The reality is that the web-designer took the role of the victim voluntarily and shirked his responsibility to refuse direction that he considered harmful.
If you are a professional, you never allow yourself to be put in the role of the victim.
What's all this nonsense about Katas? 226
There has been an increase in interest in Software Katas of late. What is all this buzz about, and why might it be important?
Several years ago (Pragmatic) Dave Thomas started a special blog about coding katas. The idea was simple: Professionals practice.
This thought might not have occurred to you before; but it’s self-evidently true. Professional musicians practice. Professional dancers practice. Doctors practice. Soldiers practice. Indeed, any kind of professional craftsman or artisan must practice their adopted trade in order to execute it well when it counts.
Dave’s point was that professional programmers need to practice like any other professional. He set forth a number of simple exercises and problems that programmers could solve during their practice time. He also suggested that practice time needs to be scheduled and protected as part of the normal routine of a software developer.
At XP2005 in Shefield, UK, I attended Laurent Bossavit’s and Emmanuel Gaillot’s Coding Dojo session. I blogged about it at the time. I left that session with a different view of what a Kata might be. In Dave Thomas’ view a kata is an exercise to solve. Each time you solve it you try a different approach. Dave’s notion is that a kata is a way to explore the solution space of a problem. But in Martial arts a kata is something different; it is a set of motions that one memorizes in minute detail. A martial arts kata is a precisely executed dance. I left Sheffield with the idea that a coding kata could be more like a martial arts kata.
About a year ago, Corey Haines (our wandering minstrel of code) stopped by and told me about some mini-conferences that had adopted the notion of coding kata. What he described sounded more like a group dance than a bunch of people independently solving a given problem. This got me thinking. So at the next Software Craftsmanship meeting at 8th Light (Which, not coincidentally, takes it’s name from a martial arts philosophy) I conducted a simple kata session in dojo style.
I, acting as the Sen Sei, had everyone file in to the room as they would to a dojo. I had them put their green bands on their wrists (mine was black!). I bade them to sit, and then gestured for silence. For the next 15 minutes I led them through the Prime Factors Kata in Java without uttering a word (well, almost). I would write a simple test case, then gesture for them to do the same. Then I would make the test pass, and again gesture for them to repeat my moves.
Then, this Fall, I attended Programming with the Stars at Agile 2009. As I watched the contestants perform their programming sessions, I realized that they were not simply demonstrating programming prowess; indeed they were competing in how well they performed their session. That’s when it struck me. This was a performance art!
It seems absurd to think of programming as a performance art. And yet watching those people up on stage working through routines that they had clearly practiced over and over again, was delightfully entertaining to me, and to the crowd. There were cheers and applause when a performing pair did something especially well. There was laughter when a pair executed a clever joke in code, or in behavior. For programmers, watching other programmers perform well practiced routines was fun!
Now I had seen martial arts katas executed as performance art during competitions. Indeed, it is a beautiful thing to watch a skilled and well practiced martial artist peform a kata. And that started me thinking. Why would a martial artist practice these forms so intensely that they could be performed as an art?
The goal of martial arts is not to perform on stage. The goal of martial arts is self defense! And yet, when a martial artist is at the peak of his skill, his practice takes on the quality of a performance art. When you watch a skilled martial artist perform, you know you don’t want to fight him. The performance is a demonstration, and a realization, of mastery.
And yet the performance is not the goal. No martial artist practices his art so that they can perform on stage. A martial artist practices to achieve personal perfection in the art of self defense. The fact that the practice can be performed is a (pleasant) side effect.
Could it be that these coding kata that we’ve been dabbling with for the last few years could be performed? Is there a benefit to practicing them so much that performance is an option? Is there really any reason for a programmer to create and then memorize a routine down to the level of individual keystrokes? Is there profit to be gained from practicing that routine so thoroughly that you can do it at high speed with virtually no errors? This August I decided to find out.
I started with the Prime Factors Kata in Java, and set it to music inspired by this video of dancing kites. The piece is about 4 minutes long, and I figured I’d need about twice that, so I found two different version of the music and played them back to back. But working in Java is ponderous, and I could not complete the kata before the two pieces had finished. So I switched to Ruby. Using Ruby and Rspec I was able to finish the Kata with plenty of time to spare.
Thereupon began an evolution. Since I had time, I added more features to the kata. As I improved in my practice I found I had even more time, so I added even more features. I refined and polished. I refactored my refactorings. I trimmed keystrokes, and learned many new keyboard shortcuts in the process. I completely abandoned the mouse; and then later reacquired it for flourishes and highlights (but never for actual coding).
Week after week, I set aside 30 minutes or so every day to practice, and practice, and practice—just the way I used to practice my Jiu Jitsu Katas. I would practice on airplanes while flying to clients. I would practice in bed with my laptop in my lap. I would practice late at night in hotel rooms after a long day consulting for clients. I would practice early in the morning before shower and breakfast. And the practice started to pay off.
Ten weeks later I finally decided I was ready to create a screencast. I reduced my screen resolution to 1024X768. I configured SnapZ ProX to record the whole screen at 80% size. And I began to record.
Performing a coding kata in time to music is a very difficult thing to do. Maintaining the timeline is critical. There are very few errors that you can effectively recover from. If you miss a stroke, the whole sequence melts down. And melt down it did. Over and over and over again. I spent weeks trying to record a reasonably good session. I must have done hundreds of takes. It was very frustrating.
But day by day I got better and better at it. Finally, after weeks of trying, I got what I consider to be a recording that, though not perfect, is good enough to present. You can watch that recording here.
Has this paid off in the regular programming I do? I think it has. My mouse usage is much less than it used to be. I know a much larger number of keyboard shortcuts than I used to, and I can use them almost instinctively. My typing and accuracy have improved quite a bit, and I now type more punctuation and number keys without looking. So, yes, I think the effort has paid off; though I’m not at all sure the payoff compensates for the effort.
But something else compensates for the effort. Making this recording was fun—it was a lot of fun. And that’s probably the real answer to the question posed in the title of this blog.
Archeological Dig 112
I was going through some old files today, and I stumbled upon some acetate slides from 1995. They were entitled: “Managing OO Projects”. Wow! What a difference fifteen years makes! (Or does it?) ...
In 1995-99 I was frequently asked to speak to managers about what a transition to OO (usually from C to C++) would do for (or to) them. I would spend a half day to a day going over the issues, costs, and benefits.
One part of that talk (usually about 90 min) was a discussion about software process. It was the process part of the talk that those acetate slides that I found described.
1995 was during the ascendency of Waterfall. Waterfall thinking was king. RUP had not yet been conceived as an acronym. And though Booch was beating the drum for incrementalism, most people (even many within Rational) were thinking in terms of six to eighteen month waterfalls.
So, here are the slides that I uncovered deep within an old filing cabinet. I scanned them in. They were produced on a Macintosh using the old “More” program. (Where is that program now? It was so good.)
Go ahead and read them now. Then come back here and continue…What struck me about those slides was the consistency of the message with today. It was all about iterative development. Small iterations (though I never deigned to define the length in the slides, I frequently told people 2 weeks), measured results, etc. etc. Any Agile evangelist could use those slides today. He or she would have to dance quickly around a few statements, but overall the message has not shifted very much.
What’s even more interesting is the coupling between the process, and OO. The slides talk a lot about dependency management and dependency structure. There are hints of the SOLID principles contained in those slides. (Indeed several of the principles had already been identified by that time.) This coupling between process and software structure was a harbinger of the current craftsmanship/clean-code movement.
Of course the one glaring omission from these slides is TDD. That makes me think that TDD was the true catalyst of change, and the bridge that conveyed our industry from then to now.
Anyway, I guess the more things change, the more they stay the same.
Comments please!
Excuse me sir, What Planet is this? 141
Update 12 hours later.
I’m not very proud of this blog (or as one commenter correctly called it “blart”). It is derisive, sneering, and petulant. It is unprofessional. I guess I was having a bad morning. I slipped. I didn’t check with my green band.
So I apologize to the audience at large, and to Cashto. You should expect better from me.
I thought about pulling the blog down; but I think I’ll leave it up here as an example of how not to write a blog.
Some folks on twitter have been asking me to respond to this blough (don’t bother to read it right now, I’ll give you the capsule summary below. Read it later if you must). It’s a typical screed complete with all the usual complaints, pejoratives, and illogic. Generally I don’t respond to blarts like this because I don’t imagine that any readers take them very seriously. But it appears that this blelch has made the twitter rounds and that I’m going to have to say something.
Here are the writer’s main points:
- He likens unit tests to training wheels and says you can’t use them to win the Tour de France.
- I think winning the Tour de France has much more to do with self-discipline than he imagines it does. I mean it’s not really just as simple as: “Get on a bike and ride like hell!”
- He says testing is popular amongst college students
- I’d like to see his data!
- He goes on to say: (cue John Cleese): “(ahem) unit tests lose their effectiveness around level four of the Dreyfus model of skill acquisition”.
- (blank stunned stare). Is this a joke? All false erudition aside, WTF is he talking about?
- He says that unit tests don’t give us confidence in refactoring because they over-specify behavior and are too fine-grained.
- He apparently prefers hyphenations to green bars.
- He says they mostly follow the “happy path” and therefore don’t find bugs.
- Maybe when he writes them! This is a big clue that the author can’t spell TDD.
- He complains about Jester
- without getting the joke!
- He says unit tests “encourage some pretty questionable practices.” He flings a few design principles around and says that unit testing doesn’t help with them.
- as the author, editor, and/or advocate of many of those principles; I have a slightly different view.
- He says that “many are starting to discover that functional programming teaches far better design principles than unit testing ever will”
- Oh no! Not the old “My language teaches design.” claim. We’ve heard it all before. They said it about C++, Java, COM (?!), etc… The lesson of the ‘90s? Languages don’t teach design. You can make a mess in any language.
- He says: “tests can have negative ROI. Not only do they cost a lot to write, they’re fragile, they’re always broken, they get in the way of your refactoring, they’re always having you chase down bogus failures, and the only way to get anything done is to ignore them.”
- In one of my favorite episodes of Dr. Who, Tom Baker exits the Tardis, walks up to someone on the street and says: “Excuse me sir, what planet is this?”
- He says: “What I’m saying is that it’s okay if you don’t write unit tests for everything. You probably have already suspected this for a long time, but now you know. I don’t want you to feel guilty about it any more.”
- Translation: “I don’t want to feel guilty about it anymore so I’m going to try to convince you…” I sincerely doubt this author has your best interests at heart.
- He says: “Debugging is easy, at least in comparison to writing all those tedious tests.”
- Refer back to the Dr. Who quote.
To quote Barack Obama: “Enough!”
Has this guy ever done TDD? I rather doubt it. Or if he did, he was so inept at it that his tests were “fragile”, “always broken”, and “in the way of refactoring”. I think he should give it another try and this time spend a bit more time on test design.
Perhaps he’s one of those guys who thought that unit tests were best written after the code. Certainly his list of complains makes a lot of sense in that light. Hint: If you want to fail at unit testing, write them last.
The bottom line is that the guy probably had a bad experience writing unit tests. He’s tired of writing them and wants to write fewer of them. He’d rather debug. He thinks he can refactor without tests (which is definitively false). He thinks he can go faster by writing fewer tests. Fine, that’s his choice. And he’s found a rationalization to support his desires. Great.
I predict that his results will not compare well with those who adopt the discipline of TDD. I predict that after a few years he’ll either change his mind, or go into management.
Oh, and to the author: Gesundheit!
Manual Mocking: Resisting the Invasion of Dots and Parentheses 230
The twittersphere has been all abuzz today because of something I tweeted early this morning (follow @unclebobmartin). In my tweet I said that I hand-roll most of my own mock objects in Java, rather than using a mocking framework like mockito.
The replies were numerous and vociferous. Dave Astels poignantly stated that hand-rolling mocks is so 2001!
So why do I roll my own mocks?
public class SelectorTest { private List<Object> list; @Before public void setup() { list = new ArrayList<Object>(); list.add(new Object()); } @Test public void falseMatcherShouldSelectNoElements_mockist() { Matcher<Object> falseMatcher = mock(Matcher.class); Selector<Object> selector = new Selector<Object>(falseMatcher); when(falseMatcher.match(anyObject())).thenReturn(false); List<Object> selection = selector.select(list); assertThat(selection.size(), equalTo(0)); } @Test public void falseMatcherShouldSelectNoElements_classic() { Matcher<Object> falseMatcher = new FalseMatcher(); Selector<Object> selector = new Selector<Object>(falseMatcher); List<Object> selection = selector.select(list); assertThat(selection.size(), equalTo(0));} private static class FalseMatcher implements Matcher<Object> { public boolean match(Object element) { return false; } } }
The first test shows the really cool power of mockito (which is my current favorite in the menagerie of java mocking frameworks). Just in case you can’t parse the syntax, let me describe it for you:
- falseMatcher is assigned the return value of the “mock” function. This is a very cool function that takes the argument class and builds a new stubbed object that derives from it. In mockito, the argument can be a class or an interface. Cool!
- Now don’t get all panicy about the strange parenthetic syntax of the ‘when’ statement. The ‘when’ statement simply tells the mock what to do when a method is called on it. In this case it instructs the falseMatcher to return false when the ‘match’ function is called with any object at all.
The second test needs no explanation.
...
And that’s kind of the point. Why would I include a bizzare, dot-ridden, parentheses-laden syntax into my tests, when I can just as easily hand-roll the stub in pure and simple java? How hard was it to hand-roll that stub? Frankly, it took a lot less time and effort to hand-roll it than it took to write the (when(myobj.mymethod(anyx())).)()).))); statement.
OK, I’m poking a little fun here. But it’s true. My IDE (InteliJ) generated the stub for me. I simply started with:
Matcher<Object> falseMatcher = new Matcher<Object>() {};
InteliJ complained that some methods weren’t implemented and offered to implement them for me. I told it to go ahead. It wrote the ‘match’ method exactly as you see it. Then I chose “Convert Anonymous to Inner…” from the refactoring menu and named the new class FalseMatcher. Voila! No muss, no fuss, no parenthetic maze of dots.
Now look, I’m not saying you shouldn’t use mockito, or any of these other mocking tools. I use them myself when I must. Here, for example, is a test I wrote in FitNesse. I was forced to use a mocking framework because I did not have the source code of the classes I was mocking.@Before public void setUp() { manager = mock(GSSManager.class); properties = new Properties(); } @Test public void credentialsShouldBeNonNullIfServiceNamePresent() throws Exception { properties.setProperty("NegotiateAuthenticator.serviceName", "service"); properties.setProperty("NegotiateAuthenticator.serviceNameType", "1.1"); properties.setProperty("NegotiateAuthenticator.mechanism", "1.2"); GSSName gssName = mock(GSSName.class); GSSCredential gssCredential = mock(GSSCredential.class); when(manager.createName(anyString(), (Oid) anyObject(), (Oid) anyObject())).thenReturn(gssName); when(manager.createCredential((GSSName) anyObject(), anyInt(), (Oid) anyObject(), anyInt())).thenReturn(gssCredential); NegotiateAuthenticator authenticator = new NegotiateAuthenticator(manager, properties); Oid serviceNameType = authenticator.getServiceNameType(); Oid mechanism = authenticator.getMechanism(); verify(manager).createName("service", serviceNameType, mechanism); assertEquals("1.1", serviceNameType.toString()); assertEquals("1.2", mechanism.toString()); verify(manager).createCredential(gssName, GSSCredential.INDEFINITE_LIFETIME, mechanism, GSSCredential.ACCEPT_ONLY); assertEquals(gssCredential, authenticator.getServerCredentials()); }
If I’d had the source code of the GSS classes, I could have created some very simple stubs and spies that would have allowed me to make these tests a lot cleaner than they currently appear. Indeed, I might have been able to test the true behavior of the classes rather than simply testing that I was calling them appropriately…
Mockism
That last bit is pretty important. Some time ago Martin Fowler wrote a blog about the Mockist and Classical style of TDD. In short, Mockists don’t test the behavior of the system so much as they test that their classes “dance” well with other classes. That is, they mock/stub out all the other classes that the class under test uses, and then make sure that all the right functions are called in all the right orders with all the right arguments. etc. There is value to doing this in many cases. However you can get pretty badly carried away with the approach.
The classical approach is to test for desired behavior, and trust that if the test passes, then the class being tested must be dancing well with its partners.
Personally, I don’t belong to either camp. I sometimes test the choreography, and I sometimes test the behavior. I test the choreography when I am trying to isolate one part of the system from another. I test for the behavior when such isolation is not important to me.
The point of all this is that I have observed that a heavy dependence on mocking frameworks tends to tempt you towards testing the dance when you should be testing behavior. Tools can drive the way we think. So remember, you dominate the tool; don’t let the tool dominate you!
But aren’t hand-rolled mocks fragile?
Yes, they can be. If you are mocking a class or interface that it very volatile (i.e. you are adding new methods, or modifying method signatures a lot) then you’ll have to go back and maintain all your hand-rolled mocks every time you make such a change. On the other hand, if you use a mocking framework, the framework will take care of that for you unless one of the methods you are specifically testing is modified.
But here’s the thing. Interfaces should not usually be volatile. They should not continue to grow and grow, and the methods should not change much. OK, I realize that’s wishful thinking. But, yes, I wish for the kind of a design in which interfaces are the least volatile source files that you have. That’s kind of the point of interfaces after all… You create interfaces so that you can separate volatile implementations from non-volatile clients. (Or at least that’s one reason.)
So if you are tempted to use a mocking framework because you don’t want to maintain your volatile interfaces, perhaps you should be asking yourself the more pertinent question about why your interfaces are so volatile.
Still, if you’ve got volatile interfaces, and there’s just no way around it, then a mocking framework may be the right choice for you.
So here’s the bottom line.
- It’s easy to roll your own stubs and mocks. Your IDE will help you and they’ll be easier and more natural to read than the dots and parentheses that the mocking frameworks impose upon you.
- Mocking frameworks drive you towards testing choreography rather than behavior. This can be useful, but it’s not always appropriate. And besides, even when you are testing choreography, the hand-rolled stubs and mocks are probably easier to write and read.
- There are special cases where mocking tools are invaluable, specifically when you have to test choreography with objects that you have no source for or when your design has left you with a plethora of volatile interfaces.
Am I telling you to avoid using mocking frameworks? No, not at all. I’m just telling you that you should drive tools, tools should not drive you.
If you have a situation where a mocking tool is the right choice, by all means use it. But don’t use it because you think it’s “agile”, or because you think it’s “right” or because you somehow think you are supposed to. And remember, hand-rolling often results in simpler tests without the litter of dots and parentheses!