getsaf / shallow-render

Angular testing made easy with shallow rendering and easy mocking. https://getsaf.github.io/shallow-render
MIT License
273 stars 25 forks source link

Runtime performance is very slow compared to native Angular testing #224

Closed antch closed 1 year ago

antch commented 2 years ago

In my project, there are a few problematic component tests that occasionally creep past the 5s limit and cause Jasmine to fail awaiting the result of shallow.render().

One such component has 9 tests that take between 14-17 seconds to execute with shallow-render using Jasmine spies. When changing it to use TestBed.configureTestingModule with the same spies, directly accessing fixture, the 9 tests take less than one second.

I also just quickly refactored a component test that renders a chart from shallow-render to native Angular testing, and the runtime decreased from around 1.4 seconds to 0.18s.

Is this type of rendering performance discrepancy expected?

Edit: I created a gist to illustrate this, based off of a fresh ng new project with the default spec deleted: https://gist.github.com/antch/cc792661d0e9e2c9ce7801856ad01ed6

The only added dependencies are chart.js and primeng.

You can comment out each describe block to see the huge disparity in execution time.

FrEaKmAn commented 1 year ago

What happens on rerun of tests? Is the time lower?

antch commented 1 year ago

No, it's still slow. For example in the repro in the gist, the execution time just went from 1.15s to 1.05s. The "TestBed" version went from about 0.09s to 0.04s.

antch commented 1 year ago

I think I figured this out. It basically comes down to the fact that when normally writing an Angular test you (or at least I) don't await fixture.whenStable(), and the fact that shallow-render does this by default is what appears to be causing the discrepancy.

If I change my linked gist to pass in whenStable: false, the execution time is on par with the native Angular testbed:

shallow.render({ whenStable: false });

I'm going to close this. Just a side note, it may be nice to have an option to change this globally to default to false, but that's probably a pretty specific request.