Top 8 Signs Your Writing Bad Unit Tests

If you have been developing software for a long time, then you can easily relate to the importance of unit testing.  Experts say that most bugs can be captured in the unit testing phase itself, which eventually gets passed on to quality teams.  Here is a list of my top 8 signs your writing bad unit tests.

1) Test passes but not testing the actual feature

Believe me, I have seen test cases in some projects that appear to be doing lots of work in the code but in reality, they were doing nothing. For example – a test that’s sending requests to the server and no matter what the server responds with, the test was passing.

Beware of these such test cases taking place in your code repository by doing strict code reviews. Once they make their way in your code base they will become a liability on you to carry them, build them, and running them every time but without adding any value.

2) Testing irrelevant things

I have seen developers checking multiple irrelevant things so that the code passes with doing [something], well not necessarily the correct thing. The best approach is to follow the single responsibility principle, which says, one unit test case should test only one thing and that’s all.

3) Testing multiple things in assertions

In the previous sign, the test was testing irrelevant things. For this sign the unit-test is testing the correct items,  however, there are too many items in one test case. This again is a violation of the single responsibility principle.

Well, please note that I am not encouraging the use of a single assertion per test case. To test a single entity, you might need to use multiple assertions, do it as needed.

For example, one API which takes some parameters in a POST body then creates the Employee object and return it in response. This Employee object can have multiple fields like first name, last name, address etc. Writing a test case to validate only first-name, then another for last-name and another for the address is duplicity of code, without any value. Don’t do it!

Instead, write a single positive test case for creating the Employee object and validate all of the fields in that one unit test. Negative test cases should be written separately doing only one thing and one assertion in this case. e.g. One test case for blank first name, one test case for invalid first name and so on. All such negative test cases can be validate using a single assertion which expect an exception in response.

4) Test accessing the testee using reflexion

This one is real bad. Trying to change the testee to suit ones need.  The test will blow up when the testee may refactor some of the code.  Do not use this or allow to be used either.

5) Tests swalloing exceptions

I have seen my fair share of such test cases. They silently swallow the exception in little catch block at the end of the test case. And worse is that they do not raise a failed alarm. Exceptions are signals that your applications are trying to communicate that something bad has happened and you must investigate it. You should not allow your test cases to ignore these signals.

Whenever you see an unexpected exception, fail the test case without failure.

6) Test which depends on some excessive setup

I do not like test cases that require a number of things to happen before they start testing the actual thing. Such a scenario could be an application which facilitates online meetings. Now to test whether a user of a particular type, can join the meeting, below are the steps test is performing:

  • Create the User
  • Set user permissions
  • Create the meeting
  • Set meeting properties
  • Publish meeting joining information
  • [Test] User join the meeting
  • Pass/Fail

Now in the above scenario, there are 5 complex steps which must be setup before actual logic is verified. For me, this is not a good test case.

A correct test system will have an existing user present in the system for this activity, at least. This will reduce at least two steps in the test case. If appropriate, you could have a few already created meetings to make this test case really focused.

Another way to make it correct is by using mock objects. They are there for this very purpose.

7) Test compatible to only developer machine

This is not widely seen but sometimes visible when written by freshers. They use system dependent file paths, environment variables or properties in place of using common properties/paths.

8) Tests filling log files

This never seems to be an issue until you need to perform a deep debug then make life hell for debugger who is trying to find something hidden in those log files bloated with wasteful messages.

Tests are not for debugging the application, so do not put debug statements in your logs. A single log statement for Pass or Fail is enough. Believe me.

 

These are my thoughts based on my experiences. I do not expect you to agree with me on all of the above points or you might have some other opinion which is perfectly cool too.

Is Web Development Dead?

Personally, I’d give it about 5 to 7 more years, maximum 10. I’d even kill off web design alongside it. I am talking about website development, specifically where the developer is concentrating on writing code that manifests directly on a website, rendering HTML and Javascript.

