Closed jkyoutsey closed 2 years ago
Different, random tests fail each time I run all tests. Every time, those tests have some sort of date logic in them. This happens on both windows and mac systems and happens for different developers on the team.
It sounds like there may be some (unwanted) dependencies between some of the tests, that are revealed when running Wallaby (and because it uses multiple processes with smart test distribution among them, different tests may fails because of the shared state).
ng test
consistently works without any issues for the project, then you may configure Wallaby to use 1 worker process (similar to ng test
) to make Wallaby run all tests in certain order and ignore that shared state/dependency issue. Note that in this case Wallaby will not be running your tests in parallel so this may affect the initial run time. To make Wallaby to use 1 worker process you may add the following to your package.json
:...
"wallaby": {
"autoDetect": true,
"workers": {
"initial": 1,
"regular": 1
}
}
I reviewed these tests pretty thoroughly. I made sure they were not re-using any mutated objects, etc. I made sure that state was completely reset every test. And I even set the package.json configuration you provided. And the same tests still failed in wallaby, but not in ng test.
In all cases the failures are related to testing if a date is in the future or the past.
It is across three specific files that these fail. And If I put in a space in the file and then save so they re-run, everything in that file will suddenly pass.
For example, here is a form validator function and test that fails intermittently only in Wallaby. There is no state. This is a pure function, and the test has no dependencies.
import { ValidatorFn, FormGroup, ValidationErrors } from '@angular/forms';
export const reportByTopicDatesValidator: ValidatorFn = (control: FormGroup): ValidationErrors | null => {
const start = control.get('startDate');
const end = control.get('endDate');
// We must not clear this error!
if (end.errors?.matDatepickerParse) {
return null;
}
end.setErrors(null);
// end.value is 00:00:00 in the current time-zone based on how the MatDatePicker control works.
// We need the end date to be the last moment of the day.
if (end.value) {
end.value.setHours(23, 59, 59); // don't set millis
}
if (start.value && start.value > new Date()) {
const startDateInFutureError = { startDateInFuture: true };
start.setErrors(startDateInFutureError);
start.markAsTouched();
return startDateInFutureError;
}
if (end.value && start.value && start.value >= end.value) {
const datesBackwardsError = { datesBackwards: true };
end.setErrors(datesBackwardsError);
end.markAsTouched();
return datesBackwardsError;
}
return null;
};
And here is the test:
it('validates if end date is after start date', () => {
const form = new FormGroup({
startDate: new FormControl(today),
endDate: new FormControl(tomorrow)
});
expect(reportByTopicDatesValidator(form)).toBeNull();
expect(form.controls.endDate.touched).toBeFalsy();
expect(form.controls.endDate.errors).toBeNull();
});
And If I put in a space in the file and then save so they re-run, everything in that file will suddenly pass.
This is interesting. It means that if the test file runs in isolation (from other test files), then its tests are passing. Can you please try the following:
// file.skip
comment to any 2 of the 3 test files causing the issues (to make Wallaby not run the test files at all),For example, here is a form validator function and test that fails intermittently only in Wallaby. There is no state. This is a pure function, and the test has no dependencies.
Thanks for sharing the example.
expect(reportByTopicDatesValidator(form)).toBeNull();
? Can you add some console.log or //?
comments to the reportByTopicDatesValidator
function to find out why is it failing? Specifically are the end.value
and start.value
logged values expected or not?today
and tomorrow
variables in the test are coming from? They seem to be declared in some our scope, are they used in other tests of the file?One possible issue that I can see: because today
and tomorrow
variables are possibly re-used elsewhere in the test file, and the endDate
value (possibly referencing tomorrow
variable) is being mutated in your source code:
end.value.setHours(23, 59, 59);
and thus after the test executes, the tomorrow
variable is modified (that may cause other test failures).
@jkyoutsey - were you able to review @ArtemGovorov's suggestions in the response above?
@jkyoutsey - were you able to review @ArtemGovorov's suggestions in the response above?
Not yet. But it does suggest some things that make sense. I will get to it, just not sure how soon. If you want to close the issue for now that's fine though.
OK - closing the issue for now. Feel free to reply when you're ready (if you need) and we'll re-open.
Different, random tests fail each time I run all tests. Every time, those tests have some sort of date logic in them. This happens on both windows and mac systems and happens for different developers on the team.
For Example: One run this one fails: ProductExpirationDisplayComponent Should show expired message Next run it's a different test: QASessionComponent show/hide percentage or counts percentage in shortMode complete hold in past
The diagnostics report is far too big for me to include on GitHub comments. I'll be happy to email it.