How to step up your automated tests game

fixing unit tests

This is a follow-up of my previous post here. If you’ve ever had to write automated tests, you might have some bad memories lingering around. Automated tests have a way of becoming troublesome as time goes by. You end up spending more time fixing the tests than adding actual features. When that happens, you don’t care about test anymore, you don’t run them, you’re not worried when they fail and you just don’t add new ones. That leads to brittle code and things break really bad really fast. I’m here to tell you there is a way to keep automated tests manageable.

Simple is better

Simple tests are the better tests. They should be simple to read, simple to run and simple to add. Clean up the setup. Wrap complicated setup in nicely named functions. Keep the logic linear. You should never have an if in your tests and you should scarcely use for loops or other exotic structures and/or logic. It’s as simple as this. When you write simple tests, you get easy to maintain tests.

Be precise

It should be clear what you are testing. A very good tip I have for you on this is to use the given/when/then format. What is that, you ask?! It’s a way of explicitly splitting your tests into three distinct sections.

Given should deal with setting up the data. Everything your test needs to run smoothly. This includes, but is not limited to: seeding the database, adding any mocks required, pre-generating any data and constructing all the models that you will use later.

When is where the magic happens. You test whatever you need to test here. You should make sure it’s obvious what you are testing. If you feel you’re not being clear enough, then wrap the call in function and name it accordingly.

Then is where you check your data. You have to make sure your test did what you want after all. The checks should be clear and self-explanatory. Additionally, the checks should be the direct effects of the when section. Don’t do unrelated assertions, even if they are true, unless you like to fix unrelated tests for every change.

I prefer using comments prepending each of the sections to make the tests even more explicit.

Test one thing at a time

Try to keep your test scope as narrow as possible. There is a two-fold benefit to this approach. First you get a clean list of failing tests when you break something. Hopefully you have named them well enough to diagnose the issue with just that. Secondly, updating the tests to match the code after you make a change should be a lot easier.

As I have hinted, naming is important here. The test name should hint at the non-trivial setup required and contain the assertion being made. A big red flag is if you find yourself having to use and in the test name. Some examples of some good test names are:

if the user is unauthenticated the server should return unauthorized
if the user is unauthenticated the server should log the request

A bad test name would be:

if the user is unauthenticated the server should return unauthorized and log the request

You’re actually trying to test two behaviors here.

Can you think of any other useful advice that could help us all with our tests.

Testable code design patterns

As you might have realized by now if you follow this little blog (and you should), I’m a huge fan of automated tests. If you’re not, I assume it’s because you either don’t find them useful, or you find them hard to add.

Tests are useful because code breaks. My code, his code, everyone’s code breaks eventually (and that includes yours too). What you aim achieve with automated tests is to break your code before you deploy it. It’s much easier to think of a fix when you don’t have people running around with their hair on fire because the site is down. Also, it doesn’t do you any good as a programmer to write code that breaks as soon as they leave your door.

Now that we decided tests are useful, let’s see what we can to make them easier to add.

Write testable code

You should see testing as an integral part of development. In the same way a programming language and/or framework impose some patterns in your code, in the same way the decision that you’re adding tests should change your code. I’m here to tell you there is a way to make your life a lot easier. There are a lot of design patterns out there. Together we are going to riff through a few that should make testing your code a piece of cake.

If your code is easy to test, you will test it more. With this you can ensure a more resilient project in the harsh production environment.

Dependency inversion.

You have more details here. It sounds a bit fancy at first. It’s not. The idea is this: Whenever a function/class depends on another module, they should get that module as a parameter and not instantiate it themselves. Combine that with automatic dependency injection and you’re in business. Mocking and stubbing will never be an issue again. You can completely isolate modules and mock out their dependencies. From then on the sky’s the limit on what you can test.

State is evil when testing

This is not so much a design pattern, as it is advice. Nothing will make your head hurt more than handling global state in tests. Then why don’t you save yourself the trouble and keep the state to a minimum. As a rule of thumb, all functions should be stateless. If called with the same params, then they should always return the same result.

If you remove state from modules, the problem becomes how do you deal with modules that inherently should have a state, things like db connections and network connection. My approach on this is to isolate the state in a shared model. Then pass that model around anywhere it is needed.

Be in the right mindset

Accept the fact that you’re going to have to test whatever you are working on now. Always keep that in mind when writing the code. Thinking How in the world will I test this, is a good way to spot anti patterns and code smells early on.

