What is Unit Testing?
# What is Unit Testing?
“Program testing can be used to show the presence of bugs, but never to show their absence!” Edsger W. Dijkstra
While we are developing, we can write everything that should be done and experiment with the parameters that should be. Everything may seem fine. But when we write a unit test, we try to find our deficit as if we face ourselves, and thanks to this, we may notice and correct the bugs that will come out in the prod while writing the test. So unit testing is a must for a developer.
One of the important parameters for unit testing is speed.
As it is understood from the name of unit test, it is the testing of software units. What we call the software unit here is the smallest software component that can be tested. If we take the object oriented programming approach, we can say that software units are classes. What is done is simply to check if class behaviors (methods) work correctly when certain inputs are provided, and produce the desired result.
# From the Wikipedia :
Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the "unit") meets its design and behaves as intended. In procedural programming, a unit could be an entire module, but it is more commonly an individual function or procedure. In object-oriented programming, a unit is often an entire interface, such as a class, but could be an individual method. By writing tests first for the smallest testable units, then the compound behaviors between those, one can build up comprehensive tests for complex applications.
# Why do we use it?
I am sure that many software developers have asked this question on their own. Although some of us do not understand exactly what it serves, we write unit tests because we think it is useful and to feel more secure.
Although some of us know that it is useful to write unit tests, we avoid making unit tests by producing various excuses. The main reason behind this is that we have not grasped the main purpose of unit tests and test-driven development.
By writing tests first for the smallest testable units, then the compound behaviors between those, one can build up comprehensive tests for complex applications.
The software helps to determine whether the tested part of the program is correct through unit tests. It helps you to quickly detect the changes, error determinations you make in the codes. Thanks to the test units you create, you do not have to make your tests manually. Even though we see time loss while writing your test classes / methods, you will notice the effect of the time saving provided by the test as new code pieces and features come.
Thanks to the test methods we will write, we can check whether the methods we have written meet the conditions we want. Test methods can recognize our mistakes that have been overlooked or occured after changes, so that we can make refactoring in our codes.
# Should the unit test be written before or after writing our code?
I think both answers are not wrong for this question. Namely; If you are in a team doing TDD (Test Driven Development), you will write your tests first and then your code and you will continue to develop your code until your test is positive.
Likewise, when you need to make a change to your code, you first change your test as desired, then refactor your code until your test is successful. It is not easy for projects that are not well planned and teams with insufficient experience. It is necessary to examine TDD and its practices as a separate subject.
Of course, TDD is not a necessity but a preference.
# Should I test my test?
One of the most important features that a unit test must meet is that it is not affected by any changes other than the unit it has tested. We do this basically, assuming that everything outside is working properly.
If your test is successful in the scenario that should fail, you have a serious mistake. Therefore, to test our unit tests, we can be sure that our tests fail when our test is completed, by deleting the unit we are testing or by somehow disrupting the business logic.
# Unit test concepts
# Mocks or Stubs?
Imagine your kid has a glass plate on the table and he starts playing with it. Now, you're afraid it will break. So, you give him a plastic plate instead. That would be a Mock (same behavior, same interface, "softer" implementation).
Now, say you don't have the plastic replacement, so you explain "If you continue playing with it, it will break!". That's a Stub, you provided a predefined state in advance.reference
Use Mocks to:
- verify the contract between the code under test and a collaborator
- verify the the collaborator's method is called the correct number of times
- verify the collaborator's method is called with the correct parameters
Use Stubs to:
- provide a predetermined response from a collaborator
- take a predetermined action from a collaborator, like throwing an exception