Often times you have numerous test specific helper functions, and tons of other test oriented cruft, where do all these things go? The root of the project? Also where do tests that encapsulate logic between multiple components go?
Often times you have numerous test specific helper functions, and tons of other test oriented cruft, where do all these things go? The root of the project? Also where do tests that encapsulate logic between multiple components go?
> Can someone please explain to me the rational for shoving
> your tests in the same place as your code?
Basically, (1) you are quickly able to see whether a test exists for each file without needing to explore a different directory structure (and therefore it's easy to open the tests for a file), (2) the require/import paths are not like '../../../../../' (which is awkward to reason about) or requiring alias resolver configurations (which are environment-specific and fragile), and (3) you are not maintaining an extra directory structure which could diverge by accident. > Often times you have numerous test specific helper
> functions, and tons of other test oriented cruft,
> where do all these things go?
> The root of the project? Also where do tests
> that encapsulate logic between multiple components
> go?
Modularise and publish any test helpers which are actually general so they can be imported where they are needed. And if they are too specific for this to make sense, why are they being shared?Tests which encapsulate logic between multiple components should be next to the file in which you implemented this logic.
If you're still unsure on how this is possible, investigate a large modern JavaScript project [0]. Many of these are successfully implemented in exactly this way. There are always edge-cases that go against what I've said, but in a big enough project you will also be able to see this.
[0] https://github.com/facebook/react/blob/master/src/renderers/...
And it's clearly not an opinion that many large, modern JavaScript codebases are following this practice effectively. I linked to 'React' itself as proof of this...
Also, I personally never used the term "best practice" however I will say this: (1) these practices are common within some of the most popular JavaScript projects, and (2) having used them and also previously stored tests separately, I do prefer storing tests alongside the files I am testing for the reasons I stated. I am not sure why, but your response felt a bit like you were angry with me, and putting words in my mouth.
None of your points are facts.
> And it's clearly not an opinion that many large JavaScript projects are following this practice. I linked to 'React' itself as proof of this...
React isn't that large of a project. It has a lot of contributors, it doesn't make its codebase large.
> 2) the require/import paths are not like '../../../../../' (which is awkward to reason about)
> or requiring alias resolver configurations (which are environment-specific and fragile)
Compare writing an import path within a test of `import Button from '../Button'` to `import Button from '../../../../src/features/abc/components/Button'`. The latter requires you to count the directories in the path and replace each with '..'. This is a pointless waste of mental energy, and the former solution removes the need to do it.The other solution as I described is to use things like aliases but this causes you to create complex configuration for your tests [0] which must be maintained and means your test are now dependent on this environment.
If this is just an opinion, please demonstrate that it's incorrect.
> (3) you are not maintaining an extra directory
> structure which could diverge by accident.
You are suggesting to me that `src/features/abc/components/Button.js` and `test/features/abc/components/Button.js` are not separate file-system structures which can diverge?Because they are separate directory structures it is possible for them to diverge. This is a basic implication from the fact that they are separate structures.
If somebody moves `src/features/abc/components/Button.js` to `src/features/def/components/Button.js` you are telling me that you will not need to make any changes at all to `test/features/abc/components/Button.js`?
[0] https://github.com/trayio/babel-plugin-webpack-alias/issues/...
Integration tests and other, larger tests should still be kept somewhere else, because they often not test a single component (or a single module) but a larger part of the whole application which is harder to pinpoint in the filesystem. So most people put those tests under a top-level tests/ folder inside the project.
Unit tests are about testing behavior, not types. Using type annotations has nothing to do with testing.
Putting tests right along the source code is a matter of convenience thus an opinion.
In some languages like Go it is even "good practice".
For that particular recommendation I can see arguments both ways - mind you I keep tests separate myself but I'd be interested in reasons for keeping them together.
I find you do want to find components through your editor (e.g. <cmd>+p in vs code) Finding lots of index.js doesn't help. You will in effect create a Component/Component.js but also use Component/index.js to export the Component.js
Also if you use Jest this sort of falls apart.
For tests that go beyond small (unit/spec) level we have a project level tests folder because these tests make use of multiple modules and it wouldn't make sense to place them closer to the code.
Someone else in comments mentioned cohesion - that's another way of thinking about it.