You have to think about module dependencies and if you should another. Then where should the logic and state live. Every now and then, you get to a point where you need to do some hackish workaround because the testing framework just hates you. That is OK, it’s just like every other workaround you had to do to get past a framework limitations.

These may not all be design patterns. However, I do feel that the advice above covers the gist of what you need to do so that automated tests don’t become a burden. See you next time with some advice on how to write better tests for your code.

Be a more productive coder – Some metrics you should use

What does make a good coder ? Is it the number of lines of code they write in a day ? How about the number of works they put in the office? Maybe it’s how fast they code, how quickly they solve any given issue? Well, as you might have guessed by now, I don’t fully agree with any of these statements. Here are some metrics that better reflect your proficiency as a  code writer.

Is your code easy to understand

You should always write readable code. I have an article here if you need a more in-depth opinion on what good code means. Being a productive programmer it’s not just about you. Your part of a team, a team of programmers who need to spend time understanding, maintaining and changing your code. If you have to spend a few more of your minutes to spare a few more minutes of some of your teammate’s time, then you have made the whole team more productive. Neat, isn’t it?

Forget the clever hacks and neat tricks you are tempted to use. I know, it’s hard to give up on a clever little idea you have. It happens to all of us, all the time. When it makes the code hard to read, it’s probably not worth it.

Is your code correct

This should be pretty obvious: Don’t write bugs. What it’s not obvious, however, it’s how costly bugs actually are. Tiny, little bugs cause big overheads. The QA need to file a bug report, it needs to be prioritized, scheduled into the current development cycle (call it sprint, or whatever you are using). Someone needs to pause their assigned work and start fixing it. This means they need to get up to speed with the area of the code the bug lives in, write the fix, review, and the QA needs to test it again. When you think about it this way, adding a few more automated tests and spending a couple of minutes manually testing your code doesn’t seem that bad. Am I right, or am I right?

Is your code flexible

To know if you are doing this, just remember what were your feelings the last time you were asked to change something you wrote. If your first though was: Noooo! Please don’t make me do that!!! then you should pay more attention to this. Keep in mind that requirements change all the time, and that the code is something that is constantly evolving. Therefore, you should write the code on the assumption that you will need to change it at some point, because it’s a safe bet you will. If you spend your time wisely now, you will save a lot more time later. Flexible code is an investment in your future productivity.

An important disclaimer here. Don’t overdo this. It’s a fine line between keeping your code flexible and spending waaay too much time preparing for a change that may never happen. If you are unsure, just ask someone. The PM/tech-lead/client should know how likely a change is, hence they should be able to give you the answer if it’s worth doing it. Design patterns are a good way to ensure you’re not overthinking the issue. Use them!

Summary

In the end, it’s not about how many lines of code you can write, neither about how fast you go through this current development cycle. What makes a good coder is how good they prepare their code for the next issue, and the next and so on. Therefore, in the long run, you are way more productive if you spend some time today to make your work easier tomorrow.

Do you know any other useful metrics that a programmer should use?

How to meet your deadlines – A quick guide to ensure you are never late

Oh, the dreaded deadline! You have a week’s worth of work to do by tomorrow. If that has ever happened to you, then you should know that feeling well. In the following lines I will try to give a few tips that should alleviate that feeling. Let’s begin!

Don’t underestimate the work

This is something that needs to be done in the planning stage. Estimating the amount of time a piece of work is going to take is as much an art as it is a science. It takes a great deal of experience to do it right. In most cases things are going to take longer than expected. A process that works really well for me is breaking down the work into the smallest piece of self-contained work (call them tasks, tickets, whatever you want, the concept remains the same). It is much easier accurately estimate a small piece of work, than a big one. When you have a list of small and self-contained tasks you can begin to add estimate them. At the end, add the values together and you have a deadline.

Give yourself some slack!

Estimating a task involves accounting for the unexpected. Unexpected events have an unbalanced effect on the deadlines. This is a fancy way of saying that bad things happen much more often than good things. Things will break, and they will need to be fixed, you will have to wait for other teams to be done with their work, specs and assets will be late, computers do break from time to time and that will certainly affect your deadlines. The more dependencies you have on your task, the more slack you need. This may sound extreme, but I usually add a 30% slack on the dev time and even that proves to be insufficient from time to time.

Be honest with the stakeholders

