-
Notifications
You must be signed in to change notification settings - Fork 21
Add unit/integration testing for @opencensus/web-instrumentation-zone #104
Add unit/integration testing for @opencensus/web-instrumentation-zone #104
Conversation
|
||
export class InteractionTracker { | ||
// Allows to track several events triggered by the same user interaction in the right Zone. | ||
private currentEventTracingZone?: Zone; | ||
currentEventTracingZone?: Zone; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this need to be exposed to tests?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's necessary to test when there are overlapping interactions and check the interactions have different ID. Also, when there are several event clicks corresponding to the same interaction, we want to make sure there is not a new zone for those click events. I am open to receive recommendations on a way to avoid exposing this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: I stopped exposing this as final decision was to leave this kind of testing of a future refactoring on InteractionTracker
} | ||
|
||
/** Increments the count of outstanding tasks for a given interaction id. */ | ||
private incrementTaskCount(interactionId: string) { | ||
incrementTaskCount(interactionId: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the motivation for exposing these methods and verifying that they are called?
My intuition would be to try to measure this implicitly in the test via seeing how long the interaction took
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The motivation is to make sure we actually count the correct amount of tasks involved in the interaction. The duration of interaction is a good test but might give a wrong testing on the amount of tracked tasks for every interaction, as we actually want to check that, for example, macrotasks are handled. I am open to different approach though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, I guess to me the fact that it is counting tasks is more of an implementation detail that is not exposed to the end user of the tracker. So for an integration level test, I think we should be testing the surface as experienced by the user as close as possible.
Another idea would be to try to split out the part of the code that does the task counting and test that separately more as an implementation detail to make sure the counts are correct. And then in the integration test to just measure the total time and span name/metadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Final decision: I decided to stop testing the task count as it should be more an implementation testing more than integration testing. Also, this could be done in a future refactoring on InteractinTracker
to test every specific module.
} | ||
// Don't count periodic tasks like setInterval as they will be repeatedly | ||
// called. | ||
if (task.data.isPeriodic) return false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you change this to ignore all periodic tasks? I would think that calls to setInterval
could be pretty relevant to the work of user interactions.
One other thing that should be a TODO for later I think - if you have a periodic task with > 1 second of time, then I think it should be executed outside of the tracing zone. Otherwise, if it ends up doing some work in the future it will still be associated with that same older tracing zone.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found out that if we track periodic tasks, the interaction might not finish as they are called repeatedly, so we won't be able to determine the stability of the interaction.
packages/opencensus-web-instrumentation-zone/test/test-interaction-tracker.ts
Outdated
Show resolved
Hide resolved
// As there is another setTimeOut that completes the interaction, the | ||
// span duraction is not precise, then only test if the interaction duration | ||
// finishes within a range. | ||
expect(rootSpan.duration).toBeLessThan(5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should you check a minimum time here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case, this noop sync function does not have any logic.Then, the minimum time would be 0. I think that just checking the max time is fine.
packages/opencensus-web-instrumentation-zone/test/test-interaction-tracker.ts
Outdated
Show resolved
Hide resolved
packages/opencensus-web-instrumentation-zone/test/test-interaction-tracker.ts
Outdated
Show resolved
Hide resolved
packages/opencensus-web-instrumentation-zone/test/test-interaction-tracker.ts
Outdated
Show resolved
Hide resolved
packages/opencensus-web-instrumentation-zone/test/test-interaction-tracker.ts
Outdated
Show resolved
Hide resolved
spyOn(tracer, 'onEndSpan'); | ||
interaction.stopAndRecord(); | ||
|
||
expect(root.attributes['EventType']).toBe('click'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the test cases above for the fake user interactions also test these attributes?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, Added.
Codecov Report
@@ Coverage Diff @@
## master #104 +/- ##
=======================================
- Coverage 96.29% 96% -0.3%
=======================================
Files 26 28 +2
Lines 647 825 +178
Branches 83 124 +41
=======================================
+ Hits 623 792 +169
- Misses 24 33 +9
Continue to review full report at Codecov.
|
constructor() { | ||
// register the noop exporter to have an span event listener, | ||
// helpful for testing. | ||
this.tracer.registerSpanEventListener(this.exporter); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you do this in the tests rather than here in the production code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
import { RootSpan, Tracer } from '@opencensus/web-core'; | ||
import { OnPageInteractionStopwatch } from '../src/on-page-interaction'; | ||
|
||
describe('OnPageInteraction', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be 'OnPageInteractionStopwatch'? And should the file be something like test-on-page-interaction-stopwatch.ts
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated.
While preparing for plugins, in a piecemeal fashion firstly added some interfaces and a guide but since the plugins proposal and implementation didn't make it at the last minute, let's also remove the previous code to avoid confusion. Fixes census-instrumentation#104
OnPageInteraction
class.setTimeout
,Promise
, HTTP requests).Additionally, there are some changes little changes:
InteractionTracker
as Singleton as there will be only one InteractionTracker instance always.currentEventTracingZone
when the interaction has finished before it is reset automatically.SpanEventListener
in theTracing
(for this case theNOOP_EXPORTER
) as this is helpful for testing.setInterval
) as they might never stop and interaction wouldn't be stable.