In an earlier post I talked about why developers should be more active in helping write automated UI tests. If you haven't read that post already, I'd encourage you to, because this post builds off that other one.
The TL;DR version of that earlier post: developers really need to be involved in what's going on at the UI testing level. Devs' involvement is a critical piece of overall success for a team's automation efforts.
Regardless of whether it's Kendo UI Professional or Kendo UI Core, Telerik Kendo UI gives organizations a tremendous set of tools to quickly create amazing, responsive, performant systems. Even though Kendo UI makes it easy to build gorgeous UIs, teams regularly struggle with getting solid UI testing wrapped into their delivery flow. Teams often run into issues with asynchronous operations, difficult Document Object Model (DOM) structures, or browser incompatibilities that challenge team members writing functional UI tests.
Telerik Test Studio helps teams solve just these problems, and the terrific integration points with Kendo UI make it even easier. Moreover, Test Studio helps you create solid, flexible, maintainable test suites that won't kill you with high maintenance costs as your system grows. You can focus on delivering exciting value, rather than spending half or more of your time updating broken tests.
Test Studio gives developers a number of great tools and features to work together with testers in building up powerful, flexible test suites:
Test Studio comes in two versions: a plugin for Microsoft Visual Studio 2010 or later, and a standalone edition. The Visual Studio plugin brings all the features above right into Visual Studio; the Standalone edition supports all that plus load and performance testing. If you're working in an organization that separates its testers and developers then having both versions of Test Studio means it's easy for testers to record and modify tests, then hand off or work with developers to extend those tests with a small amount of code as needed.
Both versions of Test Studio support Telerik's scheduling and storage server, or you can integrate to your existing build, deployment, and execution infrastructure--you're able to make use of Team Foundation Server, Jenkins, Hudson, Team City, or any other build system. That makes it a snap to tie in with other unit and integration tests you (hopefully!) have running.
Haven't used Test Studio before? No worries--I'll walk you through it right now.
I'm using a simple Kendo UI Grid in the example for this post. I've built up a data source in a SQL database, and fooled around with getting an edit feature already hooked up. Now I need to add Create functionality. (I realize it's a bit backward, but it's how I rolled for this one. Cart, meet horse.)
Planning your tests is every bit as important as planning your production code--because tests are production code! In this case, we want to make sure the test is specific, accurate, and maintainable. We'll also need to ensure we're able to properly identify the elements we need on the screen so we can head off any potential problems with how Test Studio's recorder works.
Take a few moments to clearly think through what your test's purpose is: What's the business value you're trying to confirm? Are you sure you're working on a high-value test; something that validates critical functionality versus trivial look-and-feel? What steps will you take during your test? What data do you need? What verifications (sometimes called "checkpoints" or "asserts" in other systems) will you need? Do you need any helper functions or libraries to help you?
Once that's done, it's time to get a feel for how your test script will run. Regardless whether you’re using Test Studio, Selenium WebDriver, Canopy, or some other tool, all UI tests require a way to find or locate specific elements on the page you're interacting with.
Most UI test tools use some form of a page's Document Object Model (DOM) to locate elements on the page. Locator strategy is the most critical aspect of maintainable tests. Locator strategy is a post or four all on its own, but in general you should prefer use of ID attributes as your primary strategy if IDs exist on the element and aren't dynamically generated. Name attributes are a great fallback if an ID isn't present. Other options include CSS Class attributes, JQuery-style references, and XPath.
We can use Chrome's Inspector to check out the page's current DOM. Note the button and its corresponding DOM element. Currently there's no 'ID' attribute, but the 'class' attribute has part of its value as 'k-grid-add'.
Using ‘class’ for a locator is normally acceptable; however, below I’ll show you how easy Kendo UI makes it to create a perfect locator.
While we're here, we can also look at the Edit dialog and get a feel for its part of the DOM. Kendo UI nicely gives us 'name' attributes on each input field, so we're good to go.
Unfortunately, when you inspect the row of a Kendo UI Grid (or most other HTML grids, frankly), a problem appears: there's no ID. This row has no usable attributes at all.
We could approach this problem by building locators based on XPath or using the InnerText property of a row; however, both those techniques aren't optimal. We could also build a locator based on row position; however, that's nearly as close to a Worst Practice as possible because the test will break if anything impacts data on the table.
To solve this we need to add an ID attribute to each row that contains enough useful information that we could latch onto. In this case, we can update our Kendo UI Grid's definition to include code in the DataBound event that will add the desired ID to our DOM. For this simplistic example, I'm going to add in the row index plus the contact's last name. Tailor this approach in your own systems to work with whatever unique data you might have access to.
The update is highlighted with the red box below.
One issue to keep in mind with this particular solution: this does loop back through each item in the returned dataset, so there could be potential performance issues if you're working with large returned page sizes. As with everything, talk it over and make sure it's the right solution for your situation.
While we're here, let’s take an extra moment to make the Create button even more testable by adding an ID attribute to it. That's a snap with one statement added to the same spot in our Kendo UI grid's definition.
That addition gives us a much nicer UI to work with! We’ve now got usable IDs on every row and the create button.
Now it's time to move on to building our tests.
First, add a Test Studio project to your solution. Use Projects => Add and then select the Test node in your language of choice, or the Test node under Telerik. Choose Telerik Test Studio in the middle Project Type pane. Finally, give your project a good name. (I'll avoid using this post to start a pursefight about naming. It's an even more inflammatory topic among developers than tabs versus spaces...) Once your test project is built you add tests to it as needed.
Before you begin creating tests, you'll need to change two default settings for Test Studio to work properly with Kendo UI controls. Under the Test Studio project settings (middle icon in the Test Studio toolbar), select the Recording Options and check Simulate Real Clicks by Default and Simulate Real Typing by Default. These two settings cause Test Studio to use system desktop APIs to inject keystrokes and clicks versus working with properties in the DOM of the in-browser page. You'll need this set by default in order to properly work with Kendo UI controls.
One other item of note here: the Browsers area of the Settings panel. This section enables you to calibrate settings on each browser to enable smooth recording and stable playback of tests. Non-calibrated browsers show as red. Simply click the appropriate button to properly calibrate that browser.
Add a Test Studio test item to your project. You can use any of the 9,742 various ways for adding new items; the image below uses the right-click method. Note Test Studio web and WPF tests are specifically called out.
Make sure the correct test type’s selected, then give it a good name.
From within a test item, start your recording session by selecting the browser you'd like to work in. Test Studio supports Internet Explorer, Firefox, Chrome, and Apple's Safari. (Apple's stopped supporting Safari on Windows; however, Test Studio still ships plugins for it.)
I'm using Chrome for this example. Chrome starts and you'll see Test Studio's info page. Pay attention to the popup calling your attention to the recorder's address bar! You have to use this in-browser panel when navigating.
Type your URL in this field and press enter. Chrome will load the page, and Test Studio will start recording actions inside the Visual Studio test pane.
Record your test by taking the actions needed to walk through the scenario you've thought out. Here I'm testing the Create New Contact function, so I'll need to click that button, enter a contact's info, save it, and verify its accuracy on the grid.
As you record actions Test Studio adds steps to the test pane. Interactions with the page (clicks, text entry, etc.) populate the target elements into the Element Repository.
Verify the entry by creating verifications for each field in the row. You could simply use the inner text of the entire row as one verification point; however, that's a brittle path to go down: the test is guaranteed to fail if the column order changes or a new column is added. Instead, take the slightly longer approach of validating each column's value separately.
To build verifications click the hover-over highlighter in the toolbar.
Next mouse over the Region cell for the row you just created and pause. You’ll see a red outline appear around the element and Test Studio’s Elements Menu will appear.
Select Verify Text Content and add it to your test. Repeat for each cell in the row. Repeat for each table cell in the row. Exit Chrome when you're done. The completed test looks something similar to the image below.
Test Studio's Record and Playback is a tremendous productivity booster, but you have to be carefully aware of how it creates find logic by default. Often it's simply not possible to automatically create find logic that's specific enough yet flexible enough to handle dynamic situations.
In this case, the find logic for table cells isn't very appropriate. It's simply the equivalent of "find me any cell in the table with 'Arrakis' in it, regardless of what row it's in." That means this test could pass if a different row has 'Arrakis' as its region. Whoops.
We want validations that are bound to the correct row of data. There are a number of ways we could solve this, including modifying each cell to include the unique row ID we built above.
Instead I’m going to show you a different way to handle this using chained find expressions in Test Studio. This concept is extremely useful in many situations where you don’t have control over IDs. We’ll start by first finding the unique row, then finding each cell under that row.
Start Internet Explorer and navigate to the page for the app. Select the verification step in the Test Explorer pane. Note the element repository highlights the correct element for that test step. Right-click the element and select Edit Element.
Test Studio offers three options for editing elements. Find Without Connection is great when you know exactly what you’re changing and you don’t need to validate it on a live page. We’ll use Find in the Live Version.
You’ve also options for connecting to the live page, including the highly useful, nifty method of using a test to drive you to a particular spot. We’ll use the browser we just fired up. In the Current Page section, select the open IE instance and click Go.
This live connection lets you validate your edits against the actual web page—you can see exactly how your updated find logic will (or won’t!) work.
The Find Element’s Find Settings pane lets you customize find logic for the situation you’re trying to solve by creating groups of filters. Each group is made up of one or more criteria based on any property available for that type of element. Attributes like ID, name, or class are all obvious; however, using properties like TextContent, InnerText or OuterHtml give you some incredible power.
Our current problem’s quite simple, so the locator below will fit the bill. You’ll get a nice visual confirmation on the locator’s correctness: the element located by the expression is handily highlighted in the open IE session!
Saving the updated settings updates the find logic not just for the current step, but for every step in every test that uses the same element. That’s a tremendous help for easing maintenance impacts!
Follow this same pattern to update locators for each verification.
As with anything to do with software engineering (yes, test automation IS software engineering!), there are many ways to handle the problems above. Instead of text verifications on the same text used in the locator, I could have verified each table cell’s presence based on that flexible locator. This example’s quite simplistic; in the “real world” (wherever that is), I’d likely use a customer number or some other unique data instead of just the last name.
And so on and forth.
Hopefully this hands-on section here has given you some insight on how easy it is to use Test Studio to create powerful, flexible tests. As a developer, you’re not done there, though. There are still many things you can do to help your team create better tests.
One of the best value-ads for Test Studio is the translator plugins for Telerik controls. The translators expose lots of other great functionality based on the context you’re in. In Grid controls, you’re able to fan out from any highlighted element and vary the scope from that element to its parents—from a table cell all the way up to the containing Grid.
Translators expose context-specific tasks, such as one-step validation of a grid’s row count, for example.
Translators are maintained by each control team at Telerik, so you’re ensured of great features and updates.
As a developer, making a system that’s easy to test means looking at a number of different things.
IDs are nearly always the best thing a developer can do to help with great tests. Above I showed how easy it was to tailor the Kendo UI Grid with custom IDs for rows, and to add on a static ID for the Create button. Keep this in mind as you build out your UI: what elements can you add IDs to for easing testing?
Learning how to cope with asynchronous updates is a difficult task for teams. Simple async calls can easily be handled with Test Studio’s Wait features.
More complex situations can be solved with code that adds elements to the DOM when particular AJAX calls complete. For example, use the requestEnd event in a Kendo UI dataSource to add elements to the page after an update is complete. Then you’re able to use that element’s presence as the condition in a Wait for Present action.
If you’ve multiple connections then perhaps you’ll need to do the same general approach, but instead monitoring $.ajax() for open connections. Perhaps your system has complex custom queuing events that enable or disable parts of the UI. Creating helpers around those lock/unlock events can dramatically ease the frustration of your entire team.
Kendo UI isn’t just for building great applications. It’s also for building great testable applications! Make use of Kendo’s customization and adaptability to do things like add IDs to elements, create custom events, and sprinkle other testing hooks across your application.
Pair Kendo UI with Telerik Test Studio and you’ve got a great combination for creating valuable, flexible, low-maintenance test suites that will keep your systems running smoothly throughout their lifetime.
Jim is an Executive Consultant at Pillar Technology. He is also the owner of Guidepost Systems. He has been in various corners of the IT world since joining the US Air Force in 1982. He’s spent time in LAN/WAN and server management roles in addition to many years helping teams and customers deliver great systems. Jim has worked with organizations ranging from startups to Fortune 100 companies to improve their delivery processes and ship better value to their customers. When not at work you might find Jim in the kitchen with a glass of wine, playing Xbox, hiking with his family, or banished to the garage while trying to practice his guitar.