vendredi 29 janvier 2021

What is the best unit testing design for form tests?

The problem relates to the tests design. I'm attaching a pseudo code. let's assume that:

  • the form consists not of 3, but 14 (or more) fields
  • and each field has more business logic that needs to be tested (say 150 tests)
  • the proportions are that 75% of the tests will be the same for each field, 25% of the tests will be specific to each field on

Suppose this is an extended form which:

  • disables fields when form is submitting
  • shows validation error for each field. Some validators are the same (eg. "required"), some are specific for the particular fields (eg. email)
  • sends to analytics event (eg google analytics) field that user has started as the first one
  • also, field where a user commits an error
<form>
  <input name="firstName" disabled={isFormSubmitting} />
  <input name="lastName" disabled={isFormSubmitting} />
  <input name="email" disabled={isFormSubmitting} />
</form>

Here the pseudocode for tests:

// APPROACH 1 - one field, single tests, single assertion

describe('first name field', () => {
  test('should disable field when form is submitting', () => {});
  test('should display "required" error when form has been submitted without value', () => {});
  test('should send analytics event when user has started filling this field as the first one ', () => {});
  test('should send analytics event when user has committed an error', () => {});
});
describe('last name field', () => {
  /* the same tests + the ones specifir for the last name field */
});
describe('email field', () => {
  /* the same tests + the ones specifir for the email field */
});

// APPROACH 2 - tests for all fields at once if business logic is the same for all fields

test('should disable all fields when form is submitting', () => {});
test('should display "required" error for all fields when form has been submitted without values', () => {});
test('should send analytics event with field name when a user has started filling any field', () => {});
test('should send analytics event with field name when a user has committed an error for any field', () => {});

// but where tests which busines logic is specific for particular fields?

// APPROACH 3 - group by business logic. "one business logic", single tests, single assertion

describe('disabling fields', () => {
  test('should disable first name field when form is submitting', () => {});
  test('should disable last name field when form is submitting', () => {});
  test('should disable email field when form is submitting', () => {});
});
describe('showing required error', () => {
  test('should display "required" error for first name field when form has been submitted without value', () => {});
  test('should display "required" error for last name field when form has been submitted without value', () => {});
  test('should display "required" error for email field when form has been submitted without value', () => {});
});
describe('sending "a user started filling a field" analytics event', () => {});
describe('sending "a user committed an error" analytics event', () => {});

My question is which approach is better:

  • approach 1: is it better to group the tests into fields and test each field separately?
  • approach 2: is it better to group the tests into business logic and test all fields that behave the same in one test
  • approach 3: is it better to group the tests into business logic and each field should have its own test

Aucun commentaire:

Enregistrer un commentaire