Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: make tests less fragile #111

Closed
wants to merge 8 commits into from
Closed

test: make tests less fragile #111

wants to merge 8 commits into from

Conversation

marcelltoth
Copy link
Contributor

@marcelltoth marcelltoth commented Mar 9, 2021

Summary

When publishing #109 I found out that unfortunately the current tests give me approximately zero confidence when changing structure like in that PR. Unfortunately even a single whitespace change breaks the entire suite, not to mention adding a level of nesting (like another div). It makes me have to go through every single snapshot to see if the change is really just as much as intended or more.

We have a pretty solid looking testing strategy at @stoplgihtio/undefined for Elements, see here. The aim of this PR is to rewrite the test suite to use these newer techniques which are supposed to be less fragile, so we can be confident that something like #109 doesn't break anything.

Goals

  • I have not changed component code at all.
    There are techniques lot better than these getByText queries I have here, but those would require changes in the component code. (Fixing accessibility problems mainly.) As the goal is to provide a solid baseline for future changes, these were ruled out.
  • I have not changed the test cases. I assume the test cases were designed to cover the tricky use-cases in a solid manner. I may have combined some into it/describe.each-es, or changed titles where they were misleading, but the cases should in general be the same.
  • Where unsure what the real assertion is, I followed the title of the test case. Another downside of snapshots is that it's not always clear what is being tested (well... everything?), I sometimes had to make assumptions based on the scenario titles.

Results

Everything should still be passing, which is a win!

What's even nicer is that replaying these commits on top of refactor/jsv I get the same green lights (for the rewritten tests at least), proving that the change really makes the test suite robust against even major implementation changes.

Oh, and 1000 LOC lost 💪 (mostly snapshots though).

Questions / to-do

I haven't yet figured for sure what to do with the generic fixture based snapshot tests. I'm leaning towards converting them to .innerText based snapshots, for the time being at least, that feels like the best balance between safety and sturdiness. What do you think?

@marcelltoth marcelltoth requested review from P0lip and a team March 9, 2021 16:44
@marcelltoth marcelltoth self-assigned this Mar 9, 2021
@P0lip
Copy link
Contributor

P0lip commented Mar 9, 2021

Yeah, I added these tests prior to switching to JST.
The goal was to verify the basic output, so that I could easier compare potential differences between JST <-> non-JST based version of JSV.
The outputs meant to be equal or almost equal back then, so it didn't quite matter.
Right now, when you're essentially making a major UI redesign, I'd probably drop existing snapshots, and also revise some schemas we use.

Where unsure what the real assertion is, I followed the title of the test case. Another downside of snapshots is that it's not always clear what is being tested (well... everything?), I sometimes had to make assumptions based on the scenario titles.

so I hope the above explains.
AFAIR I didn't mention that before, but you can probably nuke these output tests that we have.
They were added to help me migrate to JST to highlight any potential significant differences that occur right away when you render the component for the first time, so they didn't quite cover any user interactions such as expanding and so on.

expect(dumpDom(<JsonSchemaViewer schema={schema} defaultExpandedDepth={Infinity} />)).toMatchSnapshot();
render(<JsonSchemaViewer schema={schema} defaultExpandedDepth={Infinity} />);

expect(screen.getByText('array[string]')).toBeInTheDocument();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd refrain from such tests tbh.
At the very least we should verify the order they appear in component.
The fact that text is in the document does not imply they're render in the correct position, and with correct nesting.
If I swap the order of properties in JST or do something similar, this test won't catch it.

