Background: I am new to testing in general, and have been studying it in context of JavaScript, specifically React.js, front-end development (actually new to this as well). For the question, I have these 2 similar cases:

Case 1: My code and a library

I'm using UI library and aside from its decent design, I want to leverage its form validation utilities. I want to test this validation, but not sure how to do it.

  • Option 1: Just test for the behaviors I expect

    It would be testing if my field (which is a sub-module of the library itself) receives the library-specific classes for fields with errors as expected, and if these errors prevent from calling the submit handler I passed to the form (also sub-module of the library).

    • Problem A with Option 1

      I am very likely to be duplicating tests that are already covered by the library itself. (e.g. I am testing if the field receives the error classes when the input is invalid when the library itself has tested if it does so, given the right configuration.)

    • Problem B with Option 1

      It slightly couples the test code to the library, i.e. I have to use library-specific classes and markup to evaluate my code.

      Okay, this is actually a side-question, is this a bad thing for a test? Is this making the test brittle, or is what they call 'contract' that is actually necessary for unit tests?

  • Option 2: Test which sub-module is used and what configuration is passed

    • Problem A with Option 2

      This is much more brittle, I think, It's almost like repeating the implementation (i.e. repeating the type sub-module used, and the configuration passed to it.)

    • Problem B with Option 2

      Same as Option 1's Problem A -- coupling test to the library's API, specifically its configuration API. (Again, not sure if this is just test being brittle, or contract being written)

Case 2: My code and its sub-component

I have my good 'ol to do app. Its to do list component has addTodo() method and it passes to its sub-component to do field. I want to test its feature to add todo item, but not sure on how to do this either.

  • Option 1: Again, just test for the behaviors I expect

    Test `to do app` that if input and submit with sub-component `to do field`, another `to do item` is added. (This is implemented by passing `addTodo()` method from `to do app` to `to do field` as onSubmit handler)
    • Problem A with Option 1

      If I'll do this, is there still a point in unit testing the to do field alone? If I already unit-tested to do field that it calls any onSubmit handler upon submitting, wouldn't this to do app test case indirectly repeating to do field's test case??

  • Option 2: Test if correct sub-component is used and what configuration is passed (Similar to Case 1's option 2)

    Its specs would look like this:

    • Unit test to do app to assert...
      • that to do app's addTodo() method adds a todo item properly
      • that to do app renders to do field sub-component
      • and that to do app passes addTodo() to as onSubmit handler to to do field
    • then also unit test to do field to assert that...
      • that to do field calls the onSubmit, which is received from parent component, during submit

The Question

Which of these options are better, especially if I favor BDD over TDD? Also, please correct me if you noticed I misunderstood anything. Thank you.

  • 1
    I'd avoid testing 3rd party library code in general. Your approach concerns me though because you're coupling your validation (which is business logic) to a specific UI. Change UIs (or even to another library) and it seems like you'll be throwing your business logic away. – Andy Jul 11 '17 at 21:09
  • What would be the better approach? – Christopher Regner Jul 11 '17 at 21:29
  • Keep your business logic in a business library that doesn't have any dependencies on UI. An N-layer, DDD, onion, whatever you want to call it approach. – Andy Jul 11 '17 at 21:31
  • Hmm, my understanding is that in BDD, in order to test the behavior, you inevitably involve the UI, this is what I've observed in JS front-end development. – Christopher Regner Jul 11 '17 at 22:16
  • Not sure where you got that idea, that sounds off to me. MSpec for example is a BDD framework. Its mostly a shift in your thinking about how to build the unit test. Integration / acceptance tests may involve the UI, but nothing in BDD to me suggests it has to involve the UI. en.wikipedia.org/wiki/Behavior-driven_development – Andy Jul 11 '17 at 22:42

You are testing a user interface. This is exactly what functional testing was created to do. You want to test the behavior of the interface you've created, specifically:

  • When the screen is first loaded, is the submit button visible/selectable? If it shouldn't be, you can test for that.
  • Enter invalid data into your text field. Use all the different types of invalid data that you have configured to check. The submit button should probably be visible/selectable, but clicking it should generate some kind of error message. Check that the error message displays as you expect it to.
  • Enter valid data into your text field. The submit button should be visible/selectable, and clicking on it should produce the correct result. Check that the correct result is displayed.

Using functional testing like this prevents coupling to your library. Changing the library should result in these tests passing. Even dropping the library and rolling your own validation routines should result in these tests passing.

If you haven't chosen a functional testing tool, you may want to consider Selenium. It will enable you to write and run functional tests.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.