Web development is a broad term though because API development that manifests as JSON data across HTTP requests could also be considered web development.

When web design was a top role for designers, about 12-15 years ago, it was because design demands were rooted in print design. This was before mobile phones were a viable browsing tool, so you could bank on having consistent screen sizes. This was also at the time when broadband for the home was common enough that the average person could view a complex website that was so abundant with a skeuomorphic design that the bandwidth requirements were high, but the quality was high as well. As a result of complex design, web development was also a dominant role, because it was a lot of work to develop alongside that complexity of the design.

But as mobile device usage has grown, and the separation of concerns from websites being king, to instead a combination of websites, apps, and other services, the website’s need for being gloriously designed decreased. Given that we continue to have an increase in device variety, this trend is not going to reverse itself. A simple, clean design is best suited to auto-adapt to the variety of screen sizes and types that will be available for decades: visually, this is all the way from a wristwatch to a billboard.

Based on that, the majority of website development has already shifted to more data-centric work, above design-centric. If I’m viewing website content on my computer, the design might matter to me. But when I switch to my phone, design (at least, heavy graphical design) is only going to get in my way. The design components that will matter on my phone are color, typography, readability, etc. There will still be a need for designers, but far less than what we needed a decade ago, and certainly less than we need now. Designers will need to branch into more cross-device creative direction than simply “website design.”

And developers are already heading that way, by avoiding design and focusing on API development, which is critical for driving website content while also driving the two other most important technologies needed right now:

  • Apps, which are currently manifesting primarily as mobile apps, but which also include voice-activated apps, and VR apps (through independent devices like what Google tried with Glass), and
  • Integration, which is the data-sharing aspect of API development that allows the data from one app to be integrated with the service of another app to provide suite-like features across disparate systems.

When a design is needed, most of the existing frameworks can already handle 95% of the design needs a company has. What we’ll be lacking though, unless the trend changes, is qualified business experts who can properly capture web application needs from business owners to develop solutions that fit company requirements. The demand will be on making custom applications at a fraction of the cost of what it used to be. The more APIs there are out there to perform the functions we need, with integration at their core, the more a website is just going to be a clean merger of technologies from a variety of sources, and design is going to remain minimal, because that same content needs to adapt to varying phone sizes, a watch, a lens over my face, an audio interface reading back to me, VR projections from a headset, and so forth.

So web design and development as we know it today, is going to be mostly gone within a decade. API development, app development (in many forms) and systems integration will be the primary focus.

If PHP “does’t scale” why use it?

I would summarize:

The main issue is that server time is cheaper than developer time.

A scripted language like PHP (or Ruby, etc.) takes about half as much time to program as bytecode or compiled language like Java (or C, C++, etc.).

So if you have a team of 10 developers each paid $100K, then you are paying out $1M in salaries. If you replace Python with Java, now you need to hire 10 more developers and pay out another $1M. In exchange for what, saving $50K of server time? Obviously, that’s not worth it!

If you already know PHP then go with it. Especially if you want to get to market as soon as possible to have an early mover advantage. Experienced PHP developers know that they could find out where to optimize once their site is in production and its features had been decided on.

This is a good example for other startups. The combination of rapid development time and flexibility on the front end and speedy service time on the backend is a good example to imitate.

As a professional PHP engineer:

The stigma that PHP applications don’t scale well comes from the fact that many inexperienced programmers choose PHP for their web applications. This is because PHP is an easy language to learn, integrates extremely well with Apache, and is supported on nearly every host in the world.

Inexperienced programmers will often use bad practices when writing code. Given enough of these bad practices littered throughout the web, written in the inexperienced programmer’s favorite language, it’s easy to see why some people are averse to PHP.

There’s also, probably, a “holier-than-thou” attitude that some programmers have toward PHP (again, because of its simplicity).

PHP scales just as well as any other language when page caching and best practices are taken into account. There are plenty of well-used PHP projects to prove it.

Return of the Senior Engineer

