Encoding changes as tests

We've already explored how we can write tests to discover and specify current functionality, and, in previous chapters, we discussed the obvious benefits of following a Test-Driven-Development (TDD) approach. It follows that we should, when operating in an unfamiliar code base, always confirm our changes via cleanly written tests.

Writing tests alongside your changes is definitely a need when there are no existing tests. Writing the first test in an area of code can be burdensome in terms of setting up libraries and necessary mocks, but it is absolutely worth it.

In our previous example of introducing the capability of rendering videos to GalleryImage, it would be wise to add a simple test to confirm that <VIDEO> is correctly rendered when the URL contains the "/VIDEO/" substring. This prevents the possibility of future regressions and gives us a strong level of confidence that it works as expected:

import { mount } from 'enzyme';
import GalleryImage from './GalleryImage';

describe('GalleryImage', () => {
it('Renders a <VIDEO> when URL contains "/VIDEO/"', () => {
const rendered = mount(
<GalleryImage url="https://cdn.example.org/VIDEO/1234" />
);
expect(rendered.find('video')).to.have.lengthOf(1);
});
it('Renders a <IMG> when URL contains "/IMAGE/"', () => {
const rendered = mount(
<GalleryImage url="https://cdn.example.org/IMAGE/1234" />
);
expect(rendered.find('img')).to.have.lengthOf(1);
});
});

This is a rather simple test; however, it completely encodes the expectations we have after making our changes. When making small and self-contained changes or larger systemic changes, it's so incredibly valuable to verify and communicate our intent via tests like these. As well as preventing regressions, they aid our colleagues in terms of immediate code review, and the entire team in terms of documentation and general reliability. As such, it's quite normal and preferable to have a team mandate or policy that says you cannot commit a change if it does not come with a test. Enforcing this will, over time, create a code base that produces more reliable functionality for users and is more pleasant to work with for fellow programmers.

We've now completed the section on Inheriting code, and so you should have a good foundational knowledge of how to deal with such a situation. Another challenge in dealing with other people's code is the selection and integration of third-party code, meaning libraries and frameworks. We'll explore this now.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.150.123