Test driven development in ReactJS

 Suppose you are developing a large website/mobile app and your task is way too complex.

Under these circumstances Test driven development can help in controlling complexity. It gives developers breathing space. It lets them keep code bug free from the ground up. You would not believe it but most people get burnouts from developing software if they aren't adopting TDD.

So how do you do Test Driven Development?

TDD for short is by writing a test case before you write even one line of code. Naturally the test case will fail initially. This gives the developer some breathing space, some respite of having written something like a test case no matter if the code that is going to be tested is unwritten as yet!!!.

Now I am going to show a component that I wrote following an article on the internet that spoke of TDD.

import React from 'react';
export default class MyComponent extends React.Component {
    handleUpdate(event) {
        this.setState({ input: event.target.value });
    }
    render() {

        return (
            <div>
                <form>
                    <h1>Form Testing2</h1>
                    <input

                        onChange={this.handleUpdate.bind(this)}
                        type="text"
                    />
                </form>
            </div>
        );
    }
}

This component in ReactJS simply registers a handleUpdate function that sets the value of the state whenever the input value changes.

The testing starts by writing the import statements to get the required testing tools:

//MyComponent.test.js
import React from 'react';
import {shallowfrom 'enzyme';
import MyComponent from './MyComponent';
import diff from 'jest-diff';

Now to test this component you might need to write a snapshot test that does flags you of any changes to the component DOM.

Once there are any changes to the component you need to investigate further if the changes introduced have caused existing features to regress.

This can be found out by writing test cases such as:

Snapshot Test:

it("Should render initial layout",()=>{
//when
const component=shallow(<MyComponent/>);
//then
expect(component.getElements()).toMatchSnapshot();
});

Input element to be defined when input props changes:

it("should create an entry in component state", () => {
    // given
    const component = shallow(<MyComponent />);
    const form = component.find('input');
    // when
    form.props().onChange({target: {
       name: 'myName',
       value: 'myValue'
    }});
    // then
    expect(component.state('input')).toBeDefined();
});

The third test case we write will test if the value on the component state is set to the input that we provided to the component.

it("should create an entry in component state with the event value", () => {
    // given
    const component = shallow(<MyComponent />);
    const form = component.find('input');
    // when
    form.props().onChange({target: {
      name: 'myName',
      value: 'myValue'
    }});
    // then
    expect(component.state('input')).toEqual('myValue');
  });

All these tests are written first and then when the test fails the component is updated to add the feature so that the test passes.

This style of development is easier on the developer. Finally upon running the tests we get the following report:(Two test cases extra that I have added just for learning)

PASS  src/Components/MyComponent.test.js

  MyComponent

    √ Should render initial layout (7ms)

    √ should create an entry in component state (4ms)

    √ should create an entry in component state with the event value (1ms)

    √ should display differrences (18ms)

    √ two plus two is four

    √ adding positive numbers is not zero (9ms)

Test Suites: 1 passed, 1 total

Tests:       6 passed, 6 total

Snapshots:   1 passed, 1 total

Time:        2.882s, estimated 24s

Ran all test suites.

Watch Usage: Press w to show more.

 Upon pressing w we get these options:

Watch Usage › Press f to run only failed tests. › Press o to only run tests related to changed files. › Press q to quit watch mode. › Press t to filter by a test name regex pattern. › Press p to filter by a filename regex pattern. › Press Enter to trigger a test run.

These options are important to actually investigate if some of the test fail.

We can execute only the failed test which gives us further data about what went wrong. Or if we want to run tests on only those files that have changed then we have that option also.

Comments

Popular posts from this blog

HTTP then HTML then WWW then CSS+JS and then comes Hell

ReactJS is cool