menu

Testing Library

Simple and complete DOM testing utilities that encourage good testing practices.

Channels
Chat
view-forward
# All channels
view-forward
# General
view-forward
# General Help
view-forward
# Angular Help
view-forward
# Cypress Help
view-forward
# DOM Help
view-forward
# React Help
view-forward
# Svelte Help
view-forward
# TestCafe Help
view-forward
# Vue Help
view-forward
Team

Testing form errors

February 4, 2020 at 9:12am

Testing form errors

February 4, 2020 at 9:12am (Edited 2 months ago)
For example
<form>
<div>
<label for="field-1">Field one</label>
<input type="text" name="field-1" id="field-1"/>
</div>
<div>
<label for="field-2">Field two</label>
<input type="text" name="field-2" id="field-2"/>
<p>This is required.</p>
</div>
<div>
<label for="field-3">Field three</label>
<input type="text" name="field-3" id="field-3"/>
<p>This is required.</p>
</div>
</form>
So I would like to assert the first field does not have an error and the second and third fields does have an error. It can be done using within utility, but this requires knowledge of the DOM structure. Since each "field" is actually rendered using an external library I can't really rely on the DOM structure being the same. Is there a better way to do this kind of thing?

February 4, 2020 at 3:59pm
Which part of the code is a "field"? Which part do you own? Which part 3rd party?
  • reply
  • like
Would you mind sharing a working example on codesandbox.io?
  • reply
  • like
Each <div> is a Field component. I own the form and would handle the submission. I would store the errors (as state) and pass them to each Field to render.
  • reply
  • like
and the errors are part of field?
  • reply
  • like
or do you own <p>This is required.</p>?
  • reply
  • like
Correct. It’s a react component. So I would just set an error prop on it.
  • reply
  • like
so something like this? <Field label={"field-1"} error={errors["field1"]} onChange={....} />
  • reply
  • like
there seem to be 3 testing possibilities here.
  • testing that the 3rd party library displays the errors correct (dont test 3rth party libraries)
  • testing that the developer passed the correct props to the 3rd party library
  • testing that the form validation returned the correct errors
Edited
  • reply
  • like
which one do you want the test to prove?
  • reply
  • like
or do you want to prove something else?
  • reply
  • like
I would say it's "testing that the developer passed the correct props to the 3rd party library"
So my test would be it("should display an error for the fields that failed validation", () => {});
  • reply
  • like
This is what I ended up doing to assert the errors.
expect(within(getByText("Field one").parentNode).getByText("This is required.")).not.toBeInTheDocument(); expect(within(getByText("Field two").parentNode).getByText("This is required.")).toBeInTheDocument();
So this works, but it does rely on knowledge of the DOM and I'm at the mercy of the 3rd party library rendering the field structure.
  • reply
  • like
maybe within(getByLabelText(/field one/i).closest('div')).getByText(...)
Edited
  • reply
  • like
Thanks, but this still kind of implementation details (i.e. closest('div')). In which case would enzyme be a better option for this kind of test case.
  • reply
  • like
Maybe add role to each div, const [field1, field2, field3] = getAllByRole('field')
  • reply
  • like
within(field1).getByText(/required/i)
Edited
  • reply
  • like