I am sure many of us have faced the task of trying to do test driven development (TDD) on a legacy codebase. I myself am facing such a challenge, with several tens of thousands of lines of code in a Laravel project which I am helping maintain and is around a decade old. And being severely behind in the packages it uses, the time has come to give the code some TLC, and update it to use the most recent versions of those package (for example, we are moving from Laravel 5 to 12). With Laravel and PHP, there is Laravel Shift and Rector, but the former costs money and they are not guaranteed to address all the issues which the code has. For example, does it properly handle moving from the abandoned jenssegers/mongodb package to the modern package supported by the MongoDB folks? And it certainly would not add the unit and feature tests the project has so desperately been needing. So, the decision was made to do the lift ourselves and write the tests while updating the code.
Such an act is not easy, nor is it remotely test driven development, at least at first. And when the requirements are "the code is the requirements", to use the existing database and maintain the look and feel, this is especially so. As a result, I am starting with a clean repository and a basic Laravel "site", and copying code from the old repository to the new one file by file, and placing it in its new location (models were segregated in their own subdirectory) and then getting it under test. All the while, I am learning the structure of the MongoDB collections associated with the models, since there is no schema in the sense that relational databases have. It is going to be a big job ahead.
With all this work, I am writing lots of unit tests which border on being feature tests. The tests are considering the "unit" to be the class under test, but while I write them, if I happen to cover a public method by testing another public method, I am being sure to get 100% coverage of that first method directly. But, as I write these tests, the only changes I am making are adding proper type hinting which PHP 8.4 allows, fixing import paths, and other critical changes until I get it under test. Then true TDD changes might be done to improve error handling such as queries unexpectedly returning empty results.
Its a huge lift, but I will get there. Stay tuned. And if you want to see the progress, see my Medusa 4 repository on GitHub.