The evolution of .test as a languageby edA-qa mort-ora-y on Wednesday July 09 2008 @ 20:22:25 (11/11 Points) |
|
| General ↪Other ✑ Reply ✓ Stick It ✗ Ditch It ⚐ Tag It |
The An_example_using_Google→ has simple code like the below. The question I was posed was what this would look like not using our specialized test language. It is a fair question, as it addresses why one would want to use our language.
GotoURLAbs http://www.google.com/
Notice %Response://form[@name='f']/@action%
SubmitForm with
%Params% with
%q% 4 + 5
end
end
Check //b[contains(string(),'4 + 5 = 9')]Evolution
Let me think back to the very beginning, before we had any framework, we would have been using something like HTTPUnit (now perhaps HTMLUnit). I can't remember exactly, but the code above would look something like this in Java.
package testplan.sample;
import com.library.html.*;
class GoogleTest {
public static void main() {
Connection cnx = new Connection();
try {
Response resp = cnx.gotoURL( "http://www.google.com/" );
Form form = resp.getFormByName( "f" );
System.out.println( form.getAction() );
form.setParameter( "q", "4 + 5" );
Response next = form.submit();
Locator loc = next.getLocatorByXPath( "//b[contains(string(),'4 + 5 = 9')]" );
if( loc == null )
System.err.println( "Result not found." );
else
System.out.println( "Okay" );
} catch( Exception ex ) {
System.err.println( "Something failed: " + ex.toString() );
}
}
}Now this is more simplified than in reality. If you notice we are not actually checking for exceptions on all steps, so we don't have easy logging of where failures occurred, nor do we really know what they are. This can also not be well integrated into an overall test framework; it is a simple main function. Plus, well, there are many additional small additions that would actually be needed, but let's move on nonetheless.
After a while of doing this we naturally built a framework on top of the HTML library. Eventually the library performed all the small details for us and allowed code like this.
package testplan.sample;
import our.library.*;
class GoogleTest extends WebTestUnit {
protected function intExecute() {
doGotoURLAbs( "http://www.google.com/" );
Form form = doGetFormByName( "f" );
notice( form.getAction() );
form.setParameter( "q", "4 + 5" );
doGotoRequest( form );
doCheck( "//b[contains(string(),'4 + 5 = 9')]" );
}
}This is getting smaller, the syntax is still not optimal, but that isn't the major annoyance anymore. You see, there are only six lines of code that actually do something, yet there are about ten effective lines in the code, plus a few trailing terminators. That means about half of this code has nothing to do with the test we are writing. But for Java that's it! There is just no more effective way to reduce the code.
But look back to the original example now, you'll notice it is a lot smaller. In fact it is only about 40% the size when comparing total bytes. Beyond the size it is also a lot clearer as to what is being done; we aren't bogged down by the Java syntax.
This is not meant in any way as a slight towards Java. Indeed the test language VM is written in Java. It's just that Java was designed to be general purpose, and as such suffers from bulk in certain specialized domains. Test scripts happen to be one of those domains. In some cases however proper Java code is still better, and therefore interaction between the test language and Java is painless -- in fact the test language itself doesn't care whether functions are written in .test or Java.
XPath Insanity
Another reason to have the custom language was that our basic data types included strings and XPaths; it makes up more of the code than anything else. Further to that, what we were testing also ensured that we'd encounter every special character imaginable in those two data types, therefore escaping became a major issue.
For example, consider this rather innocuous looking string:
Henry Jone's Quartet & The Amazing "Rock"!
Now consider you'd like to find a row in a table containing this string. The actual XPath needs to be something like below. It's frightening nature comes from XPath having no way to escape a quote.
//tr[*/contains(string(),concat("Henry Jone's Quartet & The Amazing ",'"Rock"!'))]So now imagine the fun you'll have getting this right while also considering that Java needs to escape the quotes!
Well, that isn't quite fair. You should probably create an XPathLiteral function which will handle escaping for you. We did, but it is still bulky to use. Consider the following check for this XPath on a web page.
String subject = "Henry Jone's Quartet & The Amazing \"Rock\"!"; String xpath = "//tr[*/contains(string()," + XPath.literal( subject ) + ")]"; doCheckNode( xpath );
In .test it is a lot easier to work with XPaths as they are supported as a native type. Thus you don't really worry about escaping so much, you just do what seems right.
set %subject% Henry Jone's Quartet & The Amazing "Rock\"! check //tr[*/contains(string(),'%subject%')]
The primary advantage here is that the XPath is not broken up, making it easier to read.
With More
There are many other advantages to using .test over Java, but finding simple comparisons can sometimes be hard. Ultimately even our Java parts have evolved to look similar to the .test code; the new language showed us how to simplify and create a new API for Java by mimicing the structure of .test.
Through this however the Java code doesn't look like traditional Java anymore, and the resulting syntax bulk becomes even more of a hindrance. Consider this example (which mimics real tests we have).
_call( "unit.web.UpdateForm", _with(
"name", "form_one",
"params", _with(
"name", "John",
"address", "Nowhere 123"
)
);The indentation style here is essential to even having a clue what this does: it shows the name value pair relationships of the items, and the sub-structure involved. The language of .test was designed aroud this syntax, thus it is better at it.
UpdateForm with
%name% form_one
%params% with
%name% John
%address% Nowhere 123
end
endPlus in those cases where only one or two parameters are needed for the form, there is also a convenient syntax like below.
UpdateForm with %name% form_one %params:name% John %params:address% Nowhere 123 end
Combing all small syntax improvements together ultimately means that the .test code is quicker to write, and easier to understand, than the Java equivalent. Of course, this only applies in the domain of test scripts.
TestPlan The evolution of .test as a language