To paraphrase Mark Zuckerberg, there is a widespread feeling that young people are smarter and senior developers are not needed. But, when you look inside most businesses, you see businesses that are being held back by a lack of senior developers.

What did the founder of one of the largest tech companies mean by this?

Many new startups typically take a year to produce something that is ugly, full of bugs, inflexible, poorly written and practically (but not absolutely) unusable. Then, in year 2, they re-write the entire product which is 10x better yet is plain, still full of bugs, still inflexible, poorly written in a different way and somewhat usable. Finally, in year 3, they re-write the entire product for the third time and, before it is delivered, the investors give up, the startup runs out of money and the startup folds.

This is one reason (but not the only reason!) that startup failure is so high. The startup built the wrong thing in the wrong way and paid the price in years of development time and millions of dollars of venture capital.

Differently, in the biggest tech corporations, the product just slows down and creeps along. After years, the product is reasonably attractive, has a “big” codebase and is not very flexible. New features are small and mundane, and, in the worst cases, simply visual (“a new coat of paint on an old car”). Developers add to the mass of code but simply don’t have the technical ability to see into the codebase and make the changes necessary to make big, new features possible.

First, is it reasonable to expect one senior developer unwind 2 years of design and code chaos, bring to heel a 10-person team of non-senior developers who continue to produce code and whip the product into shape in 6 months? Is it reasonable to hire Michael Jordan to lead your team of rookies in the mid-season and expect him, by himself, to win the NBA championship for you? Yet that’s what a lot of companies expect: that they can hire ONE person to supercharge an entire team or even turn nothing into something amazing.

At a startup, it’s possible that the right senior developer(s) could get the startup to year 2.5 in 1 year. Instead of having your developers finally producing a sell-able product just when it’s too late to matter, you can save a lot of time and some money.

At a big company, the right senior developer(s) can clean up your code base, make it possible to produce big, new features and actually produce big, new features. The focus should be placed on hiring those software engineers who have “experience” dealing with the software problem(s) you have and less about tossing warm bodies at the problem.

Great truths about computer programming

After sitting around with a few programmer friends of mine we came up with the following truths about computer programming.

  • Programming is 99% self-taught. See all that stuff you learned in that Python class? Yeah, you’re going to relearn it all when working on a real project.
  • There’s no such thing as a simple bug. A stupid mistake like leaving out a semi-colon or misspelling a variable name can easily take a week to find and fix and can cause significant loss of sleep.
  • The more code you write the more you shut up about what’s possible and what’s next to impossible. And the more you pity those newbies with that “Of course it’s possible!” mentality.
  • The language you use doesn’t matter. There’s so much fuss about which language is better for x or y. At the end of the day what matters is can you solve the problem? As a company manager, I’ll want to see a running system. Not a running (insert language name here) system.
  • Six months later, you wouldn’t recognize your own code. Documentation and comments are more of a survival tactic than niceness to whoever encounters it next.
  • Programming isn’t sexy at all. Try taking that girl home by telling her your heroic tale of saving an entire department by rewriting a recursive function to take advantage of a feature in the new server Intel chips to scale up their online orders. Then tell me how it goes.

How do Project Managers break down requirements into Stories?

A good product manager doesn’t “break down” requirements into user stories, they start with good user stories and work from there.

The whole point of using user stories is that they are how you communicate “requirements” to your development teams — by stating the user persona that you’re targeting, the task that user is trying to perform, and the goal that the user expects to achieve.

If you’ve already got a list of “requirements” then you’re not really using user stories for the purposes for which they were intended.

That said, you may start with a very large user story, such as “A new customer wants to set up an account so that they can access the product.” That story is way too big for a team to do in an iteration, if at all. We generally call these “epics” which can be broken down into “themes” and then further broken down into “stories” until we get to something that a single development team can fully complete in a single iteration. For this story, that might look something like this:

  • Epic: “A new customer wants to set up an account so that they can access the product.”
  • Theme: “A new customer wants to confirm their email address so that they know we have the correct account information for them.”
  • Story: “A new customer wants to enter an email address so that we can contact them if we have information that is important to them.”

