Search code examples
javascriptunit-testingarchitectureintegration-testingdirectory-structure

What are structures for a project to know at a glance what needs unit tests and what doesn't?


I'm looking for some ways in which to structure a project so that I can at a glance know what files require/should have unit tests and what files don't.

This is why I'm looking for this: Let's say I have a structure in which I have various modules. As I add business logic, I also add unit tests for it. There's a business logic someFile.js file and an accompanying test file someFile.spec.js. I also have integration layer code that puts together my business logic units. For these I've deemed I only want to cover them in my integration tests. Since integration tests can span across multiple files, I'll put those in a top level folder. Now the problem, I have is that when I look at a birds eye view of my project, it looks like I'm missing tests for those integration only files, when in fact I've already decided that I meant to cover them in integration tests and not unit tests. So, there's some mental overhead involved in this.

I'm trying out and evaluating a structure such as the following at the moment to help with this problem. Each module has a folder. Each module folder has an integration folder in which I know files in there don't need a unit test. Each module folder also has a service folder in which I know I need unit tests. There is a top level test folder which houses integration tests.

src
|__ fileSystem
    |__ integration
        |__ save.js
        |__ delete.js
    |__ index.js
|__ dataApi
    |__ integration
        |__ get.js
        |__ getAll.js
    |__ service
        |__ success.js
        |__ success.spec.js
        |__ error.js
        |__ error.spec.js
    |__ index.js
|__ calculate
    |__ service
        |__ add.js
        |__ add.spec.js
        |__ subtract.js
        |__ subtract.specjs
    |__ index.js
|__ utility
    |__ service
        |__ sort.js
        |__ sort.spec.js
        |__ unique.js
        |__ unique.spec.js
    |__ index.js
|__ test
    |__ edit
        |__ addNote.spec.ts
        |__ removeNote.spec.ts
|__ index.js

I could try to use code coverage to do this, but I still need some sort of pattern to distinguish integration code from business logic code.

What are some other ways to structure for this? Is there an agreed upon best practice way to do this? If not in JavaScript, do other languages have a best practice structure for this?


Solution

  • There is no silver bullet. It depends on your demands. And this is why the following thoughts might be considered good or bad by different people:

    What are some other ways to structure for this?

    • Flat hierarchies: Unfolding structure can be an overhead. Multiple different indentation levels can add more noise then they help organizing. Maybe it is better to use unified naming and reduce folder depth. (As in: .spec indicates tests.) (Meaningful names) Modern IDEs do make it very easy to search meaningful names or naming patterns. (.spec)
    • Projection: Do you want all your tests together or should they be next to the logic they are checking? To answer this, you need to think about at which point in development you write your test code.
    • Why is it so important for you to know if your test is an integration test or an unit test? If there is not a special reason, consider reducing noise and merge them.

    Is there an agreed upon best practice way to do this?