<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>

<channel>
	<title>Lawrence Song</title>
	<atom:link href="http://lawrencesong.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://lawrencesong.net</link>
	<description>ruby, Java, c#, javascript</description>
	<pubDate>Fri, 09 May 2008 12:17:15 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>Must have firefox add-ons for web development</title>
		<link>http://lawrencesong.net/2008/05/09/must-have-firefox-add-ons-for-web-development/</link>
		<comments>http://lawrencesong.net/2008/05/09/must-have-firefox-add-ons-for-web-development/#comments</comments>
		<pubDate>Fri, 09 May 2008 12:13:48 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Deployment]]></category>

		<guid isPermaLink="false">http://lawrencesong.net/?p=10</guid>
		<description><![CDATA[Firebug - Firebug integrates with Firefox to put a wealth of web development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.
Web Developer - The Web Developer extension adds a menu and a toolbar to the browser with various web developer tools.
FireShot [...]]]></description>
			<content:encoded><![CDATA[<p><a title="web development evolved" href="http://www.getfirebug.com/" target="_blank">Firebug</a> - Firebug integrates with Firefox to put a wealth of web development tools at your fingertips while you browse. You can edit, debug, and monitor CSS, HTML, and JavaScript live in any web page.</p>
<p><a title="Web Developer" href="http://chrispederick.com/work/web-developer/" target="_blank">Web Developer</a> - The Web Developer extension adds a menu and a toolbar to the browser with various web developer tools.</p>
<p><a title="FireShot" href="http://screenshot-program.com/fireshot/" target="_self">FireShot </a>- FireShot is a Firefox extension that creates screenshots of web pages.</p>
<p><a title="ColorZilla" href="http://www.iosart.com/firefox/colorzilla/" target="_blank">ColorZilla </a>- Advanced Eyedropper, ColorPicker, Page Zoomer and other colorful goodies&#8230;</p>
<p><a title="Why slow?" href="http://developer.yahoo.com/yslow/" target="_blank">YSlow</a> - YSlow analyzes web pages and tells you why they&#8217;re slow based on the rules for high performance web sites. YSlow is a Firefox add-on integrated with the popular Firebug web development tool.</p>
]]></content:encoded>
			<wfw:commentRss>http://lawrencesong.net/2008/05/09/must-have-firefox-add-ons-for-web-development/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Selenium DSL II</title>
		<link>http://lawrencesong.net/2008/03/11/selenium-dsl-ii/</link>
		<comments>http://lawrencesong.net/2008/03/11/selenium-dsl-ii/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 11:47:10 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Selenium]]></category>

		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://lawrencesong.net/?p=8</guid>
		<description><![CDATA[In this post, I will talk about creating nicer syntax for verifications.
In Ruby, we can add new methods into existing class. Rspec adds some nice assert methods such as should_equal(expected_string) into string class.  However, it is impossible to do it in Java. Right, we can&#8217;t do it in unit test. Fortunately, we are writing [...]]]></description>
			<content:encoded><![CDATA[<p>In this post, I will talk about creating nicer syntax for verifications.</p>
<p>In Ruby, we can add new methods into existing class. Rspec adds some nice assert methods such as should_equal(expected_string) into string class.  However, it is impossible to do it in Java. Right, we can&#8217;t do it in unit test. Fortunately, we are writing automated tests. we can control what to return. Hence, I write a wrap class to allow code to use rspec-like syntax.</p>
<pre class="syntax-highlight:java">

public class TextDSL extends Assert {
private String text;
private String errorMessage;

public TextDSL(String text) {
this(text, &quot;&quot;);
}

public TextDSL(String text, String errorMessage) {
this.text = text;
this.errorMessage = errorMessage;
}

public void shouldEqual(String expectedText) {
assertEquals(errorMessage, expectedText, text);
}

public void shouldNotEqual(String notExpectedText) {
assertFalse(errorMessage + &quot; not expected:&lt;&quot; + notExpectedText + &quot;&gt; but was:&lt;&quot; + text + &quot;&gt;&quot;, notExpectedText.equals(text));
}

public void shouldEqual(int expectedInteger) {
assertEquals(errorMessage, String.valueOf(expectedInteger), text);
}

public void shouldNotEqual(int notExpectedInteger) {
assertFalse(errorMessage + &quot; not expected:&lt;&quot; + notExpectedInteger + &quot;&gt; but was:&lt;&quot; + text + &quot;&gt;&quot;, String.valueOf(
notExpectedInteger).equals(text));
}

public void shouldInclude(String expectedIncludedText) {
assertTrue(errorMessage + &quot; expected included:&lt;&quot; + expectedIncludedText + &quot;&gt; but was not included in:&lt;&quot; + text + &quot;&gt;&quot;,
text.contains(expectedIncludedText));
}

public void shouldNotInclude(String expectedNotIncludedText) {
assertFalse(errorMessage + &quot; not expected included:&lt;&quot; + expectedNotIncludedText + &quot;&gt; but was included in:&lt;&quot; + text + &quot;&gt;&quot;,
text.contains(expectedNotIncludedText));
}
}
</pre>
<p>then we can get nicer syntax to express our intent for verification.</p>
<p>dropDownList.shouldDisplayLabel -&gt; dropDownList.lable().shouldEqual(expectedLabel)</p>
<p>dropDownList.shouldDisplayIndex -&gt; dropDownList.index().shouldEqual(expectedIndex)</p>
<p>and I can do something like verify css style includes a particular style:</p>
<p>dropDownList.css().shouldInclude(&#8221;errorField&#8221;)</p>
<p>We can add more methods to TextDSL class. or we can create other DSL class we want to verify the object we want.</p>
<p>Later on, I will post the source code so that you can see the whole implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://lawrencesong.net/2008/03/11/selenium-dsl-ii/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Selenium DSL I</title>
		<link>http://lawrencesong.net/2008/02/27/selenium-dsl-i/</link>
		<comments>http://lawrencesong.net/2008/02/27/selenium-dsl-i/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 11:16:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[Selenium]]></category>

		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://lawrencesong.net/?p=4</guid>
		<description><![CDATA[I was working in a project which used Selenium RC as web test tool. The functional test coverage is high. However, as the application has become more complicated and more tests have been added, the automated testing becomes a bottleneck for velocity. The problems?

Hard to understand the intent of automated tests
Duplication of Selenium test code
Hard [...]]]></description>
			<content:encoded><![CDATA[<p>I was working in a project which used Selenium RC as web test tool. The functional test coverage is high. However, as the application has become more complicated and more tests have been added, the automated testing becomes a bottleneck for velocity. The problems?</p>
<ul>
<li>Hard to understand the intent of automated tests</li>
<li>Duplication of Selenium test code</li>
<li>Hard to reuse</li>
<li><a href="http://code.google.com/p/webdriver/wiki/PageObjects" title="Page objects">Page objects</a> has all responsibilities of page operations and verifications</li>
<li>Test the wrong thing</li>
<li> Because of complexity, fewer scenarios are created</li>
<li> Overtesting cause performance problem</li>
<li> New team members find it hard to write tests</li>
<li> QAs take a long time to write automated tests</li>
</ul>
<p>Let&#8217;s see how to solve all the problems listed above.</p>
<p>In the project, developers and QAs are both writing selenium tests. Without navigator into the code, it&#8217;s very hard to understand what does the particular test do.One way to solve the problem is to name the test better. for example testShouldAllTestFieldSetMaxLengthAsWhatTheyExpected(). However, selenium tests is not unit test, sometime it&#8217;s not easy to give a name to define all the operations and verification of the tests.</p>
<p>Recently, DSL became a hot topic. Define DSL in automated tests would help develops and QAs (even BAs) understanding the intent of all tests.  Hence, I decide to define DSL for elements in the page object.</p>
<p>The advantage to use DSL as following:</p>
<ul>
<li>Easier to read</li>
<li>Precise error message, i.e.:
<ul>
<li> assertTrue(selenium.isElementPresent(&#8221;id&#8221;) will give you message&#8221;expect true, but false&#8221;,  what the heck does that mean when you see the error message?</li>
<li>element.shouldExist() will give you message &#8220;expect element ### exist, but not exist&#8221;, you can customized the error message you want.</li>
</ul>
</li>
<li> Reuse DSL</li>
<li>No more asserts in the test class</li>
<li>Quicker development</li>
<li>Precise testing</li>
</ul>
<p>Here I show some simple DSL. (two types: operations and verifications)</p>
<p>TextBox:</p>
<ul>
<li>type(String text)</li>
<li>shouldDisplayRedBorder(), shouldNotDisplayRedBoder()</li>
<li>shouldDisplayValue(String expectValue)</li>
<li>shouldBeReadOnly(), shouldNotBeReadOnly()</li>
<li>shouldBeDisabled(), shouldNotBeDisabled()</li>
<li>shouldExist(), shouldNotExist()</li>
<li>&#8230;&#8230;</li>
</ul>
<p>Radio:</p>
<ul>
<li>click()</li>
<li>shouldBeSelected(), shouldNotBeSelected()</li>
<li>&#8230;&#8230;</li>
</ul>
<p>DropDownList:</p>
<ul>
<li>selectLabel(String label)</li>
<li>sleectIndex(String index)</li>
<li>shouldDisplayLabel(String expectedLabel)</li>
<li>shouldDisplayIndex(int index)</li>
</ul>
<p>Checkbox, Label, ErrorIcon, Table&#8230;</p>
<p>Depends on the project, you can create more customized element suitable for your need.</p>
<p>In  page objects, we just need to return element object. for example:</p>
<pre class="syntax-highlight:java">

class AmazonPage

public searchInDropDownList() { return newDropDownList(&quot;url&quot;); }

public fieldKeywordTextbox() { return newTextbox(&quot;field-keyword&quot;); }

public searchButton() { return newButton(&quot;go&quot;); }

}
</pre>
<p>then the test become look like</p>
<pre class="syntax-highlight:java">

amazonPage.searchInDropDownList().selectLabel(&quot;Books&quot;);

amazonPage.fieldKeywordTextbox().type(&quot;Selenium&quot;);

amazonPage.searchButton().click()
</pre>
<p>self-documentation is better than having a lot of comment in the test.</p>
<p>In selenium DSL II, I will talk about how to define better DSL syntax.</p>
]]></content:encoded>
			<wfw:commentRss>http://lawrencesong.net/2008/02/27/selenium-dsl-i/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Selenium Element Locators</title>
		<link>http://lawrencesong.net/2008/01/07/selenium-element-locators/</link>
		<comments>http://lawrencesong.net/2008/01/07/selenium-element-locators/#comments</comments>
		<pubDate>Mon, 07 Jan 2008 09:37:24 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Selenium]]></category>

		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://lawrencesong.net/?p=7</guid>
		<description><![CDATA[When element doesn&#8217;t contain any id and name, using xpath to find the element is very important for writing selenium test. I list some sample locate for the element which doesn&#8217;t contain id or name.
1. get the link with the link text&#60;a href=&#8221;link url&#8221;&#62;Link Text&#60;/a&#62;  -&#62;  link=Link Text
2. get element with the element [...]]]></description>
			<content:encoded><![CDATA[<p>When element doesn&#8217;t contain any id and name, using xpath to find the element is very important for writing selenium test. I list some sample locate for the element which doesn&#8217;t contain id or name.</p>
<p>1. get the link with the link text&lt;a href=&#8221;link url&#8221;&gt;Link Text&lt;/a&gt;  -&gt;  link=Link Text</p>
<p>2. get element with the element text</p>
<p>&lt;a href=&#8221;link url&#8221;&gt;Link Text&lt;/a&gt;  -&gt;   //a[text()='Link Text']</p>
<p>3.   get element with part of the element text</p>
<p>&lt;a href=&#8221;link url&#8221;&gt;Link Text&lt;/a&gt;   -&gt;  //a[contains(text(), 'ink Tex')]</p>
<p>4.   get element with an attribute</p>
<p>&lt;a href=&#8221;link url&#8221;&gt;Link Text&lt;/a&gt;  -&gt; //a[@href='link url']</p>
<p>5.  get element with  two attributes</p>
<p>&lt;input type=&#8221;text&#8221; value=&#8221;value&#8221;/&gt;  -&gt;  //input[@type='text' and @value='value']</p>
<p><a href="https://addons.mozilla.org/en-US/firefox/addon/1192" title="XPather">XPather</a> is a firefox plugin help you to find the xpath.</p>
<p>There is more element locators document to be found on <a href="http://release.openqa.org/selenium-remote-control/0.9.2/doc/dotnet/Selenium.html">Selenium Doc</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lawrencesong.net/2008/01/07/selenium-element-locators/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Implement Java Interface in Ruby</title>
		<link>http://lawrencesong.net/2008/01/03/implement-java-interface-in-ruby/</link>
		<comments>http://lawrencesong.net/2008/01/03/implement-java-interface-in-ruby/#comments</comments>
		<pubDate>Thu, 03 Jan 2008 05:58:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[JRuby]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://lawrencesong.net/?p=5</guid>
		<description><![CDATA[Sometime I want to use a ruby library and implement something in ruby code so I could use the cool ruby features. JRuby provide the capability to run ruby code in Java. Therefore I could implement Java interface in Ruby.
1. Create the Java Interface

public interface Animal
{
public String speak();

public String move();
}

2. Implement the interface in Ruby


class [...]]]></description>
			<content:encoded><![CDATA[<p>Sometime I want to use a ruby library and implement something in ruby code so I could use the cool ruby features. JRuby provide the capability to run ruby code in Java. Therefore I could implement Java interface in Ruby.</p>
<p>1. Create the Java Interface</p>
<pre class="syntax-highlight:java">
public interface Animal
{
public String speak();

public String move();
}
</pre>
<p>2. Implement the interface in Ruby</p>
<pre class="syntax-highlight:ruby">

class Animal
def move
&quot;Move...&quot;
end

def speak
&quot;Speak...&quot;
end
end
</pre>
<p>3. Create a factory to create the concrete class of the interface</p>
<pre class="syntax-highlight:java">

import org.jruby.Ruby;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.javasupport.JavaEmbedUtils;

import java.lang.reflect.Method;
import java.io.InputStream;
import java.io.File;

public class RubyFactory
{
public static final String RUBY_src=&quot;ruby&quot;;

public static &lt;T&gt; T getBean(Class&lt;T&gt; type)
{
Ruby runtime = Ruby.getDefaultInstance();

try
{
runtime.evalScript(runtime.evalScript(&quot;File.open('&quot; + RUBY_SRC + File.separator + type.getSimpleName().toLowerCase() + &quot;.rb').read&quot;).toString());
runtime.evalScript(extendRubyScript(type));
}
catch (Exception e)
{
System.err.println(e.toString());
}

Object c = runtime.evalScript(type.getSimpleName() + &quot;.new&quot;);
c = JavaEmbedUtils.rubyToJava(runtime, (IRubyObject) c, type);
return (T) c;
}

private static String extendRubyScript(Class type)
{
String rubyScript = &quot;require 'java'\n&quot; +
&quot;class &quot; + type.getSimpleName() + &quot;\n&quot; +
&quot;  include Java::&quot; + type.getName().replace(&quot;.&quot;, &quot;::&quot;) + &quot;\n&quot;;

Method[] methods = type.getMethods();

for (Method method : methods)

{
String name = method.getName();
rubyScript += &quot;  eval(\&quot;alias &quot; + name + &quot; #{&#8217;&quot; + name +        &quot;&#8217;.gsub(/([A-Z]+)([A-Z][a-z])/,&#8217;\\1_\\2&#8242;).gsub(/([a-z\\d])([A-Z])/,&#8217;\\1_\\2&#8242;).tr(&#8217;-', &#8216;_&#8217;).downcase}\&quot;)\n&quot;;
}

rubyScript += &quot;end&quot;;
return rubyScript;
}    public static void main(String[] args)
{

Animal animal = RubyFactory.getBean(Animal.class);
System.out.println(animal.move());

System.out.println(animal.speak());
}
}
</pre>
<p>All the ruby files should be put into the ruby directory. I follow the naming convertion as following:</p>
<p>interface Greeting -&gt; greeting.rb with class Greeting</p>
<p>method sayGoodbye in java -&gt; method say_goodbye in ruby</p>
<p>4. use the factory above, we could easily to implement another java interface.</p>
<pre class="syntax-highlight:java">

public interface Greeting
{
public String sayGoodbye();

public String sayHello();
}</pre>
<p>5. The implementation of interface greeting.</p>
<pre class="syntax-highlight:ruby">

class Greeting
def say_hello()
&quot;Hello&quot;
end

def say_goodbye()
&quot;Goodbye&quot;
end
end</pre>
<p>6. Test Greeting.</p>
<pre class="syntax-highlight:java">

public class GreetingTest extends TestCase
{
private Greeting greeting;

@Before
protected void setUp() throws Exception
{
greeting = RubyFactory.getBean(Greeting.class);
}

@Test
public void testSayHello()
{
assertEquals(&quot;Hello&quot;, greeting.sayHello());
}

@Test
public void testSayGoodbye()
{
assertEquals(&quot;Goodbye&quot;, greeting.sayGoodbye());
}
}
</pre>
<p>In order to run the application, you need to include asm-2.2.3.jar, asm-commons-2.2.3.jar, backport-util-concurrent.jar and jruby-complete-1.0.1.jar</p>
<p><a href="http://lawrencesong.net/wp-content/uploads/2008/01/java-ruby.zip" title="download source code">download source code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lawrencesong.net/2008/01/03/implement-java-interface-in-ruby/feed/</wfw:commentRss>
		</item>
		<item>
		<title>My Tech Blog</title>
		<link>http://lawrencesong.net/2007/09/10/hello-world/</link>
		<comments>http://lawrencesong.net/2007/09/10/hello-world/#comments</comments>
		<pubDate>Mon, 10 Sep 2007 13:18:15 +0000</pubDate>
		<dc:creator>admin</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Thanks  Daniel Arago and James Crisp to encourage me to write technical blogs.
]]></description>
			<content:encoded><![CDATA[<p>Thanks  <a href="http://antagonisticpleiotropy.blogspot.com/" title="Daniel Aragao">Daniel Arago</a> and <a href="http://www.jamescrisp.org/" title="James Crisp" target="_blank">James Crisp</a> to encourage me to write technical blogs.</p>
]]></content:encoded>
			<wfw:commentRss>http://lawrencesong.net/2007/09/10/hello-world/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