</div>
"
`;
exports[`HTML Output should match combiners/allOfs/base.json 1`] = `"object{5}AllOfMergeObjectsobject{2}Object1Propertystring>= 1 charactersObject2Propertynumber<= 2AllOfMergeValidationsstring>= 1 characters<= 2 charactersAllOfMergeTakeMoreLogicalValidationnumber<= 1AllOfMergeObjectPropertyValidationsobject{1}Propertystring>= 1 characters<= 2 charactersAllOfMergeRefsobject{4}street_addressstringrequiredcitystringrequiredstatestringrequiredzipCodestring"`;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mentioned earlier, this not validate nesting correctly.
You'll certainly want to assert the validation, colors (if we still use different colors for types, don't recall), etc. are all in all in the right state.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@marcelltoth
Copy link
Contributor Author

marcelltoth commented Mar 9, 2021

It looks like this textContent snapshot thing does it's job surprisingly well. (See #112)

image

UPDATE

I see your comments now @P0lip. Let me think about them reply to them tomorrow.:)

@P0lip
Copy link
Contributor

P0lip commented Mar 9, 2021

Where unsure what the real assertion is, I followed the title of the test case. Another downside of snapshots is that it's not always clear what is being tested (well... everything?), I sometimes had to make assumptions based on the scenario titles.

To add a bit more context to my previous comment.
It tested:

  • nesting
  • colors (each type had a different color)
  • the expandability of a node (well, just the presence of the expand button)
  • an actual content -> mostly title and type

@marcelltoth
Copy link
Contributor Author

marcelltoth commented Mar 10, 2021

@P0lip I get it. I agree that those things need to be tested. My problem is, I can't figure out any better way to test, a way which also stands the test of time (and a big change in structure).

You said your goal was to ensure safety when extracting JST, now mine is to ensure it when dropping tree-list and virtualization. While testing the structure would be nice I agree, keeping the structural tests then having to rebuild all the snapshots would give me way less confidence than these.

Unfortunately right now - because of virtualization - there isn't really an accessible DOM structure I could test nesting & stuff with.

After merging #109 I plan to update the DOM tree to use nested uls and lis with correct roles and attributes set, like this example. That will allow us to test all that you are asking for here, without snapshotting the DOM. But I really need something for this one step. 🤔 I'm open to ideas.

Again, not to convince you but I think it's not even as bad as it seems like:

  • nesting

There are tests explicitly for nesting in place, so there is some protection on that side.

  • colors (each type had a different color)

As @mallachari said we eliminated colors already, so no need.

  • the expandability of a node (well, just the presence of the expand button)

There are specific tests for this. So while maybe not everywhere but it is already covered.

  • an actual content -> mostly title and type

That is being tested with textContent.

So the question is: is this good enough for now? Or can you suggest some alternatives that will still provide value when being rebased on top of the structural changes?

/**
* Makes sure that exactly the first `desiredVisibleElementCount` elements from `hierarchy` are visible on the screen.
*/
const assertTreeFragmentVisible = curry((hierarchy: readonly string[], desiredVisibleElementCount: number) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

curried assertions <3

@P0lip
Copy link
Contributor

P0lip commented Mar 11, 2021

While testing the structure would be nice I agree, keeping the structural tests then having to rebuild all the snapshots would give me way less confidence than these.

I mean, the idea is that when you update the snapshot you do verify the output.
Basically, what I used to do was to go to storybook, see how a particular schema is rendered, and then I would update the snapshot for that given schema.
it's a bit time consuming, but that actually does give you confidence, that at least the initial schema that's get rendered is correct.
Obviously, this won't cover any interactions, like hovering over a tooltip, or expanding (the most error prone bit cause of flattening combined with stepIn), but it's arguably better than verifying just content.

There are tests explicitly for nesting in place, so there is some protection on that side.

Yeah, I get it, but what I'm saying is that these updated tests bring little value in general.
I mean, I'd rather just disable the tests until everything's implemented, and then rewrite them.
Will be probably easier.
So, my suggestion is to disable the existing tests, and keep on going with the UI revamp.

One could also try to use https://www.npmjs.com/package/treeify. We leverage that lib in a number of projects.

@marcelltoth
Copy link
Contributor Author

Closing in favor of updating snapshots for now, then later developing stronger tests on top of my structural changes. (Which will allow easier testing of nesting & such).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants