Why You Should Co-Locate Test and Application Code
Yuki Kitaoka Lead Consultant - QA
There has been considerable debate over where the automation test code should be located. Over the years, I have worked on a multitude of projects where the test code was either located on multiple repositories or on the same code base, and my experience has shown me how the latter option positively impacts on how applications operate and favourably influence work processes and I will explain why in the key points below.
1. Share resources: connection, authentication, identifiers and more
More applications are built using microservice architecture, which allows us to deliver independent components more regularly in the distributed system. In order to achieve this, setting up all the infrastructure code to use the cloud resources is a prerequisite. This applies to the automation test code as well. The infrastructure code which includes setting up the basic authorisation for the http client can be shared within the same repository and this prevents code duplicates and is easier to manage in the long run.
For the front-end automation test code, common flaky tests problems are caused by the web element locators. Digging through the page’s document object model for the page and updating the web element identifier after your test has failed due to changes is quite frankly a harrowing task. However, if the test code resides in the same repository, the front-end code identifier can simply be shared, and an additional identifier (unique attribute) can easily be added to the main code.
2. Get early feedback
More and more teams move towards Continuous Integration and Continuous Deployment (CI/CD), and the use of automation testing covering common flows, including business scenarios and system failure scenarios is evidently vital to implement this successfully. Most teams seem to run unit tests to make sure their code is correct before they check in, and additional testing such as integration and acceptance tests should also be run. When these tests are in a different repository, they are typically executed after the build is completed, whereas if they are in the same code base, it becomes much quicker for the team to run any type of tests at any given time including running locally. Navigating between the main application and the test is much easier in the same code base, and checking the test also helps the team to understand what is ‘expected’ to behave well. Running tests and getting feedback as early as possible is an integral part of the Continuous Testing approach which helps the team to find issues early to improve product quality.
3. Treat tests as a first citizen in a codebase
There is an erroneous belief that the test code is of secondary importance, even more so if the tests are not deployed as a part of the production code.
We commonly hear people say how vital clean code is for successful delivery but this is also true for test code. When the test code is not maintained to the same standards applied to the rest of the system, the test becomes more fragile and rigid, and as a consequence, harder to manage. In a similar way to the feature code, refactoring techniques should be used on the test code.
Poor (or lack of) feedback does not allow the team to identify what actually went wrong, or if tests should be re-run. Treating test code as secondary compromises the whole review phase, and defeats the purpose of running the test.
4. Nurture the quality culture by means of collaboration
This last point may be the most important as to why I support the practise of having the app/test on the same repository because I believe that the way code is managed significantly affects work practices and implementations. How often do you start working in the scrum team but end in a silo? If tasks are assigned and compartmentalised into “specialised” groups, information will not be shared between groups and as a result, people will naturally become less involved. Traditional development typically creates silos for the team and this is still happening in many places.
However, agile practices have matured, and the DevOps model has influenced the agenda of many organisations and their digital transformation. Implementing CI and CD has emerged as a primary incentive to enable quality and momentum. We are in an era where individuals’ roles are required to cross over different disciplines and our work practises have to evolve. Unless the team does not consider the system as a whole, including the operation, the delivery may potentially fail. To achieve a smooth, top quality delivery, Continuous Testing (CT) is a key driver as it shortens the developmental and operational phases while testing occurs at every stage, as the following image shows.
I would also like to also highlight the importance of communication within the team – what is the ‘definition of done’ for each job? How is the application released? Which stage of the release cycle tests should be executed? These points need to be collectively agreed within the team.
Sharing the same repository fosters the team culture where more members participate in regular reviews, and this has a direct impact on their work. Furthermore, team ownership is more naturally enforced, and teamwork becomes more transparent.
In a decade, the need for software development has evolved dramatically and more organisations are transitioning towards an agile approach to deliver software at a fast pace. Any real change requires the alignment of people, processes, and technologies and none of them is an enabler on its own. A small step such as sharing a repository can change the team culture for the better, and within a few hours, you may well hear the team refer to ‘our code’ rather than ‘your code’ or ‘your test’.