Learning a codebase by reading tests

Getting up-to-speed on a new codebase - whether you're diving into an open source library or you just joined a new company and you're learning their code - is always a bit daunting... Where do you start? What file do you open first? What is the code even doing?

There are lots of ways to go about this, but one of the best ways I've found and how I tackle learning any new project is by reading the tests that accompany the code.

Advantages of learning via this approach

Documentation is the usual place most developers will start when learning a codebase. This is definitely not a bad place to start, and it can help you to get a high-level understanding. But there are a few advantages of reading tests as "documentation".

Often documentation will become out-of-date, but unit tests generally won't. Since tests are (hopefully) run as part a CI build and deployment, if a function changes and breaks the test the CI build will fail. Which means tests have to be more up-to-date than documentation, which is static.

Another major advantage is that tests are about inputs and outputs, usually more written from an "outcome" perspective. Most modern test frameworks have you write a test with an expected input(s), pass those to whatever it is that's being exercised/tested, and confirm an expected output. Reading through tests like this can help you understand how data is passed around, gets modified, passed to other functions, etc.

And 90% of the time when you're trying to understand a codebase, you're trying to understand what a given function expects and what it either returns or what action(s) it takes. Tests will help you understand that.

Similar to how "Test-driven development" is about writing the test to write the code, this is about reading the test to understand the code.

Starting with higher-level tests

Usually the way I will do this is start with reading the end-to-end and integration tests (if they exist, ideally both do), since they are written to test things at a more "high level" and less granular than unit tests. These tests will exercise a larger amount of code paths, and are usually written in more "business requirements" or "feature requirements" language. This helps you understand how the module or REST API/service is used/consumed, and get a sense of what each feature does.

Reading unit tests

Next I will go a level deeper/more granular and start reading the unit tests. For these tests, a great way to go through these is to have the test file and source file open side-by-side in your IDE.

Generally but not always, unit tests will be grouped by function or at least more correlated to a couple functions (in contrast to integration and end-to-end tests which will hit many functions and harder to trace back to a specific part of the code). This makes having the source file open side-by-side with the tests easier to start getting an understanding of what the code is doing. You can see expected inputs, follow those through the function, see how they're used or manipulated, then see what the expected output should be.

Test files

Usually codebases will have a test file name that corresponds to a source file, something like books.service.js and books.service.test.js. But in the case of integration or end-to-end tests, they most likely won't. This makes locating the unit test that goes along with a given source file easy to find and open up next to your source.


Next time you need to get up to speed on a new codebase, try the method discussed above. It's always helped me learn much more quickly and given me a "roadmap" of where/what to start focusing on.

Aside from learning a codebase, something I see Node developers often struggle with is where all your code should go in a REST API (sometimes referred to as "project structure"). If you want to see how I structure my Express REST API's and learn where your different types of code like request logic, middleware, database calls, etc. should go, subscribe below to be sent an email with an explanation of that as well as a repo with that structure. You'll also get all my future posts delivered directly to your inbox!

Subscribe for the explanation and repo!

No spam ever. Unsubscribe any time.