Evolution in Data Integration From EII to Big Data
Approaches to integrating data are changing with emergence of cloud computing.
The content has been bookmarked!
There was an error bookmarking this content! Please retry.

Posted by Jian Fang on Sep 21, 2010
ui.Container(uid: "GoogleSearchModule", clocator: [tag: "td"]){
InputBox(uid: "Input", clocator: [title: "Google Search"])
SubmitButton(uid: "Search", clocator: [name: "btnG", value: "Google
Search"])
SubmitButton(uid: "ImFeelingLucky", clocator: [value: "I'm Feeling
Lucky"])
}
As shown in this example, the UI module is a set of nested UI elements with tags and attributes. The adoption of the UI module makes Tellurium expressive, and robust to changes. It is also easy to represent dynamic web content, and easy to maintain.
In today’s hyper-competitive world, later may be too late to adopt Agile development and this Roadmap for Success will help you get started. Download "Agile Development: A Manager's Roadmap for Success" now!
The framework comprises the following components:
The main features are:
For example:
type "GoogleSearchModule.Input", "Tellurium test"
click "GoogleSearchModule.Search"
In addition the framework:
The Selenium web testing framework is one of the most popular open source automated web testing frameworks. It is a ground-breaking framework offering many unique features and advantages such as: browser-based testing, Selenium Grid, and "record and replay" of user interactions with the Selenium IDE.
However, Selenium has some issues. Take the following test code for example:
setUp("http://www.google.com/", "*chrome");
selenium.open("/");
selenium.type("q", "Selenium test");
selenium.click("//input[@value='Google Search' and @type='button']");
If one were not familiar with the Google search page, could one tell what the UI of the page looked like based on that code? What does the locator q mean in this instance?
What if the XPath //input[@value='Google Search' and @type='button']became invalid due to changes on the web? More than likely, the test code would have to be reviewed in its entirely to locate the lines that needed to be updated.
What if there are tens or hundreds of locators in the test code? Creating the test code using the Selenium IDE may be easy to use initially, but it is difficult to generalize and refactor.
Refactoring is a more tedious procedure than generating new test code from scratch. The reason for this is that hard-coded locators tightly coupled with the test code are being used. Maintaining the code can be difficult because the test code is not structured.
Selenium is a good framework when it acts as a low level web test driving framework. However, it requires a lot of effort to create robust test code.
Tellurium was built with the goal of solving most of these issues with Selenium.
Tellurium is also designed to address other weak points of Selenium. For example, IE performance is a prominent issue for Selenium. The Tellurium solution to this situation is to use CSS selectors as the default locators. The locators are automatically generated from the UI module, improving the test speed.
Test speed is further improved with the Tellurium UI module caching and command bundling using the new Tellurium Engine. Tellurium also assists in the testing of Ajax applications: The List and Table Tellurium UI objects are used to represent dynamic web content at runtime. The option object is used to represent two different UIs at runtime for the same web element.
Like Selenium, Tellurium is used to test any web applications based on the HTML DOM structure.
Tellurium takes a new approach to automated web-testing through the concept of the UI module. Objects are used to encapsulate web UI elements so that manually generalizing and refactoring of the UI locators is not required. The UI module is simply a composite UI object consisting of nested basic UI objects.
The framework runs in two modes. The first mode is to work as a wrapper to the Selenium framework. That is to say, the Tellurium core generates the runtime locator based on the UI object's attributes in a UI module. The generated runtime locator is then passed in the Selenium call to the Selenium core with Tellurium extensions.
Tellurium is also developing its own test driving engine, the Tellurium Engine, to better and more efficiently support UI modules.
The following example, which uses the issue search UI on the project web site, illustrates the idea.
We start by defining the UI module for the issue search UI
ui.Form(uid: "issueSearch", clocator: [action: "list", method: "GET"]) {
Selector(uid: "issueType", clocator: [name: "can", id: "can", direct:
"true"])
TextBox(uid: "searchLabel", clocator: [tag: "span", text: "for"])
InputBox(uid: "searchBox", clocator: [type: "text", name: "q", id: "q"])
SubmitButton(uid: "searchButton", clocator: [value: "Search", direct:
"true"])
}
The following test method is used:
public void searchIssue(String type, String issue){
select "issueSearch.issueType", type
keyType "issueSearch.searchBox", issue
click "issueSearch.searchButton"
waitForPageToLoad 30000
}
If for some reason, the Selector is changed to an input box, then we just update the UI module accordingly
ui.Form(uid: "issueSearch", clocator: [action: "list", method: "GET"]) {
InputBox(uid: "issueType", clocator: [name: "can", direct: "true"])
TextBox(uid: "searchLabel", clocator: [tag: "span", text: "for"])
InputBox(uid: "searchBox", clocator: [type: "text", name: "q", id: "q"])
SubmitButton(uid: "searchButton", clocator: [value: "Search", direct: "true"])
}
then change the command:
select "issueSearch.issueType", type
to:
type "issueSearch.issueType", type
and the rest remains the same.
When there is dynamic web content, taking the Google Books website as an example, the UI includes a list of book categories with a list of books inside each category. The UI module for this UI is surprisingly simple to use as follows:
ui.Container(uid: "GoogleBooksList", clocator: [tag: "table", id: "hp_table"]) {
List(uid: "subcategory", clocator: [tag: "td", class: "sidebar"], separator:
"div") {
Container(uid: "{all}") {
TextBox(uid: "title", clocator: [tag: "div", class: "sub_cat_title"])
List(uid: "links", separator: "p") {
UrlLink(uid: "{all}", clocator: [:])
}
}
}}
The Tellurium UID description language (UDL) provides more flexibility to define dynamic web content. Let us see a complex example.
ui.StandardTable(uid: "GT", clocator: [id: "xyz"], ht: "tbody"){
TextBox(uid: "{header: first} as One", clocator: [tag: "th", text: "one"], self:
true)
TextBox(uid: "{header: 2} as Two", clocator: [tag: "th", text: "two"], self: true)
TextBox(uid: "{header: last} as Three", clocator: [tag: "th", text: "three"],
self: true)
TextBox(uid: "{row: 1, column -> One} as A", clocator: [tag: "div", class: "abc"])
Container(uid: "{row: 1, column -> Two} as B"){
InputBox(uid: "Input", clocator: [tag: "input", class: "123"])
Container(uid: "Some", clocator: [tag: "div", class: "someclass"]){
Span(uid: "Span", clocator: [tag: "span", class: "x"])
UrlLink(uid: "Link", clocator: [:])
}
}
TextBox(uid: "{row: 1, column -> Three} as Hello", clocator: [tag: "td"], self:
true)
}
In the above example, we use meta data "first", number, and "last" to indicate the header positions. The meta data "{row: 1, column -> One} as A" means the UI element, a TextBox in our case, is in row 1 and the same column as where the header "One" is. The test code is very clean, for example:
getText "GT.A"
keyType "GT.B.Input", input
click "GT.B.Some.Link"
waitForPageToLoad 30000
Tellurium is a young and innovative framework with many novel ideas from both the development team and the user community. There are many areas Tellurium would like to develop:
Other areas of the framework to be developed include:
Jian Fang graduated from Georgia Institute of Technology with a Ph.D. degree in Electrical and Computer Engineering. He works as a senior software engineer in a company in the IT industry and mainly focuses on the design and implementation of enterprise applications. He is the creator of the Tellurium Automated Testing Framework.
We have been using Tellurium for some time now, our tests are more expressive now with low cost of maintenance.
Project site:
code.google.com/p/aost/
Tellurium User Group
groups.google.com/group/tellurium-users
Tellurium on Twitter
twitter.com/TelluriumSource
Tellurium IDE
code.google.com/p/aost/wiki/TelluriumIde080RC1
We're using tellurium's tests and data-driven tests for our testing. With Tellurium, we've been able to overcome issues that we had with Selenium tests on web pages with Ajax. The Tellurium developers are the most responsive open source developers that I've interacted with. Awesome software!
Jade
May be I am jumping the gun here, since I have not given it a try yet or may be I am too used to Selenium but the code examples for Tellurium look pretty verbose syntactically as compared to Selenium
Consider the following command in Selenium:
selenium.click("//input[@value='Google Search' and @type='button']");
In Tellurium, the command is
click "Google.Search"
Which one is verbose?
Not only is Tellurium a great framework for doing web-testing but the community, although small, is very responsive to the needs of the users. I've seen a very quick response to problems I've reported via the mailing list.
Compare full working snippets. Your example is misleading. You haven't shown the code necessary to create the "Google" module in Tellurium.
we've been able to overcome issues that we had with Selenium tests on web pages with Ajax
Could you please elaborate? In particular, what type of Ajax testing issues are you referring to?
I don't think InfoQ wants me to post all code, but most stuff has already been posted. Here is the full UI module class:
public class GoogleSearchModule extends DslContext {
public void defineUi() {
ui.Container(uid: "GoogleSearchModule", clocator: [tag: "td"]){
InputBox(uid: "Input", clocator: [title: "Google Search"])
SubmitButton(uid: "Search", clocator: [name: "btnG", value: "Google Search"])
SubmitButton(uid: "ImFeelingLucky", clocator: [value: "I'm Feeling Lucky"])
}
}
public void doGoogleSearch(String input) {
type "GoogleSearchModule.Input", input
click "GoogleSearchModule.Search"
waitForPageToLoad 30000
}
}Compare full working snippets. Your example is misleading. You haven't shown the code necessary to create the "Google" module in Tellurium.
And isn't that verbose?
You mean the UI module definition? Isn't it very expressive about
the UIs under testing? Once you define it, you always use UIDs to
reference UI elements, which is not verbose.And isn't that verbose?
Approaches to integrating data are changing with emergence of cloud computing.
Michele Ide-Smith presents the lessons learned in the process of introducing UX principles and techniques into a large organization through a series of small steps.
Dave Farley and Martin Thompson discuss solutions for doing low-latency high throughput transactions based on the Disruptor concurrency pattern.
Rajneesh Namta shares his thoughts, experiences, and some of the critical lessons learned while implementing software test automation on a recent Agile project.
Dale Schumacher presents several patterns of actor interaction that can be used in collaborative programs written in any language.
Rúnar Bjarnason discusses Scalaz, a Scala library of pure data structures, type classes, highly generalized functions, and concurrency abstractions to perform functional programming in Scala.
One of the main challenges when designing software architecture is considering quality attributes. Not only their design turns out to be difficult, but also the specification of these attributes.
Michael Feathers analyzes real code bases concluding that code is not nearly as beautiful as designers aspire to, discussing the everyday decisions that alter the code bit by bit.
11 comments
Watch Thread Reply