Project

General

Profile

Cleanup #44530

Updated by Ernesto Puerta about 4 years ago

Currently dashboard Angular unit tests take, depending on the environment, ~10-20 mins (and lots of CPU power/memory due to jest parallelization) to complete. This is mostly caused by the lack of isolation between components (fakes/mocks/stubs), which leads to most all dependencies (children component, services, pipes, etc.) being instantiated and tested on every individual test-case (and there are ~100s). 

 The following strategies could be followed: 
 * **Use of mocking frameworks** (e.g.: "ng-mocks":https://www.npmjs.com/package/ng-mocks, "ts-mocks":https://www.npmjs.com/package/ts-mocks). Currently jasmine has (namespace/clashing) issues with jest (e.g.: @jasmine.createObjSpy@) and jest provides very minimal mocking features. 
 * **Tune Angular default testing framework**: (e.g.: https://www.npmjs.com/package/ng-bullet) to avoid repetitive creating/destroying infraestructure objects. 
 * **Use a unit testing helper framework**: (like "spectator":https://www.npmjs.com/package/@ngneat/spectator). This would aid in the refactoring process by reducing the amount of boilerplate code. 
 * **Refactor tests (and components) to increase overall testability and reduce dependencies/side-effects** (e.g.: using Directives or Pipes instead of services & DI for specifying behaviors). This should be backed by some agreed guidelines on the expectations from devels. regarding unit tests. 


 Converting "current unit tests" to "strict unit tests" could lead to: 
 * **~700% speed-ups and decrease in resource utilization**: as an example, @navigation.component.spec.ts@ test took 138.995s (~3 secs./unit test) with the legacy approach (see https://github.com/ceph/ceph/pull/32419), and with the strict unit-testing it only takes 19.47s to finish (250 ms/unit-test, and much less peaks of CPU). As a result of this, the whole Angular unit test suite could be run in 2-3 mins max. 
 * **Better coverage**: currently part of the coverage is 'accidental' (100% packages, classes or files), as it's caused by the subsequent running of dependent components. However, when looking at method or branch coverage, we may see that the average coverage is 70-76%, and in some components that figure plunges to 0% (https://jenkins.ceph.com/job/ceph-pull-requests/46781/cobertura/). Proper branch coverage would require matrix-like/combinatorial testing, but with the current overhead per-unit test, that's unaffordable. 
 * **Reduce 'flappiness' of tests**: currently, some services are not mocked, and perform polling to the backend (e.g.: SummaryService in navigation.component.ts) or asynchronous behaviours/spurious race conditions.

Back