Tales from the jar side: Testing as a Weapon, Managing Your Manager changes, and Functional Cat Pictures
Hai. My presentation on Tuesday can haz cat pics, downloaded in functional style, in parallel. Kthxbye!
Welcome to Tales from the jar side, the Kousen IT newsletter, for the week of July 25 - August 2, 2020. This week I taught one-day courses in Kotlin and Spring, Managing Your Manager, What’s New In Java, and Mockito and the Hamcrest Matchers, all on the O’Reilly Learning Platform. I also spent four half-days teaching a bootcamp for career changers.
A Rant About Testing As A Weapon
I try not to go on a rant very often, partly because doing so on the web is such a cliche and partly because as I get older I’m trying not to transition into curmudgeon mode.
Curmudgeon: seen it all, done it all, not impressed. You’ll find at least one in every IT organization.
Nevertheless, an issue came up during my Mockito class that I had to address. For those who don’t know, Mockito is a framework for generating mocks and stubs for unit testing. The goal of a unit test is to ensure a particular piece of code is working, without having to deal with its dependencies.
For example, say you have a service class that completes an order on some ecommerce site. That class needs to update tables in the database regarding orders, customers, products, and shipments, and also charge a credit card. If the credit card fails, all the changes made during the current process need to be undone.
An integration test or a functional test would test the service class while the database and credit card checker were all connected, so it feels like you’re driving the web site programmatically. That’s realistic, because it’s close to the actual performance of the real site, but can require a fair amount of setup and teardown. Plus, integration and functional tests tend to take longer.
Unit tests, on the other hand, set up “rigged” objects called stubs or mocks, for the database changes and credit card checker. That way you can focus exclusively on how the service logic is implemented without worrying about issues in the dependencies throwing off your tests. That isolates the code you’re testing, and it tends to be much faster. Mockito is a framework for creating those rigged objects automatically.
One lesson I have to emphasize in my class is that your job is not to test the mocks. You’re testing another class which relies on the mocks. The Mockito documentation is easy to misread if you don’t keep that in mind, because it’s all about how to configure the mocks and stubs to do what you need.
Mockito also has several limitations, most of which are deliberate. For example, with Mockito you cannot mock constructors, or the equals and hashCode methods, or even static methods (until very recently — see the changes in Mockito 3.4 and above). Someone in class always asks why you can’t do those things and what other frameworks they should use to overcome those limitations.
I used to wonder why people were so determined to do what Mockito insisted was a bad idea, but this week I finally realized part of what was driving those questions. Many companies employ code coverage tools like jacoco (Java Code Coverage, get it?), which report on the percentage of lines in your system that have been covered by tests.
A sample jacoco code coverage report, from their home page.
The problem is, whenever you see a metric, there’s an overwhelming urge to maximize it. That table shows “missed branches” and “missed instructions” and coverage percentages as low as 64%. It’s really hard not to want to make all of those as close to 100% as possible.
Unfortunately, the marginal return on doing that drops quickly. A few years ago I consulted with one company that insisted on better than 95% code coverage on every project, and the result is that one poor developer I knew spent three days writing a test for code that took her only 20 minutes to write, covering edge cases that were very unlikely to ever happen. That was a massive waste of time.
It’s not easy to say what percentage of code should be tested. It’s an experience thing as much as anything, and the real answers depend on the situation at hand. The principle is you test what needs to be tested, like business logic or anything that affects the results. You don’t need to test every getter or setter or every constructor in your system, because they’re normally both trivial and auto-generated. But not testing them makes your percentages go down, and when a company has a metric, it’s hard not to focus on it.
(This is also a subtle argument in favor of alternative JVM languages like Groovy or Kotlin. Those languages dramatically reduce the number of lines of code you have to write, and generated code that doesn’t appear in the code base doesn’t affect your statistics.)
The other problem with testing is that no matter how you do it, somebody always argues you should have done more or done it differently. That leads to harsh judgements in code reviews. When you combine these effects, developers are reluctant to write tests because nobody wants to be criticized. It feels like you can never do enough or do it properly, so why bother in the first place?
That drives me crazy. The analog I always give to try to fix the problem is to compare testing to brushing your teeth, of all things.
From ask the dentist, though I don’t plan to.
If you ask a dentist the proper way to brush your teeth, they’ll give you a detailed answer. But if you press them on it, they will admit that it doesn’t really matter how you do it as long as you do it at all. You can optimize, but the difference between not brushing and brushing is much greater than the difference between brushing and brushing perfectly, whatever that means.
My attitude about testing is:
Don’t Use Testing As A Weapon.
Just because you have a metric and therefore a way to show off your superior skills, don’t use it to attack your co-workers, thinking it will make you look better in the process. Sure there are better and worse ways to accomplish any given task, but the real goal is to get the job done, and that’s much more likely to happen if everybody can cooperate in a pleasant working environment. I don’t know what it is about testing (and a few other subjects) that brings out the pedant in so many people, but please try not to fall into that trap.
That, by the way, is a corollary of one of my “Principles To Live By,” which is:
Try not to waste time and energy attacking your friends.
It’s ironic that it’s easier to attack your friends than your enemies, because your friends will listen to you and they care about what you say. But the closer someone is to you, the easier it is to hurt them. Hurting people may make you feel powerful (see our current administration, made up almost exclusively of damaged people who live to hurt others), but the result is you wind up alone and surrounded by rubble.
If you’re going to attack, attack the people who deserve it. At the moment, for me at least, those are the people currently trying to destroy my country by blaming all their problems on the weak and vulnerable, while doing everything they can to preserve their own privilege. I have nothing but contempt for those people, and I agree they deserve your scorn and we should do anything we can to remove them from power.
Of course, this is why I labeled this section a rant. I try not to do it often. Plus, the readers of this newsletter are the least likely people I know to be part of the problem. So in conclusion, I’ll just say, thank you for coming to my TED talk. :)
Managing Your Manager
Over several newsletters I’ve talked about my upcoming book, Managing Your Manager, which will be published by Pragmatic Programmers later this year. I’m still headed for the initial three-chapter review, even though most of the book is written. As part of the process, I had a discussion with my managing editor about the book.
One point he tried to make (and I appreciate how diplomatically he approached the subject) is that I really need to drop the chapter I was planning on advice for women and underrepresented minorities (URMs). I originally didn’t have a chapter like that, but decided a couple months ago that it would be wrong not to address those issues in one form or another. The plan was to make sure to “stay in my lane” as it were, and stick to discussing how the other principles I recommend in the book change when applied to situations involving women and URMs.
The problem — and I know this, but my privilege allows me to forget it sometimes — is that any chapter like that is going to generate a lot of controversy, and some people complaining about it will be arguing in bad faith. I don’t mind hearing from women and URMs who I respect. In fact, I was rather looking forward to that, to check if what I recommended made sense to them and to learn about their experiences. I spent a fair amount of time digging into the relevant issues, and I feel I have something to contribute to the discussion.
The problem with connecting everyone on the internet, however, is that you connect the bad actors as well as the good. The danger is that people who want to push a particular agenda will find my book and attack it, whether they read it or not, no matter what I said. I agreed that I didn’t want issues associated with a single chapter to dominate all discussions about the book.
Of course, any woman or URM on the net already knows that. It reminds me of the time I once suggested to my friend Trisha Gee that if she taught any training classes, she should skip reading the evaluations for a while. She gave me a wry look and said, “you mean don’t read the comments?” and I had to laugh. Any woman with a public profile on the internet knows far more about protecting themselves from abuse than I will ever know. At least when I get feedback it’s related to what I actually said or did. I’m sure that’s not at all the case for Trisha, at least for a certain despicable subset of commenters.
That relates to another danger that comes from including that chapter. Maybe I have something to say, but I can’t escape the fact that I would be an older white male talking about racism and misogyny to women and URMs, and for most people in my position the best thing for them to do in that case is to STFU.
On the other hand, as it turned out most of the chapter as written involved giving advice to colleagues of women and URMs, which has an “only Nixon could go to China” vibe to it. I think I can explain the concerns of women and URMs to other men in a way they’re likely to hear and understand.
In the end, though, I agreed to drop the chapter, at least for now. I expect I’ll still bring up the issues, both in this newsletter and possibly in my training class or presentations. But in today’s world such issues are understandably sensitive, and I’ll do my best to respect that.
The Internet Was Made For…
… cat pictures, despite what you may have heard.
The original, infamous Grumpy Cat, from VidCon in 2014.
This week I’m speaking at the London Java Community group. My talk is entitled Functional Programming in Java, Kotlin, and Groovy. It is based on a similar talk I gave at DevNexus, the last conference I physically attended back in February.
At DevNexus, I was preparing one of my examples and ran into a problem. I have a Groovy script that downloads pictures from Flickr and renders them using the SwingBuilder class. Everything seemed to work, but I couldn’t see any images. I tried printing out the URLs being accessed and they worked inside a browser, but I couldn’t get anything to show up in my GUI.
This week I decided to dig into the problem again, because I want to use that demo in my presentation. After too many hours, I finally realized that all I had to do was change the protocol for the image URLs from “http” to “https” and suddenly everything worked. Apparently some time during the past few years they switched to secure connections and I missed it.
Long story short, there will be cat pictures on Tuesday.
As you can see, this time I got pictures of cats. Since I’m grabbing the latest six images on Flikr tagged with a search term, whatever they may be, that’s not guaranteed. Hopefully I’ll get cats during the presentation on Tuesday. But isn’t the chance that I’ll get something wildly inappropriate why people watch?
Miscellaneous
I really enjoyed the bootcamp students I got to meet this week. Fortunately the company let me use my own Spring and Spring Boot materials. I also got to do some basic discussions about object-oriented principles, and give my standard summary about security issues, both of which seemed to go over well. It helped that even though the class was very large (about 50 people), the students were very kind, easy to get along with, and pretty funny as well. It took a lot of energy to participate, given that I had classes every morning the rest of the week, but I’m really glad I did it.
Unrelatedly, I should note that one good thing happened this week. My wife and I watched Bob and Doug McKenzie — oops, I mean astronauts Bob Behnken and Doug Hurley — return to Earth from the ISS on Sunday. After splashdown there was a delay before they were able to leave the capsule, and I couldn’t resist live-tweeting the experience. Here’s the first tweet, which I didn’t realize was going to be part of a series:
Follow that to see the rest of the thread if you like.
(After it was over, I realized that when the spectator boats got too close and NASA had to tell them to back off, I should have tweeted Bob and Doug saying “arming photon torpedos.” Oh well. Maybe next time.)
Speaking of Twitter, here’s one of those brilliant arguments that seems blindingly obvious in retrospect:
Might as well watch it before TikTok gets banned, bought by Microsoft, and eventually killed by some clone product from Facebook. I’m sure Sarah Cooper (a true national treasure if ever there was one) will find success wherever that happens to be.
Last week:
Spring with Kotlin
Managing Your Manager
What’s New In Java
Mockito and the Hamcrest Matchers, all on the O’Reilly Learning Platform
Spring, Java, and more for bootcamp students
This week:
London Java Community presentation on Tuesday
Deep Dive Into Spring, NFJS Virtual Workshop on Wednesday
Java Testing with JUnit and Mockito, NFJS Virtual Workshop on Thursday
Working on my Managing Your Manager book