Archive for category Software Development
A very common question I hear from developers is “How do I write tests for private methods?”. My immediate answer is “You don’t!”. Technically, if you’re in C# Land, you can instantiate the class and then use Reflection to call the private method. But please don’t!
Say you have some class like this one:
Of course, instead of comments, you’d have the actual code. You get the point.
You then decide to clean things up a bit and extract the “make sure all the ingredients are in” code into a separate, private ValidateIngredients method, like so:
That’s usually the moment when developers ask “how do I test that private method?”. If we have tests for the main method (DoTheMagic, in this example), then ValidateIngredients already get test coverage.
Quite often, when developers feel strong about having separate tests for a private method, there’s a clear indication that the private method should really be a public method on a separate class. Think Single Responsibility Principle.
Following the example above, we create a Validator class and move our validation logic in there:
And then we use that validator in the previously shown class:
You’ve probably noticed that we also introduced an IValidatePotion interface. Think Dependency Inversion Principle. One of the benefits here is being able to isolate tests for the AwesomenessPotion and AswesomenessPotionValidator classes.
I have talked about the purpose of a user story and the idea of keeping stories straight to the point. I’ve recently run into a good example of how a user story could be improved, and I’ll share it here with you. The original story looked somewhat like this:
In order to quickly navigate through Sales Orders
As a salesperson working at my desk
I want to see a list of all existing Sales Orders
So that I can navigate to Sales Order that I need to take an action on quickly
I get that the person wants to navigate through sales orders “quickly”. But why is that important? To get back to playing Candy Crush or scrolling through social networks?
In a conversation with the domain expert, I’ve learned that such a person takes calls from customers all day, so that’s why it’s important that the sales order lookup happens quickly; the business wants to take care of all of their customers, not letting them wait on the line for too long, and taking the necessary actions quickly.
With that clarification, let’s think of the following bit: “I want to see a list of all existing sales orders”. Does that mean “all existing sales orders on the entire database“? That could be a very long list!
After further clarification, the user really needs to see only a list of service orders for the customer who’s currently on the phone.
That information reveals some interesting bits:
- The system only needs to present a limited list of results to the user (which certainly helps with the “make it quick” need);
- We’ve learned a little more about the context to which this user story brings value: not only is the user “working at his or her desk“, but there’s a specific customer on the phone! That little gem tells us the one filter we can immediately apply to the search.
I’d then ask the following question next:
Does the user want to see all service orders for the given customer, or only the ones where the status is “open”, or “pending”, or “my goodness, this case really needs attention!”?
Maybe the answer is “well, most of the time the user needs to see the open orders, but having to see the pending ones also happen quite often. They almost never need to see the closed orders, though.”
That last bit of information can help tremendously the effort of providing a good User Experience; the system can take that information into account and maybe preload all of the open orders for the customer, as soon as the user indicates which customer is on the phone (the system could even detect who the customer is by looking up the phone number in the database, if such info and integration are available).
With that understanding, maybe the user story could be rewritten like so:
In order to better assist a customer and quickly move on to the next customer
As a Salesperson taking a call working at my desk
I want to quickly see the customer’s Sales Orders, filtered to the “open” orders, and have easy access to the “pending” ones
Notice that the original story mentioned “So that I can navigate to a service order that I need to take an action on quickly“.
What are the actions that this user may take given this context? The conversation about would certainly produce an entirely separate user story. Depending on the number and nature of the actions, it’d even be multiple user stories, one for each action.
I’m often asked about comments in code: when to do it, how to do it, what to put, etc. I’ve recently run into Steve’s post about when to comment your code, left a comment (!) there, and we got to expand our conversation in his podcast/screencast (link at the bottom). I’ve decided to create this post to consolidate the links and info shared during the interview, to make it easy for folks to find the material.
I remembered writing blog posts a couple of times over the years and it’s interesting to see how my opinion on this subject has changed over time.
The first post goes all the way back to 2005, with me asking “can you plesae put some comment on that Regular Expression?”. 15 years later, I still ask my smart friends to get me the RegEx I need, along some comments as to what each piece does!
In 2007, I was big into using Xml Comments, GhostDoct, and Documentor… I’m not anymore, as documented 10 years later with my post “XmlDoc Comments: Auto Generate and Hide the Clutter”. In nutshell, if we’re documenting a public API, yes, by all means let’s put in that documentation, but making it count: commenting the GetCustomers endpoint with “Gets the customers” doesn’t add any value to the effort!
My practice of making comments stick out as a sore thumb posted in 2010 still stands in 2020: I still set up all of my IDEs in that manner and it still produces exactly the outcome as I intended.
When I do want to drop a quick TODO comments in code (watch/listen to the podcast interview when it’s up to know why I might do that), I have templates on my IDEs to automate that: ReSharper in Visual Studio, User Snippet in VS Code, Live Template in RubyMine.
In regards to code that’s commented out, like so:
We should be using a source control system; if we ever want that code back, we have a way to bring it back. So just remove it!
Still using the example above, notice that each if-block is preceeded by a comment. Is it really necessary? How about removing the comment and extracting the expression into a method that tells us the question being asked?
There’s also the “narrator-style” comment:
Narrating every single line of code is very annoying (by the way, I think I wrote the code above many moons ago). If the comments were written initially as a placeholder for the steps that needed to be implemented, let’s make sure to get rid of it when we’re done.
Last but not least, some people say (I’ve said it myself) that comments should document “why” the code was written in such manner. I’d propose a variaton to that: how about documenting the why with some good specs (or tests, if that’s how you prefer)?
Now, I’m not refering to tests that look like this:
Such test doesn’t tell us the “why”; it tells us the “how”. I mean this kind of test (now you’ll see why spec fits better):
Summing it up, this is how I prefer to “comment” code:
- Given-When-Then specs
- Writing code English-first
If I do have a real need to drop an actual comment in code (“why do we have this query in the code that has to potential to perform badly”), I’ll probably drop a quick comment, with a link out to the issue tracker, where I’ll put more context about why the code was left like that, and where a Product Owner can decide when it’s appropriate to address the situation.
Any comments? 🙂
And for audio-only version:
Here’s a quick tip on how to create a TODO template in RubyMine:
Go to Preferences, Editor, Live Templates, and add your “todo” template under “user” (replace “CL” with your own
Now when you type “todo” and hit Tab in the editor, you get your expanded snippet:
A few years ago I posted about creating a TODO template in ReSharper. Now here’s a tip to do the same in VS Code!
Go to Preferences -> User Snippets:
Replace “CL” with your own initials.
And after hitting Enter you should see the snippet, with the cursor already placed when you need it to be:
As I wrap up preparation for my new talk (title “Trusting IT – Bridging the Gap Between Vision & Execution”), I realize I haven’t been so excited about a new talk for a long time. How do I know? Well, I look around me and I see the 11”x11” Post-It notes with my golden circle and know-feel-do model for the talk, tons of handwritten notes, mind maps, and the slide deck being created.
So, what’s the fuzz all about? Well, as it turns out, a lot of folks don’t trust IT.
That sort of took me by surprise when I first heard about it just a few years ago. Maybe I’ve taken it for granted, given the good experiences I’ve had in that front. I’ve reflected over many interactions, clients, co-workers, and one experience in special came to my mind and stuck with me.
In the late 90’s (maybe 98 or 99), I was doing some development work on the side as a freelancer. I presented a proposal to a business owner (let’s call the business Company X) after we’ve had a few meetings and I had put it on paper how I believed I could build the software they needed to help their business. That person then asked me to come to her office and said this to me:
“I’ve had a number of people bid on this project. Your bid was, by far, the highest one. I would like to close the deal with you, though. Because I trust you!”
Fast forward to 2015. A former employee of Company X runs his own company, invites me to lunch, shares with me that he is unhappy with his current IT situation, and he trusts me to give him guidance.
These experiences make me think of other similar situations where I had the luck to enjoy being trusted by people. Wait, was it really luck? Nope, that can’t be right. It isn’t. There’s way more to it than luck. There’s behavior, practices, intentions.
So I’ve been putting a lot of thought into identifying the things I believe have helped me over the last 2 decades, and the biggest lessons learned will be shared in this new talk, set to debut on May 6!
If you haven’t already, register at this link!
I really hope to see you there. 🙂
It has been a long time since I’ve given a public talk on productivity tips and tools, so I thought “Why not?!”, since this is a topic that most definitely fits into the purpose of the Improving Code User Group.
While I’ll be sharing mostly C#, ReSharper, Visual Studio, and VS Code, the content of this talk should be applicable to developers working with any language or IDE. Title and description of this meeting can be found at the bottom of this post.
The online meeting happens on May 6th, starting at 6pm. If you’re planning on attending, please RSVP by following this link. Knowing the likely number of attendees will help me decide which online meeting platform to use.
Hope to see you there!!
Navigating and Refactoring Code, and other Productivity Tips
Any decent IDE must have features to allow developers to navigate and work with code. In this session, I’ll share how I use ReSharper, Visual Studio, and VS Code. More importantly, I’ll share the reason and the thought process. Remember: it’s NOT about the tools!
I have worked remotely on and off a lot over the last 20 years or so, I think I end up taking for granted some aspects of it and can’t quite see why some people are having a hard time with that. Some recent conversations have made me take a step back and put some more thought into it so I can best help other folks adjust to this.
On one recent conversation with a friend and co-worker, he mentioned his team’s latest sprint has been very successful, despite the work from home scenario. I asked to what he attributes that success, to which he answered “pair programming”, and that reminded me of a great success story I’ve had with a team 10 years ago!
In fact, we were so happy back then with how the team was handling remote work, that my good old friend George and I even put together a talk about it, delivered at a Houston Tech Fest. So for our Virtual Brown Bag meeting last week, we decided to revisit that content, checking what processes and tools we used 10 years ago, how well they stood the test of time, what we’ve changed since then, etc. Our realization is that the processes are still pretty much the same, whereas some of the tools may have been replaced, but still sticking to the same intent.
If you’d like to check out that conversation, sit back and enjoy the video!
P.S.: And I hope to see you online at our Virtual Brown Bag tomorrow, April 30th, 12-1pm Central Time.
Very often when I realize I’ve been talking to individual people too much about certain recurring topics, I consider turning those conversations into new talks. And so it happens again! My brand new talk, “Trusting IT – Bridging the Gap Between Vision & Execution”, makes its debut at an upcoming free virtual event brought to us by Improving. You can register here.
Below are the talk’s Title and Description. I’m putting my heart and soul into this one and I hope you’ll enjoy it as much as I am.
Trusting IT – Bridging the Gap Between Vision & Execution
As a developer:
- Have you ever had to justify the time spent writing tests?
- Do you ever think “how can I make them understand this intricate code I had to write?“
As a non-technical person:
- Have you ever wondered why developers say a user story will take so long to implement?
- Do you ever think “maybe if I learn a programming language…”?
Have you all ever wished for improved collaboration between technical and non-technical people who trust each other?
Attend this presentation and learn how to bridge that large gap by building a common ground where everyone can better contribute to the success of projects.
You’ll learn how to improve communication and collaboration to make sure developers are delivering what’s needed by the business while doing the right things right (be that writing tests, refactoring code, etc).
Whenever we teach/learn how to write user stories, we usually use the “As a… I want to… So that…” format, like so:
As a <persona>I want to <have a capability>So that <value this story brings>
It’s not uncommon we end up writing stories such as this one:
As the system
I want to remove duplicate entries from my address database tables
So that I don’t have duplicates
I hope that story has made you cringe. If it didn’t, what’s wrong with you?
Thinking about the Purpose of a User Story, let’s ask:
- How does the story above help the business either make or save money?
- Is “the system” a valid persona? (…maybe one day it will be, I guess…)
- Why is it important that addresses are stored in database tables (as opposed to documents or CSV files)?
- What’s the problem with having duplicate addresses?
- How does that story bring value to the business?
What if we rewrite the user story in this manner:
As the marketing manager
I want to send direct mail with no duplicate addresses
So that I save on mailing costs of marketing initiatives
- The story brings value to the business by saving on mailing costs;
- It makes it clear that the value is important to marketing managers;
- It indicates that sending direct mail for marketing initiatives is the business operation affected by the story;
- No technical details are specified;
- Any non-technical person can understand it.
With all that being said, here’s a question: what’s the single most important part or sentence in that story?
Here’s the answer: the “so that…” part. It is the part that tells us the purpose of the story. The why. It tells us how the story brings value to the business. It tells us why somebody is willing to pay money to see that story implemented.
Last But Not Least?
So, why is “so that…” the last part of the story?
Why build the suspense?
We shouldn’t expect anyone wanting to create cinematic versions of user stories, so let’s cut right to the chase and highlight the most important part of the story, by rearranging it like so:
In order to save on mailing costs of marketing initiatives
As the marketing manager
I want to send direct mail with no duplicate addresses
Right there, Start with Why. But first, let’s give credit where credit is due: I’ve first learned about changing user stories to go from “so that…” to “in order to…” on the Cucumber website. It made a lot of sense to me (it still does!) several years ago and I stuck with it.
That approach is so ingrained into my way of thinking that when I see a story written as “As a, I want to, So that”, I end up reading it backward (by reading the “so that” part first).
Why does it matter?
Over the years, I’ve sat in many meetings (Sprint Planning, backlog refinement/grooming, etc.), where the leader reads the story out loud following a pace that looks somewhat like this:
- “As a…”, spoken kind of fast, but the words can still be clearly heard;
- “I want to…”, spoken slowly, emphasizing the “want”
- “So that”, spoken fast, words hard to distinguish. More of a slur, really. That’s it: the person is slurring, not speaking.
But wait: if the “so that” is the most important part of the story, why are we slurring through it like that?!
There’s a lot of focus going into the want part, but not as much going into the why it’s wanted. In fact, I’ve seen a lot of time spent discussing “want this” and “want that”, and from little to almost no time spent on the why.
First Things First
My recommendation to people has been to start every user story with “In order to…”. If we don’t know how to finish that sentence than we don’t know what the value of the story is, and therefore, no time should be spent on anything else. Who the persona is (“as a…”) and what is wanted (“I want to…”) become irrelevant if the story lacks a strong why (“In order to…”).
In the example story above, after finishing the “In order to save on mailing costs of marketing initiatives” sentence, someone might raise a hand and say something like “I’m aware of a special service deal where we get significantly reduced shipping costs over X number of letters”.
At that point, the focus of the conversation could turn to figure out if there’s any chance that the cost to build and operate the new future would be more money-saving than the available service deal. Yes, software is NOT always the best solution, can you believe it?
Consider Adding Context to the Persona
I’d also recommend considering adding a context along with the persona in a user story, as described in this blog post. Take this contrived example:
In order to end my hunger
As a person
I want to get some food
Is the person really hungry for food? Maybe the person is just thirsty (the feeling of thirst and hunger can be very similar), so while the person may “want” some food, maybe what she “needs” is water. Adding some context to the persona would help clarify things:
In order to end my hunger and not get a stomachache
As a person who hasn’t eaten for 18 hours
I want to get some light food
Often, after adding context to the persona, we may end up seeing bits of information that should be added to the story in order to further clarify things, as it happened with the example above (chugging down a heavy meal after a period of 18 hours without eating probably wouldn’t be a good idea).
As a User?
And please, if the “As a…” part of a story reads “As a user”, take a step back and think a little harder about that; user is too generic of a persona!