Do you like testing?
Answer for this question may differ depending on the experience. Young developers hate testing, I’ve been there, done that. I wrote my first test at my first job, one year after I’ve started learning C#. For long time I didn’t see a point in writing tests, but I did it, because my team was doing it. I’ve changed my mind after I read Robert Martin’s Clean Code.
Today we’ll talk about unit tests. I’ll try to convince you that unit tests are the most important part of software engineer work.
What is unit test?
Unit test is a piece of code, project that runs your application under controlled conditions. After that it’ll check if results are expected, if so test passes. Characteristic for unit tests is that they run in isolation from everything else, even your own dependencies. You want to test only one thing at the time. Only that way you can be certain that functionality truly works.
Construction of tests
Every test should contain 3 parts, Arrange, Act, Assert or Given, When, Then. In Arrange you can setup test, here you need to prepare everything for test to work or artificially create state for your application that you want to test.
Act is where you run tested method. In most occasion it is only line which will call your method, nothing fancy.
Assert is the most important part of test. You can’t call your code “test” if it lacks assert. Here you will check results of called method. Remember that it’s good practice to have only one assert. It isn’t rule thou, you can have more asserts if you test similar things like http response’s status code and response body. You can create two same looking test that will check status code and response body, but you can also test both in one test.
Why do you need tests?
Finally that question. There are four main reasons.
Functional test on local machine
Well of course. You can use tests to check if your code work. With tests you don’t even need to run your application manually, because your test will simulate application running. It’s even better, let’s say your functionality has multiple steps. To test manually last step you would need to go thru every step over and over (that’s how hell looks like). With unit tests, you can just run test to check if everything works or even run test just for one selected step. It’s very handy.
Automatic error detection
You can run your unit tests during Continuous Integration build. You can setup build to run tests every time developers push their changes. So even if some change broke code, you’ll know about it, and you’ll be able to fix it before merging it.
Understand how application works
This one is mostly helpful for new developers in team. The easiest way to learn how application works is to run test and debug it. Additionally by studying tests you can learn what responsibility and features has your class, project or application.
Documentation
Unit tests can be used as documentation. I’ll show it on example. I’ve been working on new project, there was line of code that checked if input date was null or empty and then parsed input to date. I’ve changed this line to use TryParse, so I could drop useless if and add my functionality.
Aaaand then I broke functionality. I didn’t know that null and empty string was correct input. I assumed that only correct date is valid. Fortunately it came out in Code Review, but with tests I would have known right behavior of that class before pushing it, and I would find my error earlier.
You ask how? There would be test ShouldPassWhenDateNullOrEmpty (or something like that) and another test ShouldThrowExceptionWhenInputDateInvalid. Yeah, I shouldn’t have used TryParse, because application was expecting Exception, that was second bug I’ve added.
Regression
The most important at the end. You create tests to make sure that any of your change didn’t break anything. It is useful when you want to refactor code. Let’s say you’ve done your work. Application works fine, but there is mess in code. You need to clean up, remove copied code, split methods etc. If you have code covered with tests, you can do whatever you want, because when you finish, you can run tests and make sure that everything still works.
So in general, tests let you write clean code. Without tests you can’t refactor code freely. Without refactor you’ll start wasting time to think about workarounds for your hacks and that’s straight way to hell project. Make your life easier and write tests. Write high quality code, and make your colleges happy. Finally, create high quality application and make your clients happy.
Good practices
- It is important to remember that testing two completely different things in one test isn’t best idea.
- Your tests should be simple and easy to read. There should be as little logic as possible. Everyone should be able to understand tests without problems.
- Your test should be as clean as possible, you can’t say “Ehh, it’s only test, I can do quick dirty code just to make it work”. You’ll have to maintain those tests, if you won’t keep them clean, test will become burden not a help.
- Buggy tests are worse than application without tests. You need to trust your tests, there’s no point in writing tests if you have to check everything manually every time.
Last advice
There is always time for tests. Don’t let your boss shout you that you have no time for it, or you can do that later. Ask him, if he wants working application that will start earning money few days later or buggy application that will earn money now, but in few month will be unmaintainable.
You don’t have to cover everything with tests. Just agree to cover the most important parts. Additionally add tests when you’ll find a bug or make a change somewhere. It is 1 more hour of work and will dramatically rise maintainability.
Outro
I hope I convinced you that unit tests are useful. Maybe next time, when you’ll hear your manager saying “let’s skip the tests, write only functionality”, you’ll be able to straighten him, before he damages your project. Because that’s what he’s doing. By encouraging to omit unit tests he’s damaging project.
If it didn’t convince you, then remember that every employer will ask you about unit tests and testing in general at the job interview (even if they don’t write tests :P). It’s better for you to know how to write good tests, and who knows, maybe you’ll like it when you start learning it.