Modern software development is hard to imagine without automated testing - in fact, this is the only way to protect a product from destructive changes (that is, changes that damage existing functionality).

Usually two types of automatic tests are used:
Unit testing (testing of individual parts of a product, usually individual functions / methods)
Functional testing - testing of a certain product functionality, while the product is perceived as a single “black box”.
')
But let's ask an interesting question - do we really need both types of testing at once, and if not, which one is more important?
So, to begin with unit testing.
Who writes? As a rule, the author of the module / method / function, since usually only he knows that this function
MUST be done. As a rule, this is a developer, and his goal is to cover the code with unit tests. This means that, most likely, the unit test will be very incomplete (as a rule, developers check only the work with correct data, or add a small set of incorrect data, since they are not worth the task of “breaking” their code), or , if the developer really responsibly approaches the process of writing a unit test, the development will take twice as long. Do not believe? But only the qualitative coverage of the function “whether the argument is a number” requires more than 10 checks. In addition, there are a huge number of functions, which cannot be tested with unit testing, or it is very difficult (these are functions whose behavior depends on the state of the system as a whole).
And even the correct operation of all modules of the system does not guarantee their proper interaction.
One more thing, if you want to introduce unit testing into a product on which it was not previously used, then this is a very serious labor cost, and covering a small number of functions does absolutely nothing.
The most important thing - even the successful passing of all unit tests does not guarantee the correct operation of the product: after all, the same function can be used in different parts of the system, while the unit test was written for it with an eye to only one use case.
A simple example: let's say we have a
checkInt (a) {return /^[0-9-9+$/.test(a)} function. At the same time in the unit test there is no check for a negative number. What does it mean? And the fact that if a certain developer modifies this function as
checkInt (a) {return /^-?[0-9â‚˝+$/.test(a)} , then the unit test will pass as if nothing had happened. But the functionality will be damaged. And after the error is found and corrected (the function returns to its original state), some of the functionality will fall off in another place. With consistently successful passage of unit tests.
In my practice, there was even a variant of commenting on my unit test, since it ended unsuccessfully after changing my function.
However, it should be recognized that unit testing is an excellent tool if you write a certain library intended for use by many developers - in this case, unit tests will also perform the role of function documentation (it's not a secret that we often skip the description of a function and immediately see examples use). However, in this case, the library itself is a product, and unit tests are indistinguishable from functional ones.
Now back to the functional tests. As a rule, they are written by testers. Who has the task to find an error (at least we always set such a task to our testers). That means there will be more checks on non-standard data - you will agree, it's just great! In addition, we can share access code of the product and tests, which will allow to avoid changes to the tests "so that it is green, because we need to be released"
In addition, functional tests are much easier to cover the finished product than modular ones - because it is much easier to understand what exactly a particular part of the user interface should and should not do than to determine what this function
HAS to do. And the greatest beauty is that you can begin to cover only the most important parts of the product with functional tests - and they will regularly guarantee their performance.
Summarize.
Functional tests fully determine (at least should) the performance of the product. And above all, the customer / development manager. Unit testing is primarily necessary for the developers themselves to quickly find errors or check the effects of refactoring. Therefore, priority should be as follows:
- Functional tests - required
- Unit tests - desirable, but depends on the mood of the developers