In many engineering disciplines, testing is an accepted practice. It’s not something considered an afterthought or a separate process. It’s seen as a core part of the profession. Something you do without exception.
But in software development, testing doesn’t seem to be quite so absolute -- yet.
Don’t misunderstand me. I don’t want to start a flame war about this. Nor do I mean to unfairly decry the efforts of thousands of developers, who’ve given countless, often thankless, hours building the traction of testing within their development communities.
Let’s be honest, we’re all flat out with so much going on. We’re under tough deadlines, with pretty high expectations from the business about how many new features we’re going to churn out by the end of the day. Marketing is forever selling new functionality to the customer, functionality which we, the developers, need to deliver on.
You’re forever building new features, maintaining existing ones, or fixing them when they randomly go wrong. Sometimes it’s like you’re working for the fire brigade, on a permanent rotation, ready to swat the next fire.
If you don’t have a background in testing or a strong discipline to do it, when those deadlines are looming or the manager’s hovering, the thought of ditching anything “unnecessary” is extremely tempting.
What’s more, some organizations don’t even value testing. I’ve known of some who even think it’s avoiding real work. Given all these factors, if testing isn’t simple, even streamlined, it’s likely going to fall by the wayside.
Why We Have to Test
But before we get disheartened, let’s consider some of the benefits that testing can bring.
Discovers if critical functionality works
Confirms if software works from the users’ perspective
Helps avoid the classic developer cliché “that shouldn’t have happened” when a seemingly unrelated section of software is changed
When practiced properly, testing is a benefit both for developers and for the business.
But There Are So Many Types of Tests! How Do You Run Them All?
Now let’s be a bit more positive and assume that you are testing, and that you’re working in a test-driven environment and following the red, green, refactor process. You know that all or at least a high percentage of your code is covered by tests. Periodically, perhaps before you make a commit, you run all the unit, functional, and acceptance tests.
Here we meet our next challenge -- actually running the tests. Sure, it’s simple enough, even rewarding and reassuring to write tests, as you're adding, updating, and removing functionality. But with so many different forms of tests, do you always run them? Or, like we all may do from time to time, do you only run some of them some of the time?
And What About Database Testing?
Let’s go one final step further, and add one last challenge to the equation: database testing. Avoiding the conversation about a database being a global variable, testing against a database isn’t always easy. Generally, to do it properly, you need to remember the following four steps:
Setup the database schema and tables.
Insert the rows required for the test into these tables.
Verify the state of the database after your test has run.
Clean up the database after each test.
At this point, I wouldn’t blame you if you started looking for the easiest path, the one requiring the least amount of effort on your part. I also wouldn’t blame you if, from time to time, things got missed. It’s a lot to stay on top of day-to-day, right?
A Stereotypical Testing Workflow
Enough with the theoretical. What about a specific example of all this testing in action? Let’s consider the workflow which I’m currently using on a client project.
The application is built with a combination of Zend Expressive, PostgreSQL, and Redis. The testing is handled by a combination of PHPUnit and Codeception. And all code for the project is versioned with Git.
When a push on the develop branch is made, Codeship starts a build, which is as follows:
The source is cloned.
Composer installs the project’s dependencies.
The tests are run, which are composed of 206 unit, functional, and acceptance tests, encompassing 504 assertions.
If both sets of tests succeed, a deployment is made.
Do you see the likelihood of something getting missed along the way, if all this had to be done by hand? When it’s done manually, it’s far too easy for it to fall prey to external pressures such as stress, tiredness, crunching deadlines, and more.
According to Dr. Steven Stein, stress causes a range of problems:
It affects decision-making, making us too impulsive.
It forces us to make mistakes.
It causes us to ignore cues.
It interferes with relationships with clients and colleagues.
It lowers productivity.
Given these inherent problems, one of the best things we as software developers can do is to automate tests. We’re working with computers after all, machines designed to perform processes over and over again, the same way every time; doesn’t it make sense to use them to test instead of doing it ourselves?
Let me walk you through five key reasons why automated testing is worth implementing in your project.
1. Test Automation Reduces Time
If tests need to be run manually, people need to take time away from existing work to run them. What’s more, we also need to ensure that the tests worked.
But why do manually what can be automated by the very machines we’re developing on? Why manually run a process that doesn’t differ any time it’s run? It doesn’t make sense.
All we should be concerned with is whether the tests passed or failed. By automating tests, we save ourselves a lot of time out from the more valuable task of actually writing and maintaining code.
With automated testing, there’s less to think about and less to remember, which ultimately requires a smaller time investment from us. When tests are automated, with a few exceptions, we only have to react if the tests failed for some reason.
2. Test Automation Reduces Effort
Let’s consider the case of the new developer, the person who knows next to nothing about how an organization works, its processes, or its codebase. For the new developer, regardless of skill and experience, there’s so much to take on board. How do we ensure that they don’t feel overwhelmed and potentially neglect tests?
As they’re asking themselves all the pertinent questions -- what do I need to do to get setup, what do I need to roll out a release, what’s the branching methodology -- one they shouldn’t have to ask is, how do I run the tests?
If tests are automated, new developers can just get on with developing clean, test-driven code.
3. Test Automation Increases Productivity
If a developer has to remember to run the tests, then they have to take time away from development. If the tests are run automatically, as part of the build process even, developers can keep developing -- unless the tests fail, of course.
They don’t have to break their concentration, go run the tests, then come back to where they were and pick up their train of thought. This might sound trivial, but the time involved in that mental context switch to and from testing can be significant, especially over the course of time. With this in mind, think about how much more productive developers can be when they can stay within the mental focus of developing great code.
I will say that doing one thing all the time, even something as challenging and rewarding as software development, can take its toll. It’s great to have a break from it from time to time, especially since that can be where the most amount of processing of thoughts actually happens. But to have switch back and forth between tasks frequently is just wasteful.
4. Test Automation Increases Predictability
If a process is done the same way each and every time, the results should be predictable. Yes, there is an external variable, the code, which isn’t predictable. Hey, the tests can only validate what they’ve been asked to validate. They’re also only as good as the developer who wrote them and the one who peer-reviewed them.
Therefore it’s essential not to fall in to the false assumption that just because you have tests that everything will be fine. That being said, when tests are automated and code is of a high standard, you increase the predictability of the outcome -- the knowledge of the state of the working code in the application.
5. Test Automation Increases Reliability
If a process is done the same way each and every time, then it stands to reason that the reliability of that process will remain constant over time. Contrast this with when people get involved.
People are great at looking at a situation, assessing the best course of action, and taking action afterwards. But repeatedly performing a task which can be mundane -- which is what testing can be -- isn’t something we do well. Especially when we factor in stress, tiredness, family pressures, illness, and so on. These serve to increase the likelihood that we’ll miss something.
For example, let’s say my stereotypical testing process that I discussed earlier needed to be performed manually. And let’s say that the acceptance tests were being overlooked for some reason.
We might get the false impression that everything was working, then wonder why a client emailed, complaining of an issue retrieving their user profile. We’d be convinced that everything was fine... until we ran the acceptance tests again and found several tests failing. We’d likely feel even more embarrassed if we then determined that the bug had been there for several days or weeks.
Isn’t that why we have computers, to take care of more mundane, repetitive tasks? Let's put them to use doing the tasks for which they were created.
Let’s Wrap Up
Those are five reasons why automated testing tools are worth your investment. I admit that some projects may be too small to warrant the effort to setup a full automated testing regime, and I won’t excoriate you if you feel yours is. Each project only has a certain amount of time and resources allotted to it. So if you’re not able to implement a complete automated test solution for your project, don’t beat yourself up about it.
But I strongly encourage you to do what you can, for the benefits that at least that much will bring you. Then, as time and budget allow, continue to improve it. Further investment will only pay itself off many times over.