Improving Aegir test speed
RonaldZielaznicki opened this issue · 2 comments
TLDR;
Are y'all interested in some refactors?
That would...
- reduce testing time (from 4000ms to 45ms per test)
- utilize the extra time to introduce more tests for more descriptive coverage
- save money on CI
- remove side effects from
./src/utils.js
(making it easier to add new commands)
PS: I will break code examples here into smaller more manageable chunks for commits / PR reviews. The linked code was made as a proof.
Is your feature request related to a problem? Please describe
When running the tests for Aegir, most tests take 4+ seconds to finish
Describe the solution you'd like
Ideally, Aegir should not take several minutes to run its test suite
Describe alternatives you've considered
- using
command.parse
in tests overexeca
- remove reliance on outside modules through dependency injection (more context below)
Additional context
Using command.parse
over execa
Running tests with execa
forces additional overhead by opening a new node instance for each test.
By using command.parse
we use the existing instance and dodge this overhead. The caveat/blocker is src/utils.js
. It has side affects on import that make it difficult to test commands in isolation.
See: 506644e
Results
We gain almost 2 seconds back per test by doing this.
Default tests with execa and module dependencies
build
esm
✔ should build an esm project (4005ms)
ts
✔ should build a typescript project (4031ms)
Tests run from command.parse
build
esm
✔ should build an esm project (2394ms)
ts
✔ should build a typescript project (2287ms)
Removing reliance on outside modules from tests
Completely removing them wouldn't be great since we still want to make sure that it works from end to end.
But we could still pull some dependency injections to test aegir independently.
See: bfa18e4
Results
Running the typescript command on its own takes 2-3 seconds for a small project. If you look back to the tests run with command.parse you'll notice that's about how long running command.parse
takes.
With some dependency injection, that type drops to a negligible value. Compared from the original 4 seconds, it drops down to 45ms.
Default tests with execa and module dependencies
build
esm
✔ should build an esm project (4005ms)
ts
✔ should build a typescript project (4031ms)
Tests run from command.parse and dependency injections
build
esm
✔ should pass the appropriate options to injected dependencies (45ms)
✔ should build an esm project (2342ms)
ts
✔ should build a typescript project (2280ms)
I've since cleaned up the examples I made into more consumable chunks to be easier to understand.
Here is a draft pr (on my fork of aegir) to showcase the changes. If this seems like something y'all are interested in, I'll drop the PRs over here too.
https://github.com/RonaldZielaznicki/ipfs-aegir/pull/5
Here is what a test run looks like with these changes:
build
should pass the appropriate options to dependency
tsc
✔ passes preferLocal (257ms)
✔ passes stdio (149ms)
esbuild
cli options
✔ passes build to metafile (158ms)
default config options
✔ passes conditions (129ms)
✔ passes format (99ms)
✔ passes minify (108ms)
✔ passes sourcemap (104ms)
derived options
✔ passes pascalCased globalName from package.name (110ms)
✔ passes entrypoint "/src/index.js" for none-typescript project (102ms)
✔ passes entrypoint "/dist/src/index.js" for typescript project (106ms)
✔ passes outfile (105ms)
✔ passes umdPre as js banner (102ms)
✔ passes umdPost as js footer (100ms)
Closing due to a lack of input.