Communicating Agile “requirements” using user stories requires a completely different perspective and starting point than traditional product management approaches.

Why developers at Google consider Agile to be nonsense?

Responding to a junior developer who asked “Why developers at Google consider Agile to be nonsense?”

I said,  because in practice, “agile” is code for sloppy thinking & lack of design. Code first, think later. It’s also great for giving managers metrics they can report against that sound good (e.g, “tickets closed”), while not having to show real results – like sales, or lawsuits avoided.

Ok, let’s start with the four principles from the Agile Manifesto. The mindset of a hacker, not an engineer. You wouldn’t even think of applying them to a construction project – buildings would be falling down all over the place (if you could get approval to start construction, without detailed plans to approve), and all involved would be spending most of their time in court.

  • Individuals and interactions over processes and tools: For any complex piece of software, one needs to be very disciplined about pinning down design details (e.g., interfaces), about configuration management, about testing, etc. All of those are process intensive activities. The work can sometimes be reduced by good tools (e.g., a good version control system, automated build/test).
  • Working software over comprehensive documentation: A rather poor dichotomy. What does “working software” mean, without documented specs? How does one install, use, interface to, or maintain software without comprehensive documentation? Personally, I’m a big proponent of “write the documentation first” – otherwise, you don’t know what you’re building, or buying.
  • Customer collaboration over contract negotiation: Again, a poor dichotomy. In a lot of cases, contract negotiation IS collaboration, and/or defines the framework for collaboration. If you’re in business, particularly if you’re building custom software, the absolute last thing you want to do is spend a lot of time coding, only to have a customer tell you “that’s not what I meant.” Collaborate over use cases, storyboards, test & acceptance criteria, transition plans – but be damn sure to get to an agreement over what goes into a release, and how it’s going to be accepted, before starting to write code – otherwise you’re going to be out of business very, very, soon. (Might I add, that almost all companies try to insulate developers from end users. It’s kind of hard to actually get anything done if you’re spending all your time responding to support calls, or “can you just change this one thing?”)
  • Responding to change over following a plan: Yes, things change. But by and large, this says “code first, think later.” That’s just sloppy. If you’re fighting a war, agility is critical (“no plan survives first contact with the enemy”), or if you’re playing basketball. But if you’re writing software, you’re a lot better advised to “plan the work, then work the plan” – and if things change, change the plan. (One might note that most of what pass for “agile methodologies” – such as scrum – are really planning processes, just ones with very short time horizons.)

By and large, “agile” is code for laziness in up-front design. Just fix the bugs & add features in future releases. Sometimes, that works – Microsoft has been very successful in shipping quickly, then fixing things later. It also works fairly well for periodic releases of mature software (fix some bugs, patch some security holes, add a few features). And, it’s absolutely necessary if you’re responding to a security attack, at the moment.

It doesn’t work as well if you’re building buildings, or mission-critical software (no, we can’t recall the spacecraft after it goes off course), or laying rail tracks from the coasts, that have to meet in the middle of the country. Or if you’re a large team, building 100s of modules that all have to fit together – you’d better get the architecture, interfaces, and databases all pinned down well before writing a single line of code. Otherwise, you’re just going to have to do lots of re-work down the line, and God help you if you want to add new features, without having well-defined hooks built in from the start.

And then there’s: Dilbert Comic Strip on 1993-05-04

Why do programmers wear headphones while working?

There is one critically important reason to wear headphones while programming. When you understand the impact of this, it will change how you think about what it means to make things and what that process really requires.

Programmers wear headphones so that they won’t be bothered. That much is pretty obvious. The reason why being bothered is an issue is something I’ll get to in a moment.

You see, the modern workplace is designed to ruin programmer productivity. If I were to design an office space to maximize programmer output, it would look like the opposite of nearly every modern office space I’ve ever worked out of.

