The dangers of the dogmatic approach

Throughout my career I’ve seen the same thing happen over and over: whole teams would be trained or managed by a certain type of person, only when they leave the company their legacy lives on, often times for the worse.

Here is an example. A small company grew to a point where they needed to start standardizing their work processes and even get an architect to help out and manage the knowledge gap of the various teams. This is wonderful. Nothing better than to see a small company grow. So an architect was hired, let’s call him Bob (not his real name), and he set forth to standardize some approaches that were needed at the time. Everything was grand.

The teams managed to do their work, given the time constraints and have a way of working that was manageable for the project sizes the company was doing. Happy days!

The company and the team size grew, as well as the size of the projects being built, and due to the tremendous work pressures that were placed on Bob, he decided that that wasn’t sustainable and decided to leave the company. A sad day for the company, indeed.

But this is where the trouble started. The team grew even more, and while the company was looking for a replacement the team didn’t know any better but to follow the path that Bob has laid out. In other words, Bob gave the team a hammer, and now all they see is nails. Don’t get me wrong, present them with a problem and they can hammer a solution together (pun intended) but now their solutions don’t scale well.

So after a few months a new architect got hired, let’s call him Charlie (not his real name). Charlie identified the problem that the teams had. And after a month or two of looking into projects he set forth to change things. Management gave him all the support he needed but a strange thing happened – the teams were reluctant to change. Teams would go rogue and would disregard his recommendations and would default to Bob’s way of working.

Charlie went to great lengths to try and help the team transition to the new way of working but ultimately they wouldn’t listen. They thought they knew better and they kept to their dogma as set forth by Bob. Fair enough, there were projects that were stuck in a certain architecture, and changing them would require an unrealistic amount of effort that couldn’t be commercially justified.

There are three problems here that Charlie faced: the company grew relatively fast, the size of the projects grew even faster and he was stuck in a company whose employees were blinded by dogma and nobody challenged it. Now, to be fair, Charlie couldn’t ask the company to stop growing, that’s just silly and he couldn’t change the size of the projects as they were set by the clients. So he attempted to change the team, by trying his darned best to open their eyes to new technologies, techniques and methods. He brought in a ton of books, started working with people he figured would have enough pull to start changing the mentality but even there he encountered resistance.

Everyone had their excuse: family, other obligations, not enough time etc. Everyone had a reason why not to change and nobody had a reason to change. This is a very dangerous position to be in. Especially for the company as the core team can’t scale well and they become the choke point for any future growth.

 

The company is now brought into a difficult position: they can’t let go the people that won’t change because they posses a lot of project related knowledge that is valuable to the company and it’s hard to find skilled people to replace the core team. Those employees still produce decent amount of code and the company doesn’t have any realistic justification to let them go. On top of that new project work is coming in and they have to delegate it to those people in order to hit their financial goals for the quarter / year.

Essentially, it’s like the employees have taken the company hostage. The company has to keep hiring more and more people, that’s just the natural part of its growth, but they can’t scale well because the employees refuse to change.

Personally, I have a problem with dogma. I challenge the status quo every chance I get. This isn’t because I’m some sort of rebel and I want to disturb the natural order of things. I just want to shake up everything to see if the model that was set forth is still fit for purpose. A company, at different stages of growth requires different ways of approaching things and I just want to make sure we’re not stuck because of some dogma.

As an example, in a startup, in it’s early stages, everyone is responsible for almost everything. There aren’t any standardized processes, there might be barely any automation and the whole point of that is that you spend as much time hacking away at a MVP and worry about everything else later, when you start getting customers.

A year or two down the line in that startup, when there is some cash flow coming in and the core team has been established and you have something out there, you then start thinking about automation and working a bit smarter. Five or so years later when everything has grown and you now have enough presence on the market and are no longer considered a startup, you then work towards standardizing some practices and workflows.

There are several stages companies have that fall under the growth phase, from the seedling phase to the maturity phase. And then there is the decline phase. One way you know if you are about to go bust if there is a serious increase of bureaucracy. And I’ve seen so many companies head towards there, even during their startup phase, thinking that’s how you know you are maturing, when in fact it’s how you know the company is actually close to dying a slow and painful death.

So what’s the lesson here? What should you take away from this article?

Well if there is anything to take away it’s to challenge the status quo. Ask yourself, is what we’re doing what is fit for purpose? Is there something out there that can help us scale better? Are we holding onto some dogma because we’re afraid to let go?

Are we standardizing things to make us look mature or are we experiencing so much chaos in how things are done that we need a standard to help us keep our sanity? Is the documentation we’re writing actually going to get used by someone or do we need to find different activities to fill in any downtime?

Also, just asking “why” can oftentimes lead to interesting answers, often times leading to very stupid reasons like: well that’s how we’ve always done it. Asking why is one of the most powerful weapons we have and we don’t seem to be using it enough. We just keep accepting things as they come and never question them. This needs to change if we are to grow, both as people and as companies.

