We write code for fun. But we also write code to solve a problem based on provided requirements.
Behind every new feature, there is a requirement or specification that our code must met.
How can we verify if our code is really meeting those specifications?
There are several techniques to solve this. Companies usually have demo meetings with the people who created the specifications so that they can provide feedback and approve the solution.
If we closely analyze these meetings we can tell that they are just a bunch of assertions to validate that the new code is working as intended.
But, there is a problem with those meetings. What if a new feature is affecting an old feature that was already working?
Do we need to call a new meeting again to verify the old feature?
It seems that companies try to solve this by creating specialized teams for solving defects and running regression tests.
Nowadays many software teams are striving to improve this process by creating automated functional tests which are often included at the end of the code development phase or whenever a bug is found.
These automated tests describe the specifications of the system. They specify how the system should behave.
The problem with this approach is that we end up having specifications defined in two different places. One from the business area and the other from the functional tests. Thus, these specifications need to be synchronized to avoid misunderstandings.
Teams end up not knowing who is telling the truth. They don’t know whether the business area or the functional tests have the right specifications. They often agree on consider the production code as the source of truth.
Wouldn’t it be better if we write the business requirements and automated tests at the same time and in the same place?
By doing this, we could avoid many problems and confusions about the specifications when adding a new feature to the system.
We also could write our code confidently and verify it any time to see if our solution is meeting the specifications.
We wouldn’t have to wait at the end of the iteration to validate if we are doing the right thing or impacting another feature.
People who create and define business requirements are often not familiar with code writing. However, it wouldn’t be difficult to create a team that could translate those requirements into automated functional tests. Teams could even create tools to automate this task.
Test-driven development specifies that we need to create a test before creating any production code. This sounds like we need to create the specification before creating the new functionality.
There are new concepts like Behavior-driven development which propose to consider the specifications as a ubiquitous language and the use of tools to automate the specification verification process.
We could take this further and provide specifications for every new piece of code we create. We could do this for each class and each method.
Maybe someday we could stop consider tests as a QA tool and start consider them as a specifications definition strategy.