Actually, I now work in an office that basically maximizes my potential output as a programmer and it really does look like the opposite of most modern corporate offices.

The big gimmick right now in office space design is “open office spaces”. This is designed to improve collaboration (as if that is the great problem of modern work).

Open office spaces really exist so that it looks like everybody is busy working. It looks cool to see so many people busily walking around, talking, and in general looking busy. There is a sound component to it as well.

Open office spaces are loud!

But again, it looks and feels like an improvement over the previous decades’ bad idea – cubicle farms.

Also, open office spaces are cheaper than cube farms, so companies are saving money while making everybody look busy (even at the cost of huge productivity decreases).

In general, all of this is terrible for the actual act of programming.

The art of programming tends to rely on the same thing most art relies on – flow.

Getting into the “flow state” where you are focused on a problem deep enough to make connections and leaps and do your best work without “thinking” is where the real magic of programming happens. This is very similar to playing music, writing, and painting.

Imagine if Leonardo da Vinci was expected to paint the Mona Lisa in an open office space while his coworkers and manager would stop him mid stroke every 15 minutes to ask a question. Would he have ever painted it?

No, I don’t think so.

And yet, programming is a creative process that requires a similarly creative environment as most other art does.

Take authors as a similar example. Stephen King doesn’t “collaborate” to write his books. He sits down at the typewriter or keyboard and starts writing. Imagine if he had to do a daily standup about his latest few pages each day with a committee of his peers.

His work would suffer.

It turns out that to code well we rely on that same kind of process of getting into the flow and doing creative work with our minds. It’s how our brains seem to be wired for creative work.

People like Paul Graham have written about Makers Schedule vs. Managers Schedule before with a similar understanding.

It takes something like 5–30 minutes to get into a flow state. If uninterrupted, time distortion kicks in and a couple hours fly by and a bunch of code is created.

Every interruption resets the clock on that process.

So, what programmers need to maximize flow (and thus output) is blocks of 2–4 hours without interruption. Ideally, a whole day without interruption would allow for as many as 3 or 4 blocks of “flow”.

As near as I can tell, the average programmer tends to only get maybe one flow block a day. Sometimes a really diligent programmer will manage two or three flow blocks a day, but that doesn’t happen very often from what I can tell.

Headphones, especially noise canceling headphones (like the ones I’m wearing right now), are an effort by programmers to block out interruptions and stay in a flow state.

With open offices, email, slack notifications, coworkers tapping you on the shoulder, and so on…

It’s almost impossible to get to a flow state as a programmer.

So, my advice to you is simple. If you are a programmer trying to maximize the total productivity and flow blocks each day, wear headphones, avoid meetings, don’t check email, turn off slack, and basically go into a cave and write code.

And if you don’t have the option to do that, accept the fact that you might only be able to get one flow block a day and plan accordingly.

The typical stages in the career of a software engineer?

The career of a software engineer is not an easy one. It’s a tale of hardship and woe, filled with ladders to climb, and management to appease.

Level 1 (0 – 2 years):

You just graduated from college, a young boy with a young boy’s dreams, big eyes and a thirst for life. You start your work hoping to change the world, invent the next big app or make enough money to retire young and spend the rest of your life on exotic beaches, sleeping with models, who have a thing for nerds.

The first few months seem very alike, you’re assigned the same tasks every day, and your only job is not to screw up big time. It’s not what you were hoping for, giving your superior level of intellect and mad skills on the keyboard, but you’re certain that soon enough things will change.

You wake up one day after two years and realize that you’ve been living the same day and writing the same code over and over again. It makes you sad, but you feel a wind of change coming.

Level 2 (2–5 years):

You’re no longer a junior developer now, you’ve been promoted to a full-blown software engineer, basically a rock star, without the money, women, and fame.