Posted on Categories RantsTags , 719-888-1448

Test Driven Development a Pragmatic Approach

I’m going to start by making a very bold statement: In the last 30 or so years, no other discipline in software engineering has changed our industry as much as test driven development (TDD).

It doesn’t matter what programming paradigm you are using, doesn’t matter what type of code you are writing (embedded, web, desktop, mobile etc) and it definitely doesn’t matter which language you are using. In any scenario you need to know your code works and that it works well.

Tests give us that. But testing has given us so much more. When you look at it, past the surface, we get all the SOLID principles deriving from TDD practice. We can see more clearly when a unit of code is doing way more than it should be doing and thus needs separation. We can see when we tightly couple two components together how difficult it is to test it in isolation. And test driven development just naturally guides our design to be cleaner and better.

So I’m guessing you’ve heard about test driven development before, either someone mentioned it, or someone has slammed it for “being slow” or “unnecessary”,  and they might have their reasons for saying that, but they are, plain and simple, wrong.  Let’s explore why they are wrong:

TDD is Slow
Test driven development has been known to take a bit more time. In my own experience a team just starting to do test driven development will often be about half as fast as they once were. However, once a team picks up on the practice once it’s used to writing and reviewing tests, and understanding why one test is good and why another test is bad they will begin to operate at around 80% efficiency before they switched. So, you might be thinking, they actually were right, TDD is slow! On the contrary, nothing could be further from the truth. To understand why one must look at the bigger picture.

To give you an example suppose you are writing a REST API. Someone has put some architecture and design in the API and for better or for worse you are now stuck in it and you can’t go rogue and do something else. So if you are not writing tests, but you are still using some good practices, like coding to interfaces and using common patterns to solve problems, you may find your self in the following situation: in order to debug your code, which may be buried deep in some other part of the application, you may need to start the application, wait for the server to initialize, go through any authentication and authorization process required by the API and after several minutes or so finally be able to hit the endpoint that allows you to enter debug mode in your part of the code.

If you have to do this 10 or more times in a given day you are effectively wasting, potentially, hours of your time just on waiting for the damn thing to compile and initialize. Then you waster another couple of hours just on getting to the point in the application where you’d need to be. This is very ineffective.

Then even after you think you’re done you throw it over the wall to QA who then have to do the same, as well as try and break your code and send it back. In a scenario like this the team is only as good as their QA team. If they have a single bad day they could be letting bugs slip into UAT or Production, depending in your setup.

So why does this matter? Well, test driven development gives you the same feedback you would get with debugging, only it does that in a manner of seconds vs minutes. and if you think that’s good wait till you hear what else you get, completely free of charge! *insert your choice of cheesy infomercial salesman here*

OK, so we get our debug time to almost non-existent levels. What else do we get? Well, a computer doesn’t have a bad day i.e. logic is still logic at the end of a day, and unless the code has changed drastically a test that has passes yesterday should pass today. OK, so we get consistency in our QA process, what else do you get? Well, how about knowing if a refactor has broken the system? Yup, you get that. If a refactoring has been made, a simple check to see if anything is broken is to run your tests, it takes a few seconds to verify, and not days and weeks of exhaustive manual testing. OK, is that all or do you get more?

You get so much more. How about this: you know how when you have a very important sprint, you need to get some code out this sprint ASAP and you can’t afford to have anything distract you, and then a critical bug comes in from production and you are the one who has to solve it? Yup, how about no more of that, sounds good? Thought so. TDD saves time, the 5 min extra it takes to write a test is several hours saved in debugging and future maintenance. So the claim that TDD is slow is the same claim as saying that taking the money out of your pension plan now is what’s needed in order to be the first to enter pension in the future.

A simple napkin calculation will show that this practice will:

  • Reduce stress on QA team
  • Reduce the costs in support
  • Reduce the number of bugs in production
  • Reduce the amount of frustrated customers and frustrated developers

TDD is Unnecessary 

I’ll ask you this: would you buy a car that hasn’t been tested that it’s engine doesn’t explode in your face when you turn it on? Thought so.

Would you drive over a bridge that someone guesstimated what weight it can hold? Would you live in a newly built house that wasn’t up to code and that can burst into flames any time you flick the switch? Nope?

Then why do we feel like it’s justified to send out a piece of software to your customers and have them:

  • pay for software that doesn’t do what it says on the tin
  • use software that doesn’t have a good experience
  • use software that’s full of bugs that are detrimental to your customers

Now, I can already hear you saying: well nobody will die if they have a bug. True, perhaps, but perhaps you can look at it like this: would you pay for a diet drink that makes you fat? It doesn’t kill you but it also doesn’t do what it says on the tin. Be a professional and admit that sending something that’s sub par in quality should never happen. It makes you look bad, it makes the company look bad and it can drive the company to ruins.