Do not commit to more work than you are able to do! Remember, in the long run, doing things right is much faster than doing things fast. If you need to rush through work, you will unavoidably make mistakes that tend to add up over time and slow down future development time. You have probably heard this before, but I’m going to say it anyway: Do quality work from the start, even if it takes slightly longer now, it will save you tons of time later down the road.

Track progress as you go along

It is much easier to make corrections to your course as you are traveling towards your destination. How does this translates into a helpful tip? Glad you’ve asked! To sum up: It’s easier to correct for small delays than large ones. That sounds reasonable enough, right? The trick here is to spot delays as early as possible. If you have a timeline for your project, you should be able to say at any moment if you are on track. When the work slips, it’s going to be easier to account for a small delay. By doing this regularly, it should never come as a surprise to have to do a month worth of work withing a week.

That’s all we have for today! Hope you have enjoyed it! See you next week!

How to write better code – 6 things I did not found on the first page of google search results

I know there are millions of answers to this question (I for one get 484,000,000 hits on google when I search for How to write better code). They all seem to revolve around the same general idea, so I will not be repeating that. You are free to do a google search yourself and read through those.

I will however, be sharing some tips that I picked up that you may find useful. Here we go:

1. Do not compromise

We all know when we are doing a hack, or a nasty work-around because the right way takes too long. We know it, and we still do it. Maybe it’s late in the day, and we just want to go home, maybe the deadline is closing fast and someone is going to be really mad if the project is not done on time or maybe we just can’t be bothered to do things the right way. My advice to you here is, you guessed it, do not compromise code quality. Compromises made now will slow down development in the future, which will in turn lead to more compromises and so on and you will end with a mess of a project that you will need to maintain. And that’s no fun 🙁

2. Less is more

A programmer’s proficiency is not measured in the number of lines of code they write, it’s more like the opposite. The more code you write, the more chances to break said code. The odds are against you. If you have to think twice as long on task to write half the code, do it, it totally worth it.

3. DRY

Don’t repeat yourself! I’ll say it again: Don’t repeat yourself! (pun intended). In my experience, the worst codebases I had to deal with are the ones which chose to implement the same logic in many (and often quite creative) different ways. Don’t do that to the person maintaining your code. If you have to use the same logic in two different places, be sure to have the code in one place.

4. Follow the existing pattern

This is an extension of the previous topic. Please try to avoid adding a new pattern to the project, unless it’s really necessary. One style of doing things should be enough for one project. I accept that this may be hard. Especially if you are just starting on a new project that seems to be doing things differently from what you are used to, but don’t give into the temptation. Keep the project simple and follow the existing pattern, even if it means more work for you now. And remember: It will get easier with time.

A notable exception to this rule is the process of replacing the existing pattern with new and improved one. If you are doing that you can have two patterns in the project at the same time, while the old one is slowly retired.

5. Automated tests

I really don’t see nearly as much as these that I would like to. If, at any point in the development process, the thought that you need more tests crosses your mind, you are probably right. As you might have guessed if you follow my blog, I’m a big fan of automated tests (maybe enough to write an article about them some day). Automated tests are great, and they have many advantages to them. They give you the confidence that what you just changed did not break any hidden functionality. They serve as an always up to date documentation for the project (as long as they are passing).

6. Common sense must prevail

We need to take a step back now and acknowledge that each and every one of the points above can be taken to extremes. As you might expect, taking internet advice to extremes is not advisable. So I leave you with this: Whatever you do, don’t forget to use your basic, human, common sense. You are free to bend and adapt the rules so that they make sense given the situation.

Dealing with legacy code – the bane of our existence

Unless you are really, and I mean really, lucky, you are bound to be stuck on a legacy project with a thousand-year-old codebase. Maybe not a thousand years, but close enough. If it’s any like the code I have been working on, it’s big, really big, it’s complicated, no one really understands how it fully works, and it’s riddled with anti-patterns. What to do?

Burn it to the ground and start fresh

So, delete the codebase and re-write everything in a nicer language, with design patterns and all the bells and whistles.
Phew, that was easy, we didn’t we do that from the beginning?! Problem solved! Let’s get back to checking Reddit now!

Getting back to earth

OK, so burning everything might not be a sensible solution. More often than not the code took years upon years to write and is worth a small fortune. The client is not just going to let you throw that all away and sit tight while you are starting again from scratch. You’re in a bit of a pickle, you can’t live with the code and you cannot get rid of it. What to do ?!