You’re no longer being supervised by that old mean engineer who hates you because he knows you’re a better coder than he is. You’re being assigned small tasks, which you accomplish flawlessly -most of the time- and you can finally start feeling valued and useful. Everyone respects you now!… right?

Level 3 (5–10 years):

You’ve been doing this long enough now to be called a senior developer and assigned your own team. You’ve long have given up on your dreams to change the world, sleep with models or even make the next big app, after years of seeing people try to do it and fail, and having tried yourself to launch something and failed at it too, though you wouldn’t admit it, and hide behind the excuse of not giving it much attention or that people are not ready for your creation yet.

On the bright side, you get to handle big projects now and manage your team the way you want to. You also make a lot of money, which is what you always hoped for! But on the downside, you’re honestly not into coding that much anymore, your team is a bunch of brats who constantly think they’re better than you, without realizing you’ve been helping them grow all along, and you’re very sure they see you as the old mean guy who’s there to make their life hell, oh! And although you do make a lot of money, almost half of it goes to pay the rent or mortgage, because you had to move to an expensive city to get a big offer.

Level 4 (10–20 years):

At this point in your career, you have a choice to make, either you join management and become another suit who’s only concern is cutting corners to save money, and to meet this quarter’s earnings expectations, or to continue being a developer, who’s work now consists of managing multiple teams and making sure everyone’s doing their job.

You were always a rebel, you chose to code because it gave you freedom, heck, you wrote your best lines listening to Rock and Roll, so I’ll assume you’d go with continuing on your path as a developer.

It’s been years since you enjoyed coding or even went to the office excited about something. Last night you looked in the mirror and saw your empty dead eyes looking back at you, and you couldn’t help but remember the young boy with dreams and hopes who came into work with a big stupid smile and shiny eyes, and you decide to do something about this. You realized that just because you didn’t get everything you wanted, it doesn’t mean that your life or career was not fulfilling, and maybe its time for you to move on, and to start giving lectures or maybe even take a teaching position, to make sure that the newer generation does not end up the way you did.

Level 5 (20 years+):

At this point, you discover that you’ve been granted the powers of an almighty wizard, by the benevolent gods of coding. You magically turn to 24 again and have a spell for infinite money.

You get your happy ending after all, and you spend the rest of your life on exotic beaches sleeping with models.

What are the downsides to a career in software development?

The career has some similarities to the career of a professional athlete – it is very difficult to stay in the role for your entire career.

There are multiple reasons which are subtle and are not anything as simple as “older people can’t keep up” (absolutely not true).

Closer to the truth is that the industry really doesn’t have that many projects and leadership roles in teams that are creating the grand, new “something” from a blank sheet of paper. Rather, the vast majority of the activity is bug fixes and small tweaks to big blobs of legacy code. Most managers who are hiring for these roles would rather hire younger people who are still learning. Although this attitude is frustrating if you are an older person applying for the job, the attitude is not “evil”. Rather, if you are a manager and you have a lot of repetitive, banal work to do, you will naturally want to hire someone who is happy to have the work – and that would be someone young and inexperienced who is just starting to learn the ropes.

What about startups? Well… most startups involve trying to create something out of nothing and the particularly non-existent nothing tends to be money. Naturally, such startups love to hire inexperienced, young talent, feed them a grand dream of the wonderful life to be, hand out rolls of stock options (conveniently sized to fit in your bathroom’s toilet paper dispenser) and work that young talent 80 hours per week. If you are an older, experienced professional and you already have a linen closet well-stocked with such rolls of stock options, it is really hard to fit into this sort of organization…unless you are the founder and are the one handing out the rolls of stock options.

In my experience, very few software engineers really make it all the way from college to retirement with their hands still on the keyboard hammering out code. Somewhere along the way, the vast majority of them become managers, go into marketing, start selling real estate, found religious cults, get MBAs, or otherwise disappear from the scene.

In summary, my view is that if you are embarking on a career as a software engineer, you need to think about two phases: the first phase in which you actually write code, and the phase after that in which you do other things.

Hope this helps.