Ok so now that this is behind us let’s dive a bit into test driven development and see how do we go around it the right way.

Rule #1: Do not test what you don’t own

Found your self writing a test around an MVC controller? Stop it. Your controller derives from a framework class. You didn’t write that class, so you don’t get to write tests against it. That’s someone else’s responsibility.

Only test the code that you write and that derives from interfaces. The rest is someone else’s responsibility.

Rule #2: Know your patterns

Patterns are extremely useful. With TDD even more so. They make the code easier to test and provide natural isolation barriers for you to use in your tests. This applies even for legacy systems.

Rule #3: Always, always, always write your tests first, and then write your code

Writing your code first will always have more issues than if you were to write your test first. Teach test moves your code in one increment closer to its final implementation. The test needs to fail in order for you to write the next unit of code. You should never write anything other than the minimum amount of code needed to pass the test.

Rule #4: If it has nothing to do with passing the test – don’t write it

Building on the last rule. Never, ever write more than necessary, we want out code to be as lean as possible.

Rule #5: Separate your tests

This one helps with the CI process. Weather you are using a CI process or not it doesn’t matter. Each package or assembly should have it’s equivalent set of separated tests. I always create separate assemblies for unit, integration and end to end tests. Depending from where I’m approaching the system I might create the acceptance test assembly as well. This helps keep everything neatly organised, and when something fails you know where it failed.

Rule #6: Understand the difference between code coverage and test coverage

Code coverage is a metric that tells you how much of your code is being used by all of your running tests. This metric, by itself can be very deceiving for all it takes is a few tests at the very top (end to end) that will reach enough modules to produce a high coverage.

Test coverage tells you how many tests (unit, integration etc) hit the individual unit of code. And if you have started by writing your unit tests first you’ll see a fairly good number.

A good place to be with code coverage is at around 75-80% as some modules might be generated or not for us to test directly. Higher code coverage is possible but that comes with some advanced filtering across the coverage results.

When it comes to test coverage you should expect to have 4-5 tests hitting every line in your code.

Rule #7: Review, review, review

Having tests passing is great. But if the tests are poor and they aren’t providing any value to the overall system or the team, then the coverage they provide is useless and we can consider the tests to be invalid.

Reviewing the tests is an important part of the practice. It’s both a quality assurance practice and a learning practice. You can learn as much from a badly written tests as you can from a well written one.

Rule #8: Have one, and only one, assertion per test

This is an important rule, and it’s here to make sure there is only one purpose for any test. Asserting multiple things in a test means you have a test with multiple responsibilities.

Rule #9: Understand isolation

Isolation and testing go hand in hand. It’s like placing your code in a vacuum and inspecting it. In order to do so you need to isolate the code. To do so use an isolation framework.

Unit tests need to run in complete isolation. Integration tests run in partial isolation and end to end tests run without isolation. An isolated test is a fast test. An isolated test can run anywhere, any time and it will always be valid, save from system changes.

Rule #10: Understand stubs, mocks and fakes

Understanding these three basic concepts is key to writing good tests.

Stubs are anything that you use to produce the state you are testing for. This can be a simple integer or a more complex object. Naming them properly matters, as it denotes what their purpose is.

Fakes are objects used to simulate the response from an underlying dependency and we use them to see how our code manages such a dependency. We typically use isolation frameworks to accomplish this but when we have to work across multiple teams then we might implement our own fake implementations for our internal use to keep the development going.

Mocks are objects that we use to see if, in a given scenario, the system under test invokes in a proper way, using the expected set of parameter values. So this checks if something gets called, at all, N times, or once based on some business logic.

Begin to understand these rules and you will begin to grasp TDD. I will make a series out of this topic and I’ll continue to go deeper and deeper with each article, showing in depth how to go about the whole practice. Be warned, there will be a bit of pain in the beginning as you begin to unlearn the bad practices and start to learn how to go about it. But it’s worth it, after that initial pain it becomes so much easier. You will uncover the zen mentality that exists when writing code in this way. And once you switch, you will never want to go back to the old way.

Engineers, Managers and Agile, Oh My!

Ever since 2001 when the legendary Manifesto of Agile Software Development was formed, signed and published by the creators; the software community has tried to find ways to root out the old waterfall model and replace it with one of the many flavors of agile.

The problem was that there wasn’t any formal guidance for managers, or teams on how to implement those new practices in their companies. Yes, we had the principles and the manifesto but that gave barely any clarity in terms of what to do. That is, until they started giving out certifications for Scrum. Managers, being managers, went “Oh, look, a certification! We should get behind that!” and they were right to do so. At least with a certificate we get a piece of paper saying that we understand the process and the practices and we have an organisation behind this piece of paper that guarantees this. Happy days!

