Testability

As with many aspects of software development, there are many different ways of testing. Some will advocate a test-first methodology, where the tests are created first and the code will be written to satisfy these tests. Whichever method is used, we need to take steps to make sure our code can be tested. While this occasionally means adding in some helpful hooks and tricks that are only used to test, we should generally try to avoid this approach and look to write code that is naturally testable; this will often have the fortunate consequence of being better code too.

Sometime back, we talked about selectors and their relationship to testability. Let's look at the selector that Chrome Developer Tools gave us:

#gridview-1014-record-6 > tbody > tr > td > div 

This is a very specific selector and the first part of it is using an ID that was autogenerated by Ext JS. As soon as we add or alter the component hierarchy of the application or change the records being displayed on the page, this will break and our CasperJS tests will fail.

We can increase testability of our application by ensuring that our test code is less brittle. In this case, we can leverage the CSS classes that we use to style our application. Back in Chapter 9, A Shopping Application, when we built the category list view, we set the bodyCls configuration option to categories-body. This gives us a great way to target the list that we know isn't going to randomly change.

Using it in addition with the nth-child pseudo-selector gives us a simpler and more robust version of our original Developer Tools selector:

.categories-body table:nth-child(2) td

In plain language, get the element with a class of categories-body, find the second child table, which corresponds to the second row, and grab its td cell element.

Using Chrome Developer Tools is still a great way to look at the HTML structure of the page and work out an optimal selector for each case, but it's rarely going to provide the most robust selector.

Should I or shouldn't I?

There's plenty of lively debate about how testing should inform your code, if at all. In the last example, we had a useful CSS selector that was already being used for styling, but in the event we hadn't already placed it there, should it have been added specifically to support styling?

In this case, it's a very minor change, so we probably don't have to feel that bad about it. We could even wrap it in a Sencha Cmd directive to ensure that it doesn't get included in production builds:

//<debug>
bodyCls: 'categories-body',
//</debug>

In general though, anything that adds complexity or maintenance overhead to our main code base just to improve testability should be avoided. Instead, we can look at ways in which the design of an application naturally promotes testability.

Earlier in the book, we talked about MVC and MVVM and how one of the benefits of such patterns is to promote the separation of code concerns. Throughout, we've used events to ensure that components can "fire-and-forget" and trigger actions without having an awareness of other parts of the system.

This is a key feature that gives an elegant, clear design combined with a side benefit of separation of components. We can pluck out individual views, render them alone on a simple page, and perform tests on a single component in isolation. As in our Jasmine examples at the start of the chapter, we can take a single model and instantiate it without having to worry about the user interface layers.

The beauty of good application architecture is that it provides an understandable application that immediately lends itself to testing. Although, integration testing is an important weapon in our arsenal, it's much more important to ensure that the various parts of the machine are well built before trying to fire the whole thing up.

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

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