The only sensible solution at this point is to slowly improve the codebase. It’s a slow and time-consuming process, so don’t expect your life to improve overnight. We now have a plan, let’s see how we go about putting it into action ?

Test it, test it, then test it some more

You will need to improve the code in the future, however, it’s really hard to do that when you’re unsure if you have broken it. This is where tests come in. Unit tests, integration tests, performance tests, you name it, you probably need it. The more tests you have, the more confidence you have that the changes you made are not breaking anything. In addition to that, writing tests help you better understand what the code is doing. Hooray for you!

Isolate and control access to the old world

The plan here is to control access to the old code as tightly as possible. You can do that with nicely designed interfaces and wrapper classes. Here where the tests we previously talked about come into place. Once you know you’re not breaking functionality, then you are in a position to do some serious refactoring. Every new functionality you add should use one of the nice interfaces. If there are none, add them! If it suits your project, you can turn the old world into a web interface that can be safely isolated from the shiny new code you are adding.

Slowly retire the old world

Since the legacy code is now contained and you can control access to that dusty old thing, as time goes by you can gradually remove the calls to it. Once there are no more calls, that is when you are ready to remove that chunk of code. Do that over time and the big monolith you begin with is starting to look smaller and smaller. You may not be able to fully retire the whole legacy piece of code, but you can at least save your team the trouble of always having to work with it.

Slow and steady wins the race

I must warn you, this is NOT a quick process. Depending the size of the legacy code it may very well take years to make a dent on the original codebase. You need to exercise patience. The motto for the whole process should be Leave the code better than you have found it. You may be tempted, especially when the deadlines are tight, to cut corners and go for the easy, messy solution. Do not do that!! I’m saying it again: Do. Not. Do. That. This is how we got that big mess we started with. You cannot solve a problem by doing the same thing that caused the damn thing in the first place!

 

A super short crash-course in negotiation

I’m sure that at some point in your career you will be in a situation where you need to negotiate. It can be a negotiation with your boss about that big promotion you were hoping for, with a client about the shiny new project you want or maybe with a colleague about the temperature of the AC. Well, whatever that situation might be, it’s better to go in prepared. Here are a few tips and useful advice you can use.

Know what you are negotiating for

The first thing you need to know when you are about to start a negotiation is what do you want. Sounds simple enough, however it’s an important part so DO NOT SKIP OVER THIS! You need to have a clear idea on what you want from the negotiation. Make a plan and stick to it. This is the ruler you evaluate the negotiation on. It’s pretty much the one thing you should not compromise on.

BATNA

Again on the preparation side of things: Batna stands for Best Alternative a Negotiated Agreement (some background on the term here).  In short, BATNA is your backup plan in case the negotiations break down. It’s the worst case scenario, if you are unable to reach an agreement. You need to have a plan on what to do if things go south, what will it cost you and how you plan to deal with it. You’ll use that in your negotiation to gauge the value of the agreed solution, and quickly dismiss solutions that are worse than your BATNA so you don’t waste time on them. Also it should help you keep calm if you know you’re covered (sort of speak) if things don’t work out. The better you BATNA is, the better the position you are negotiating from is, so pay attention to this!

Establish rules

Negotiations should be fair (or at least you should try to make them fair). Fairness is a relative term and people don’t often agree on what it means exactly. Before you start negotiating, you should first agree with the other party what fairness means. As a professional (and I assume you are one) you should always negotiate fairly (this means do not try to cheat, it’s bad form). If you cannot reach an agreement on what fair means, you can just defer that judgement to someone else. Basically ask a friend you all trust if he thinks you’re being fair. It’s not that hard is it ?

Lateral thinking

OK. So much about preparations! It’s time to start negotiating! Yay! Lots of people tend to think about negotiation as a zero-sum game, if one party wins, the other certainly loses. Spoiler alert: It’s not!  You should keep in mind the reason you are negotiating (see first part), but other than that, everything goes. Most often than not your main focus it’s not the other party’s main focus so it’s entirely possible for both of you to get what you want. Try to find things to sweeten the deal. Things that are cheap for you to offer, but have a big impact for the other party. For example, to make a project more appealing for a customer you can offer training sessions for the users, or provide some form of documentation. You get the idea!

Well, this is pretty much all I had to share about negotiations. Hope it helped! Cheers!

The tells of good feedback

So, what makes a good feedback ? I know there are a lot of articles out there about this, but that doesn’t stop me from giving my two cents, so bear with me.
Weather you’re giving feedback or receiving feedback, I find there are some attributes that make some feedback’s better than others.