The reality, however, is a bit grim. The problem is that software development teams would get trained but, oftentimes, the management wouldn’t. As a result you’d have an organisation implementing “Scrum, but…”

Now, granted, the dogmatic approach that scrum or any other agile methodologies preach doesn’t work with every type of organisation, and the people teaching scrum understand that, so they mention that “making small tweaks to fit your company” is an ok thing to do, and it is. Like clothing no one size fits all and even when we buy some things in the shop we need to alter them to get them to fit us just right. The problem here is that companies start with something pure, and then modify it beyond any recognition to what is, essentially, waterfall all over again but with a few bells and whistles around it to make it look more like agile.

Now, I’ve been writing code for the last 20 years or so, and I’ve seen some horrors over the years (and I’ll cover those at some other time) but it’s only when I started working professionally that I have started to see the real horrors. Here are some of the things I’ve seen over the years in “agile” companies:

  • Tasks would be estimated by management, than handed down to the engineering team to implement. Then when the team wouldn’t make it (because the estimates where in hours, and not relative complexity) the team would get scolded.
  • Management would come along and announce that a (agile) project will resort to being treated as a waterfall project in order to “save time” and “address the needs of the customer”, mostly at the expense of the software development team. Resulting in epic amounts of overtime, burnout and job dissatisfaction.
  • Management would impose their, unfortunately, wrong understanding of basic scrum concepts on the team and then expect the team to perform efficiently.
  • A company would “implement scrum” by having some consultant come in and teach the team and management about scrum, and then certain teams would go rogue where they would communicate to the upper management that yes, they are doing scrum when in fact it was all still waterfall.

These are just some of the things that I can think of, of the top of my head, which I’ve seen over the years and I’m sure there is more but I’ll leave that for another time.

The solution here is very simple and it’s a two pronged approach:

  • Education and
  • Professionalism

Professionalism, you say? Yes, professionalism. Notice how I’ve mentioned that it was the management that would often push for those changes and modifications to the process.

Here is why: during the reading of the values of agile methodologies they hear the bit about how working software is valued more than comprehensive documentation. Later on they hear that they can tweak the process to fit their needs so if they can sack the activity of documenting the system they can push their team to code more.

By tweaking the process they’ll ensure that in the two week process their teams will deliver a lot, so that they can get a nice pat on the back and a nice bonus because of their brilliant idea of increasing productivity with this “scrum thing”.

The horrifying realization, for us engineers, is that they have every right to do so. The interest of management is to get software out as fast as possible and if they can get it yesterday that would be great. It’s all about the race to the market and being first and seeing their idea come to life (as well as the bonus for that feature they suggested that made the product a success).

The thing about professionalism comes when we include the software team in all of this. As software engineers we are responsible for upholding our craft to the highest standards as determined by the industry. Through self-education and practice we should know what works and what doesn’t. We know that writing tests is the only way forward, we know that using libraries vs. writing our own implementation is better, we know that we should use an ORM vs. writing SQL, we know that dependency inversion is the way to go but we end up cutting corners in order to “save time”. Granted, some projects are so small that there is no need for us to use any of that but that’s more of an exception than the rule.

The thing is, just because a manager says something it doesn’t mean that they are right, or that they have the right to demand something of us that we know we shouldn’t do.

“Oh but if you do manual testing could you get this over the line then, would that save time?”

No, it won’t save time, if anything it will take longer and it will cost more to the company as a high-value resource is doing work that an automated script should be executing, except he / she is doing it but with more errors and taking longer to do it. You wouldn’t ask a surgeon to do a 10 hour surgery in 30 min because you have a game of golf scheduled in 45 min and you want to get there a bit early before it gets crowded.

Neither would you ask your defense attorney to defend you now and do the research and discovery later. Surely your complicated legal matter isn’t that complicated. It’s only a few articles of some law or something, surely all that research and discovery isn’t necessary and they could just read that article and use some loophole…

The fact is you wouldn’t do any of that because you understand that a surgeon knows what they are doing, they are keeping to what they’ve learned in school, and over the years, and you trust their skills and their expertise.

So why do we let management get away with it? We should be communicating with them and help them understand the error of their ways. We need to be more like the doctors and the lawyers and be more professional and take some pride in our craft. After all, even the Manifesto of Agile Software Development says to value individuals and interactions over processes and tools.

That’s the hint that we’re missing. We need to effectively communicate with our management and in a very professional way explain why we shouldn’t do something and offer an effective alternative that helps solve their problem but also addresses all the good practices we should be doing.

Otherwise we’re doomed in fulfilling the prophecy Uncle Bob has given us: If we don’t stand up and defend our craft then the governments of this world will, and they know nothing about our craft to be capable of doing something like this.

So go out there, and for Christ’s sake be a professional and make a stand.