Actionable

The purpose of feedback is to help someone improve. If the person receiving the feedback has no idea what they can do to improve themselves, then the feedback is like a bald hedgehog (pointless). If you want meaningful feedback, then it should refer to specific actions the person can take to improve themselves, which leads me to the second point:

Concrete

You’ve all hear it: You are doing perfect, keep it up! (followed by a warm pat on the back). This is useless! First of all: I have no questions that you are an overall great person, but, whoever you are, there is no chance that you cannot improve! And second (and this is more to the point): What am I supposed to to with that information ?! Where do I go from here ?! Certainly there are some things that I am doing better than others and I would like to keep doing more of those. Feedback should focus on concrete facts. Even if you are a superstar and you are good at everything you do, there must be some aspects of your work you could be great at, so try to focus on those.

Short

This one may sound a bit off at first, but feedback should be short. You do not want a laundry list of items on your feedback. We are not good at multitasking (regardless of what you might think), so focusing on a lot of things is just not going to work. For feedback to be truly useful you should find a few points that you can improve upon. I would recommend 3 or 4 key points so you can focus on those. If you tend to get a lot of items on your feedback list, it’s probably a sign you should have feedback chats more often.

Measurable

This one is sort-of dependent on the type of feedback you are getting, so it might not apply in some cases. It feels good to know you are making progress, and it’s useful to know when you are not, so why not have that information available for you to judge. This is easy if the feedback is accompanied by some kind of metric.

And now for the fun bit! Here are some examples of feedback that can be improved upon (granted there are a bit extreme examples, but I trust you’ll get the point)

  1. “I liked your presentation! It was wonderful! You should do more presentations like that! ” versus “I liked your presentation! It was the graphics that I liked the most! They really help get the point accros! Keep doing those!” 
  2. “That meeting went bad! The clients are not happy with us! We should change that on the next meeting!” versus “The meeting went bad! We went in there unprepared and we were not able to address their questions! On the next meeting we should make sure we fully understand the requirements before the next meeting.”
  3. You have been missing your deadlines lately. You should focus more on being on time.” versus “You have been missing your deadlines lately! Can you think of anything that takes time necessary so you can remove those ? “

 

 

How to deal with issues in production – the short version

Okay, imagine the following scenario: You’re happily going about your day, coding away, without a worry in the world, and then this hits you: “There is something wrong with the production app” (well, maybe not this exact message, but you get the idea). What do you do?! How do you go about fixing the problem and go back to your everyday life?

1. Calm down

Yes, things are bad at the moment. However, this is not the time to lose your head and run around with your hair on fire. You need to have a clear mind in order to focus on the problem and easily find the solution. Go to your happy place and come back when you are ready to get to work.

2. Calm down some more

If you are anything like me then you probably are not calm enough to think clearly. You should calm down some more.

3. Investigate the issue and understand it

OK, now we are ready to start doing something about the problem. The first step is to understand the root cause of the issue. Maybe someone deployed something they shouldn’t have, maybe the data became corrupted or maybe, and this only happens once in a blue moon, maybe there this is just a misunderstanding and there is no issue at all, in which case: Congratulations, you solved it.

At the end of this stage you should be able to at least answer the following question: When exactly does this happens ? 

4. Estimate the impact

Now that we know when the issue occurs, we can start thinking about who does this issue affect. A quick and dirty estimation should be enough. Some useful classifications are: critical (everyone is affected and everything is broken), medium (there is some impact, but the project will probably survive), low (this issue affects only a handful of clients/users), minimal (yes, there is an issue, but unless someone looks really, really hard they’re going to miss it).

Based on the impact of the issue you need to decide if you should fix this now, or later.

At the end of this stage you should be able to at least answer the following question: How bad is it ?

5. Calm down some more

OK, things are starting to clear up a bit now. You know what the problem is and how bad it is. Take a deep breath, decide when this needs to be fixed: either now or later.

6. Track down when the issue was introduced

If you use a versioning system (if you don’t you really, really should), use that to track down the commit that caused the issue. Look trough the code and use a sandbox environment (if any available) to figure that out.

At the end of this stage you should be able to answer the following question: What is the exact cause of the issue ?

7. Fix the issue

Now that you know what causes the issue you are in the best position to start fixing it, so go do it, be a hero and save the day.

Congratulations!! You fixed it!  You can go back to your happy life – crisis averted.