<?xml version="1.0" encoding="utf-8"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xml:lang="en">
<title>Automated Testing Guy</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/" />
<modified>2006-05-11T12:15:59Z</modified>
<tagline>Strategies for effectively leveraging test automation to increase software quality.</tagline>
<id>tag:www.autotestguy.com,2006://1</id>
<generator url="http://www.movabletype.org/" version="3.15">Movable Type</generator>
<copyright>Copyright (c) 2006, Misha Rybalov</copyright>
<entry>
<title>Ajax Support is Coming!</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2006/05/ajax_support_is.html" />
<modified>2006-05-11T12:15:59Z</modified>
<issued>2006-05-11T12:01:53Z</issued>
<id>tag:www.autotestguy.com,2006://1.50</id>
<created>2006-05-11T12:01:53Z</created>
<summary type="text/plain">ABCWebTest will soon support automated testing of Ajax applications!...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>ABCWebTest</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>ABCWebTest will soon support automated testing of Ajax applications!</p>]]>
<![CDATA[<p>With the next release of ABCWebTest it will be possible to automate the testing of Ajax applications such as <a href="http://maps.google.com/">Google Maps</a>. You'll be able to move the mouse over any element on a web page (e.g. a zoom slider image) drag the mouse in either a vertical or horizontal direction (e.g. dragging a map or dragging a zoom slider up or down to zoom in on the map). ABCWebTest will automatically wait until the Ajax application has updated all the data before returning from a method call. </p>

<p>This means you, as the test writer, don't have to worry about putting in timers/waits/sleeps until the Ajax operation is finished. You'll just use this simple API (example code is testing the Google Maps site):</p>

<p><strong>C#</strong><br />
<code><br />
Image sliderImage = browser.Document.GetImageBySrc("slider.png");<br />
browser.Mouse.MoveOverElement(sliderImage);<br />
browser.Mouse.DragVertically(20); //zoom in on map - move slider up by 20 pixels<br />
</code></p>

<p><br />
<strong>Java</strong><br />
<code><br />
Image sliderImage = browser.getDocument().getImageBySrc("slider.png");<br />
browser.getMouse().moveOverElement(sliderImage);<br />
browser.getMouse().dragVertically(20); //zoom in on map - move slider up by 20 pixels<br />
</code></p>

<p><br />
Stay tuned for more details...</p>]]>
</content>
</entry>
<entry>
<title>The Need for Speed - ABCWebTest is now FAST!</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2006/05/the_need_for_sp.html" />
<modified>2006-05-09T20:17:43Z</modified>
<issued>2006-05-09T20:03:50Z</issued>
<id>tag:www.autotestguy.com,2006://1.48</id>
<created>2006-05-09T20:03:50Z</created>
<summary type="text/plain">One of the most frequent feedback comments we&apos;ve received about ABCWebTest is the request to speed up it&apos;s execution. We&apos;ve listened and it&apos;s now super-fast!...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>ABCWebTest</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>One of the most frequent feedback comments we've received about ABCWebTest is the request to speed up it's execution. We've listened and it's now super-fast!</p>]]>
<![CDATA[<p>The main issue before was that in order to ensure that the web page was loaded properly, we had to put in many checks. What we've done since version 0.5 is created a Speed class that allows you to control the speed at which your tests are executing. Think of it like a manual transmission car, except here we only have 2 speeds: low and high. By default, the speed of ABCWebTest is as fast as possible, which should suffice for most situations. However, there will be times when you'll need to slow it down. This is usually the case right before an action opens a popup. In that case, you'd simply slow down ABCWebTest before the action that causes the popup to occur and then speed it back up right after. Here's some sample code in C#:</p>

<p><code><br />
browser.Speed.SlowDown();<br />
browser.Document.GetAnyButtonByName("click_me_to_open_popup").Click();<br />
browser.Speed.SpeedUp();<br />
</code></p>

<p>Here's the same code in Java:</p>

<p><code><br />
browser.getSpeed().slowDown();<br />
browser.getDocument().getAnyButtonByName("click_me_to_open_popup").click();<br />
browser.getSpeed().speedUp();<br />
</code></p>

<p><br />
You can change the low and high speed values as you require, but by default the high speed is "0" and the low speed is "1000". This is the approximate number of milliseconds of delay. The higher the value, the larger the delay and the slower your web tests will take to run. Here's how you would change the default speed values:</p>

<p>C#:</p>

<p><code><br />
browser.Speed.High = 100;  //slow down high speed to 100ms instead of  the default 0ms<br />
browser.Speed.Low  = 800;  //speed up low speed to 800ms instead of the default 1000ms<br />
</code></p>

<p>Java:</p>

<p><code><br />
browser.getSpeed().setHigh(100);  //slow down high speed to 100ms instead of  the default 0ms<br />
browser.getSpeed().setLow(800);  //speed up low speed to 800ms instead of the default 1000ms<br />
</code></p>

<p>The speed increase is available in ABCWebTest as of version 0.5.</p>]]>
</content>
</entry>
<entry>
<title>NUnit &quot;Quick and Dirty&quot; Tutorial</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2006/05/nunit_quick_and.html" />
<modified>2006-05-05T23:11:04Z</modified>
<issued>2006-05-05T23:00:43Z</issued>
<id>tag:www.autotestguy.com,2006://1.35</id>
<created>2006-05-05T23:00:43Z</created>
<summary type="text/plain">In the style of the JUnit Quick and Dirty Tutorial, here&apos;s a similar tutorial for NUnit. I&apos;m assuming that you&apos;re familiar with C#/.NET, downloaded NUnit and have a development environment all setup for compiling and running C# code....</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>In the style of the <a href="http://www.autotestguy.com/archives/2005/03/quick_and_dirty_1.html">JUnit Quick and Dirty Tutorial</a>, here's a similar tutorial for NUnit. I'm assuming that you're familiar with C#/.NET, downloaded <a href="http://www.nunit.org">NUnit</a> and have a development environment all setup for compiling and running C# code.</p>]]>
<![CDATA[<p><strong>Preparing an NUnit test class</strong></p>

<p>1. create a blank C# file (e.g. FooTests.cs)</p>

<p>2. import the following namespace:<br />
using NUnit.Framework;</p>

<p>3. create a stand alone class that uses the "TestFixture" attribute (e.g. [TestFixture] public class FooTest { })</p>

<p>This is all that's required to setup your class for NUnit tests - fewer steps than for JUnit, in fact. Now you're ready to actually write some tests.</p>

<p><br />
<strong>Writing an NUnit test</strong></p>

<p>1. For every test you'd like to run, create a public method that returns void, takes no arguments and uses the "Test" attribute e.g. [Test] public void MyTest() { ... }<br />
Unlike JUnit, there is no need to have the method start with "test" because the "Test" attribute tags the test so that NUnit knows that's your test case.</p>

<p>2. Instantiate the object you'd like to test inside the test method from the previous step.</p>

<p>Foo foo = new Foo();</p>

<p>3. Invoke the method(s) you'd like to test and assign the return values to local variables.</p>

<p>e.g. int actualValue = foo.bar(1, 2, 3);</p>

<p>4. Check the method's return value by using one of NUnit's assert methods. You can get a list of all the assert methods from the <a href="http://www.nunit.org/index.php?p=documentation">NUnit Documentation</a>.</p>

<p>e.g. Assert.AreEqual(4, actualValue);</p>

<p><br />
<strong>Initializing and De-initializing Tests</strong></p>

<p>Often, you'll need to initialize or de-initialize a group of tests in the same way. For example if all your tests had to start with the same object creation, you can place that common initialization code into a special NUnit method with the "SetUp" attribute. Similarly, if all your tests had to do the same de-initializing steps, that code can be placed into a method tagged with the "TearDown" attribute.</p>

<p>Your test methods would then not have to perform those common steps anymore and could start with the "meat" of their testing.</p>

<p>The set up and tear down methods can have any name (unlike JUnit which requires they be called setUp() and tearDown(), respectively. Also, these methods don't need to be protected like in JUnit but can be public. If you don't have any use for them, don't include them and by default there will be no set up and tear down.</p>

<p>e.g.<br />
//foo variable should be declared as an instance of the test class<br />
[SetUp] public void SetUp() { foo = new Foo(); }<br />
[TearDown] public void TearDown() { foo.cleanUp(); }</p>

<p>NUnit also has a nice once-only initialization/de-initialization feature where you can do an initialization once before any tests are run (instead of once before every test is run) and once after all tests are run (instead of once after every test is run). Use the "TestFixtureSetUp" and "TestFixtureTearDown" attributes, respectively, like so:</p>

<p>[TestFixtureSetUp] public void TestFixtureSetUp() {<br />
//...<br />
}</p>

<p>[TestFixtureTearDown] public void TestFixtureTearDown() {<br />
//...<br />
}</p>

<p><strong>Grouping Your Tests Into a Suite</strong><br />
You can have a master suite test file that is a collection of all your unit test classes. This is another stand alone C# class that's tagged with the "Suite" attribute. Here's a sample of how it would look like:</p>

<p><code><br />
using NUnit.Framework;<br />
using NUnit.Core;</p>

<p>namespace ABCWebTest.Tests {<br />
&#160;&#160;&#160;public class AllTests {<br />
&#160;&#160;&#160;&nbsp;&nbsp;&nbsp;[Suite] public static TestSuite Suite {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;get {<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;TestSuite suite = new TestSuite("All Tests");<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new AjaxTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new BrowserTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new BrowserUtilityTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new KeyboardTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new MouseTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new PopupTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new SpeedTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new TextTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;suite.Add(new TimerTests());<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;return suite;<br />
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;}<br />
&#160;&#160;&#160;&#160;&#160;&#160;}<br />
&#160;&#160;&#160;}<br />
}<br />
</code></p>

<p><br />
<strong>Rules of Thumb</strong></p>

<p>These are general guidelines to keep in mind as you're creating more tests with NUnit.</p>

<p>1. Create a single test class for each application class you have.</p>

<p>2. Name each test class the same name as the application class its testing but with "Tests" appended to the end. So if you have an application class called "ShoppingCart.cs" the test class would be called "ShoppingCartTests.cs"</p>

<p>3. Give meaningful names to each test method. I usually name the test method the same name as the method that its testing with some additional info appended to the name. For instance if I'm testing a method called "add" in my ShoppingCart class, I'll create a few test methods to test different ways of adding to a shopping cart:</p>

<ul>
<li>[Test] public void Add_SingleProduct() { ... }
<li>[Test] public void Add_MultipleProducts() { ... }
<li>[Test] public void Add_InvalidProduct() { ... }
<li>[Test] public void Add_Null() { ... }
</ul>

<p>4. The scope of how much checking to do in a single test case (test method) is a judgement call. I usually stick to a single method call with a single set of arguments, but you can stuff a single test case with multiple method calls and assertion checks. In the example above, that would mean creating a single Add() method and testing adding a single product, multiple products, invalid product and null all in one test method.</p>

<p>5. You can use the NUnit console or NUnit GUI to run your tests. The console I find is quicker. I usually use <a href="http://nant.sourceforge.net/">NAnt</a> to run my NUnit tests from the console but I also find it convenient to use the NUnit GUI when I want to run a subset of my tests. Keep in mind, though, that the NUnit GUI uses the GUI thread as the main thread so tests aren't run in the main thread. This may cause issues if your code expects to be running in the main thread - I <a href="http://www.autotestguy.com/archives/2006/05/dealing_with_fr.html">learned this lesson</a> the hard way.</p>]]>
</content>
</entry>
<entry>
<title>Dealing with Frustrating Development Issues - Part 2 (The End)</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2006/05/dealing_with_fr.html" />
<modified>2006-05-03T17:15:46Z</modified>
<issued>2006-05-03T16:50:28Z</issued>
<id>tag:www.autotestguy.com,2006://1.47</id>
<created>2006-05-03T16:50:28Z</created>
<summary type="text/plain">As I previously wrote I was having some issues with trying to get a parent window from MSHTML.IHTMLDocument2. Turns out that the issue is the NUnit GUI!...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>ABCWebTest</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>As I <a href="http://www.autotestguy.com/archives/2006/04/so_i_was_ready.html">previously wrote</a> I was having some issues with trying to get a parent window from MSHTML.IHTMLDocument2. Turns out that the issue is the NUnit GUI!</p>]]>
<![CDATA[<p>Who would have thought that a unit testing tool affects how you have to write your core application code, but that seems to be the case. No wonder running these tests worked previously - I was using the NUnit console application. When you use the NUnit GUI, you have to take into account that it uses MTA (multi-threaded apartment threading model) by default. The way I got my code to work was to set the default threading model to STA (single-threaded apartment) like so:</p>

<p><strong>System.Threading.Thread.CurrentThread.ApartmentState = System.Threading.ApartmentState.STA;</strong></p>

<p>The reason this is necessary is because the call to IHTMLDocument2.parentElement has to be done from the main thread. Otherwise you get a nasty System.InvalidCastException. If you're running the NUnit console, it's not a problem because the main thread is the test thread. But if you're running the NUnit GUI, the main thread is the GUI thread so I kept running up against that nasty exception. Setting your code to run in STA mode fixes this problem.</p>

<p>After hours of searching, banging my head against the wall, trying dozens of solutions, it all comes down to a single line of code. I set this in the Browser static constructor so it's automatically executed whenever you use ABCWebTest. I didn't want to force all ABCWebTest.NET users to have to put this line into their NUnit tests.</p>]]>
</content>
</entry>
<entry>
<title>Dealing with Frustrating Development Issues</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2006/04/so_i_was_ready.html" />
<modified>2006-04-26T16:45:55Z</modified>
<issued>2006-04-26T16:34:56Z</issued>
<id>tag:www.autotestguy.com,2006://1.46</id>
<created>2006-04-26T16:34:56Z</created>
<summary type="text/plain">So I was ready to continue ABCWebTest development today and implement some mouse automation into the product (very useful for testing Ajax web applications) but I kept running into the same error/exception when I ran my unit tests. The details...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>ABCWebTest</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>So I was ready to continue ABCWebTest development today and implement some mouse automation into the product (very useful for testing Ajax web applications) but I kept running into the same error/exception when I ran my unit tests.</p>

<p>The details aren't important but if you must know (and there is a selfish side to this post to solicit help) I get a System.InvalidCastException when I try and obtain the "parentWindow" property from an MSHTML.IHTMLDocument2 object. Try as I might to work my way around it, I can't find a way to avoid this exception today.</p>

<p>The really frustrating thing is that this was working before! In previous days, there was no exception. I tried a few techniques to get past this blocker - I took a brief nap to come back with fresh eyes (no luck), I tried researching for a solution to this problem on the web (no luck), I tried reading other people's unrelated blogs to take a break from banging my head against the wall (no luck). So in the end, I decided it's better to stop banging my head against the wall, take my losses for the day and move on to other business activities.</p>]]>

</content>
</entry>
<entry>
<title>IT Recruitment Agencies Should Think Outside the Box</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2006/04/it_recruitment_1.html" />
<modified>2006-04-21T23:31:05Z</modified>
<issued>2006-04-21T23:01:08Z</issued>
<id>tag:www.autotestguy.com,2006://1.44</id>
<created>2006-04-21T23:01:08Z</created>
<summary type="text/plain">I find it interesting how IT recruiting companies (and many HR departments for that matter) tend to see things in boxes. For example, if a company is looking for a QA Analyst to do automated testing, then they don&apos;t know...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Sales</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>I find it interesting how IT recruiting companies (and many HR departments for that matter) tend to see things in boxes. For example, if a company is looking for a QA Analyst to do automated testing, then they don't know what to do with someone who offers to do full automated testing solutions instead of a junior person who happens to know how to use a test tool.</p>

<p>I'm currently exploring the option of using IT recruitment agencies to generate leads. The jury is still out but one thing is for sure - I'm not the run-of-the-mill person they're accustomed to dealing with. For one, I have an automated tested company. For another, I offer an automated web testing tool, (<a href="http://www.abcwebtest.com">ABCWebTest</a>), that is different from the standard commercial test tools out there. And finally, I have many years of experience implementing low-maintenance automated testing solutions, and not just using record-playback tools (which break down for complex testing scenarios).</p>

<p>While this all presents a nice offering, I find that IT recruiters don't quite know what to do with me. I don't blame them. After all, the companies that hired them are asking for a normal tester to do automated testing. They might not be aware that automated testing takes a lot of planning, technical knowledge and experience to implement properly.</p>

<p>So if you're an IT recruitment company reading this (or a company that's hired a recruitment company for an automated testing consultant), keep in mind - automated testing is a development activity requiring as much forethought, planning, and technical knowledge as regular development. Don't fall for the hype of commercial test tool vendors.</p>]]>

</content>
</entry>
<entry>
<title>Abstractions in Test Code</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/06/abstractions_in.html" />
<modified>2005-12-07T17:11:19Z</modified>
<issued>2005-06-03T22:48:49Z</issued>
<id>tag:www.autotestguy.com,2005://1.37</id>
<created>2005-06-03T22:48:49Z</created>
<summary type="text/plain">In object-oriented programming (OOP) people are familiar with abstracting things and layering so that the system stays resilient to changes. The classic example is the MVC (Model-View-Controller) architecture that allows the user interface (View) to change without having to change...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Design Patterns</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>In object-oriented programming (OOP) people are familiar with abstracting things and layering so that the system stays resilient to changes. The classic example is the MVC (Model-View-Controller) architecture that allows <br />
the user interface (View) to change without having to change the underlying business logic (Model). Concepts like this are drastically missing from  test code. I propose the following types of abstractions applied to test code and in particular, acceptance test code (aka GUI tests, functional tests):</p>

<p><br />
1. Abstract the navigation logic of your application.</p>

<p>There's no need for test cases to know the details of how to navigate around the application. All this does is tightly couple the navigation logic to each test so if the navigation logic changes there could be hundreds of tests to update to use the new navigation. The <a href="/archives/2004/12/basic_patterns_1.html">Transporter</a> pattern deals with this issue.</p>

<p><br />
2. Abstract the test steps</p>

<p>Tests shouldn't have to specify all the test steps explicitly. That makes them tightly coupled to that sequence of test steps, so if a step has to be added or removed that would involve a significant maintenance cost. One solution is to abstract the test steps out to a <a href="/archives/2004/12/patterns_catalo.html">Template</a> class and make each test implement just a few template methods.</p>

<p><br />
3. Abstract the test data</p>

<p>This is a huge topic that I'm not going to cover thoroughly here. Test data and the management of test data is an acquired skill. Too often, test tools focus on driving the GUI and test data management is an afterthought. And don't tell me that the tool can import your test data from an Excel or CSV file. It's not that simple. What about the scenarios where your tests need the application to be in a certain state before they're run? That would involve direct database access that most test tools lack.</p>

<p>There is also the issue of test data generation. Most tools make you manually specify the test data to use. This is not very automated and leads to a tight coupling between database schema and tests. Instead, there should be a test data layer that will supply tests with data they need. That way tests don't have to hard code data.</p>

<p><br />
4. Abstract the visual details of a page</p>

<p>Tests shouldn't have to know the names of specific widgets on a page they are interacting with. Otherwise, they become tightly coupled to the visual representation of the application and sensitive to any changes in the application. The <a href="/archives/2004/12/basic_patterns_2.html">Domain Test Object</a> (DTO) pattern addresses this problem by modeling the page as an object.</p>]]>

</content>
</entry>
<entry>
<title>JUnit &quot;Quick and Dirty&quot; Tutorial</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/03/quick_and_dirty_1.html" />
<modified>2005-12-07T17:12:39Z</modified>
<issued>2005-03-05T17:15:40Z</issued>
<id>tag:www.autotestguy.com,2005://1.34</id>
<created>2005-03-05T17:15:40Z</created>
<summary type="text/plain">For those that want to get started with JUnit quickly and prefer a &quot;just the facts&quot; type of tutorial, I&apos;ve create the following JUnit Quick and Dirty Tutorial. This tutorial assumes you are already familiar with Java programming, so the...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>For those that want to get started with <a href="http://www.junit.org">JUnit</a> quickly and prefer a "just the facts" type of tutorial, I've create the following JUnit Quick and Dirty Tutorial. This tutorial assumes you are already familiar with Java programming, so the junit.jar should be in your classpath and you should have a development environment all setup for compiling and running Java code.</p>

<p><strong>Preparing a JUnit test class</strong></p>

<p>1. create a blank Java file (e.g. FooTest.java)</p>

<p>2. import the following classes:<br />
junit.framework.Test<br />
junit.framework.TestCase<br />
junit.framework.TestSuite</p>

<p>3. create a class that extends from TestCase (e.g. public class FooTest extends TestCase)</p>

<p>4. create a public constructor that takes a string argument called name </p>

<p>e.g. public FooTest(String name) { super(name); }</p>

<p>5. create a public static suite() method that tells JUnit which test cases to run. The easy way to do this is to pass the class instance of your class and let JUnit dynamically figure out which tests to run. It does this by reflecting on your test class (FooTest.class) and looking for all public methods that return void and start with "test".</p>

<p>e.g. public static Test suite() { return new TestSuite(FooTest.class); }</p>

<p>This is all that's required to setup your class for JUnit tests. Now you're ready to actually write some tests.</p>

<p><strong>Writing a JUnit test</strong></p>

<p>1. For every test you'd like to run, create a public method that returns void, takes no arguments and starts with "test"<br />
e.g. public void testBar() { ... }</p>

<p>2. Instantiate the object you'd like to test inside the test method from the previous step.</p>

<p>Foo foo = new Foo();</p>

<p>3. Invoke the method(s) you'd like to test and assign the return values to local variables.</p>

<p>e.g. int actualValue = foo.bar(1, 2, 3);</p>

<p>4. Check the method's return value by using one of JUnit's assert methods. You'll be using methods inside junit.framework.TestCase since you inherited from it. You can get a list of all the assert methods from the <a href="http://www.junit.org/junit/javadoc">JUnit JavaDocs</a>.</p>

<p>e.g. assertEquals(4, actualValue);</p>

<p><strong>Initializing and De-initializing Tests</strong></p>

<p>Often, you'll need to initialize or de-initialize a group of tests in the same way. For example if all your tests had to start with the same object creation, you can place that common initialization code into a special JUnit method called setUp(). Similarly, if all your tests had to do the same de-initializing steps, that code can be placed into a tearDown() method.</p>

<p>Your test methods would then not have to perform those common steps anymore and could start with the "meat" of their testing.</p>

<p>These methods are protected and take no arguments, so if you don't have any use for them, don't include them and by default they will do nothing.</p>

<p>e.g. <br />
//foo variable should be declared as an instance of the test class<br />
protected void setUp() { foo = new Foo(); }<br />
protected void tearDown() { foo.cleanUp(); }</p>

<p><strong>Rules of Thumb</strong></p>

<p>These are general guidelines to keep in mind as you're creating more tests with JUnit.</p>

<p>1. Create a single test class for each application class you have.</p>

<p>2. Name each test class the same name as the application class its testing but with "Test" appended to the end. So if you have an application class called "ShoppingCart.java" the test class would be called "ShoppingCartTest.java"</p>

<p>3. Give meaningful names to each test method. I usually name the test method the same name as the method that its testing with some additional info appended to the name. For instance if I'm testing a method called "add" in my ShoppingCart class, I'll create a few test methods to test different ways of adding to a shopping cart:</p>

<ul>
<li>public void testAdd_SingleProduct() { ... }</li>
<li>public void testAdd_MultipleProducts() { ... }</li>
<li>public void testAdd_InvalidProduct() { ... }</li>
<li>public void testAdd_Null() { ... }</li>
</ul>

<p>4. The scope of how much checking to do in a single test case (test method) is a judgement call. I usually stick to a single method call with a single set of arguments, but you can stuff a single test case with multiple method calls and assertion checks. In the example above, that would mean creating a single testAdd() method and testing adding a single product, multiple products, invalid product and null all in one test method. <br />
</p>]]>

</content>
</entry>
<entry>
<title>When To Use a Record-Playback Tool</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/02/when_to_use_a_r_1.html" />
<modified>2005-02-18T16:29:13Z</modified>
<issued>2005-02-18T17:08:52Z</issued>
<id>tag:www.autotestguy.com,2005://1.10</id>
<created>2005-02-18T17:08:52Z</created>
<summary type="text/plain">As I previously stated, record-playback tools have some serious limitations. But that doesn&apos;t mean they should never be used. Here are some cases where they can add value: A completely non-technical person/department is responsible for automating tests These tools boast...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>As I <a href="http://www.autotestguy.com/archives/2005/02/automated_testi_2.html">previously stated</a>, record-playback tools have some serious limitations. But that doesn't mean they should never be used. Here are some cases where they can add value:</p>

<p><li>A completely non-technical person/department is responsible for automating tests</li><br />
These tools boast about their ease of use and how quickly a non-technical person can generate an automated test script. The person can just record a scenario and then play it back automatically.</p>

<p><li>The application changes relatively infrequently</li><br />
Unless the automation strategy involves some use of <a href="http://www.autotestguy.com/archives/design_patterns">design patterns</a> it's going to be very difficult to maintain new automated tests. What's most likely to happen is the automated testing resource will need to re-record test scenarios whenever the application changes. As long as this happens relatively infrequently, it could be a manageable cost.</p>]]>

</content>
</entry>
<entry>
<title>Automated Testing != Record-Playback Tool</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/02/automated_testi_2.html" />
<modified>2005-02-17T06:55:57Z</modified>
<issued>2005-02-17T16:35:48Z</issued>
<id>tag:www.autotestguy.com,2005://1.9</id>
<created>2005-02-17T16:35:48Z</created>
<summary type="text/plain">When people hear the word automated testing they conjure up a tool like Mercury&apos;s Winrunner, QuickTest Pro or Segue&apos;s SilkTest. While these tools seem worthwhile I would argue that for a serious automation effort these tools have a lot of...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>When people hear the word <a href="http://www.google.ca/search?hl=en&q=automated+testing">automated testing</a> they conjure up a tool like Mercury's <a href="http://www.mercury.com/us/products/quality-center/functional-testing/winrunner/">Winrunner</a>, <a href="http://www.mercury.com/us/products/quality-center/functional-testing/quicktest-professional/">QuickTest Pro</a> or Segue's <a href="http://www.segue.com/products/functional-regressional-testing/silktest.asp">SilkTest</a>. While these tools seem worthwhile I would argue that for a serious automation effort these tools have a lot of drawbacks.</p>

<h5>Maintenance Costs</h5>

<p>Record-playback tool vendors like to focus on how easy it is to record a test scenario with their tool. Test writers simply interact with the application normally while the test tool records all their actions. But no matter how easy it is to initially record a test scenario with a record-playback tool, the bulk of time and money will be spent on the ongoing maintenance of each test as the application changes. Screens will get added, buttons will get removed, column names will get modified. A company using a record-playback tool is left with two options - either keep re-recording all the tests as the application changes or stop recording scripts and maintain the generated test scripts like a real program.</p>

<p>Simply re-recording all test scenarios won't hold up in the long term because there will be duplication of recorded test code when testing similar scenarios. When the application under test inevitably changes (e.g. a new button was added which needs to be pressed for each test scenario), test writers will have to re-record all the test scenarios that are affected by that change. Even if the repetitive actions have been factored out into reusable modules, these modules don't use object oriented language features to make them more effective. Record-playback scripts are more expensive to maintain because the code they generate is long, complicated, not object oriented and must be further manipulated to put into reusable components.</p>

<p>It would be more desirable (and economical) to write test code using a real object-oriented language (e.g. Java, C#). Automated web testing design patterns can be fully used to create low maintenance web tests that will withstand continuous changes in the application under test. I have <a href="http://www.pnsqc.org/conference04/tuesday.php#rybalov">presented</a> and written a <a href="http://www.autotestguy.com/archives/Design Patterns for Customer Testing.pdf">paper about automated testing design patterns</a> for the <a href="http://www.pnsqc.org/">Pacific Northwest Software Quality Conference</a>. These <a href="http://www.autotestguy.com/archives/design_patterns">patterns</a> leverage the object-oriented language features to create tests that are low maintenance and adaptable to application changes.</p>

<h5>Test Language</h5>

<p>Record-playback test tool vendors are not in the business of creating programming languages. Yet most vendors create a language that is specific to their test tool. This forces test developers to learn a specialized language just to test their software.  These tools ignore industry-standard programming languages that are meant to be used in a wide array of applications - including testing. There is nothing inherently so strange about test development that necessitates having a unique language just for that task.</p>

<p>By creating their own languages, which are inevitably not as complete as industry standard languages, test developers are left with incomplete libraries for common tasks (e.g. file I/O, string manipulation, collections libraries), which means test developers have to write and test common functions that are already available in standard programming languages. What's more, the languages these vendors come up with are not object-oriented and are designed to keep companies locked-in to their test tools, since no one else uses that language.</p>

<p>This increases the time needed to train test developers on how to use a record-playback tool. Usually, record-playback tool vendors offer training courses to use their programming language with their tool, costing thousands of dollars. Not only are the costs prohibitive, but test developers are less likely to learn a technology if they know it is specific to one vendor's tool.</p>

<p><br />
<h5>Design Patterns</h5></p>

<p>Despite what record-playback tool vendors might advertise, test development is a software development activity. As such, the same principles that apply to application development apply to test development.  Namely, well designed code that is easy to change, with no duplication. Just as there are well established design patterns to write effective application software, there are analogous test design patterns that enable writing low maintenance test code. Our test tool is well suited to these test design patterns because tests are written in a real object-oriented language instead of a procedural, vendor-specific language.</p>

<p>By using the <a href="http://www.autotestguy.com/archives/design_patterns/">automated testing design patterns</a> with an object-oriented language, test developers can write tests that insulate them from application changes as well as the test tool. These patterns help decouple vendor-specific test code from application-specific test code, making tests more maintainable and adaptable to change.</p>

<p><br />
<h5>Integration with Build and Reporting Processes</h5></p>

<p>Record and playback tools are designed to keep the customer fully dependent on them for all aspects of testing - test creation, execution, reporting. Most use vendor-specific language that are not object-oriented, not recognized by test developers and are not amenable to automated testing design patterns. Even the tools that <a href="http://www.mercury.com/us/products/quality-center/functional-testing/winrunner/faq.html">claim</a> they can generate test code in an object-oriented language generate complicated procedural code that happens to be written in an object-oriented language. This leads to higher test maintenance costs because test developers can't use proven design patterns to lower maintenance costs of tests.</p>

<p>Record and playback tools often sell a total solution, incorporating many products into one test suite. The functional testing component usually uses its own testing framework for test execution, test creation, test reporting, and other test related features. Not only does this lead to serious vendor lock-in when it come to testing your application, but this doesn't address the need of test developers who like to use industry-standard approaches to testing. Most test developers are already familiar with unit testing frameworks such as <a href="http://www.junit.org">JUnit</a>. However, they will be forced to use the vendor's testing framework because the vendor's test tool only works with their own framework. If a company ever wanted to switch test tools, it would have to start the process all over again because a record and playback tool is vendor specific in every way - the test code it generates, the way it runs tests, the way it reports test results. This doesn't make it easy to incorporate these tools with industry standard build tools such as <a href="http://ant.apache.org/">Ant</a>.<br />
</p>]]>

</content>
</entry>
<entry>
<title>Are automated test tools for real?</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/02/are_automated_t.html" />
<modified>2005-02-16T16:14:34Z</modified>
<issued>2005-02-16T15:51:59Z</issued>
<id>tag:www.autotestguy.com,2005://1.12</id>
<created>2005-02-16T15:51:59Z</created>
<summary type="text/plain">Alan Earls wrote an article comparing pros and cons of traditional automated testing tools. He makes the following points: even if tools look impressive in a demo, they often fail to deliver on their promise and become shelfware the tool...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>Alan Earls wrote an <a href="http://www.adtmag.com/article.asp?id=9307">article</a> comparing pros and cons of traditional automated testing tools. </p>

<p>He makes the following points:</p>

<ul>
<li>even if tools look impressive in a demo, they often fail to deliver on their promise and become shelfware</li>
<li>the tool is not going to solve all your quality problems for you if there is no testing process nor the right people already in place</li>
</ul>]]>

</content>
</entry>
<entry>
<title>Hey Vendors, Give Us Real Scripting Languages</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/02/hey_vendors_giv_1.html" />
<modified>2005-02-16T16:41:22Z</modified>
<issued>2005-02-15T22:15:46Z</issued>
<id>tag:www.autotestguy.com,2005://1.13</id>
<created>2005-02-15T22:15:46Z</created>
<summary type="text/plain">Bret Pettichord wrote an article about how traditional automated testing tools force their users to use a proprietary language to automate their tests. He makes a lot of great points about the downside of using these proprietary languages (vendorscript) for...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>Bret Pettichord wrote an <a href="http://www.stickyminds.com/s.asp?F=S2326_COL_2">article</a> about how traditional automated testing tools force their users to use a proprietary language to automate their tests. He makes a lot of great points about the downside of using these proprietary languages (vendorscript) for test automation:</p>

<ul>
<li>they undermine collaboration between development and testing teams since developers use real programming languages while the test team is left with vendorscript</li>
<li>vendorscript often lack basic library functions that are present in real programming languages</li>
<li>no third party books/documentation is available for the vendorscript</li>
<li>it's hard to find experienced people that are proficient in the vendorscript</li>
</ul>]]>

</content>
</entry>
<entry>
<title>Automated Unit Test Creation - AppPerfect</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/02/automated_unit.html" />
<modified>2005-02-16T11:00:56Z</modified>
<issued>2005-02-14T21:59:44Z</issued>
<id>tag:www.autotestguy.com,2005://1.8</id>
<created>2005-02-14T21:59:44Z</created>
<summary type="text/plain">After the demo with Agitar, a fellow developer discovered another product that does what Agitator does and then some for a fraction of Agitar&apos;s cost. AppPerfect includes automated unit test creation, code analyzer, a web testing tool (integrates with HttpUnit)...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>After the <a href="archives/2005/02/automatic_unit.html">demo with Agitar</a>, a fellow developer discovered another product that does what Agitator does and then some for a fraction of Agitar's cost. <a href="http://www.appperfect.com/">AppPerfect</a> includes automated  unit test creation, code analyzer, a web testing tool (integrates with <a href="http://www.httpunit.org/">HttpUnit</a>) and a load testing tool. They have a free version of the tool that only omits a few features and a paid version which is priced at $495 per seat - about 1/7th the cost of Agitar's per seat cost.</p>

<p>It's interesting that a <a href="http://java.sun.com/javaone/duke_awards.html">lot</a> <a href="http://www.infoworld.com/article/04/08/27/35TCagitator_1.html">of</a> <a href="http://www.agitar.com/company/000009.html#kent">people</a> heard of Agitar while AppPerfect remains <a href="http://www.google.com/search?hl=en&lr=&q=AppPerfect">relatively unknown</a>.</p>]]>

</content>
</entry>
<entry>
<title>Automated Unit Test Creation - Agitar</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/02/automatic_unit.html" />
<modified>2005-02-14T22:18:16Z</modified>
<issued>2005-02-11T22:01:18Z</issued>
<id>tag:www.autotestguy.com,2005://1.3</id>
<created>2005-02-11T22:01:18Z</created>
<summary type="text/plain">Today at work, we got a demo of a piece of software that automates the creation of unit tests for an arbitrary piece of Java code. After going through the obligatory slides, they got to the meat of the presentation...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>Tools</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>Today at work, we got a demo of a piece of <a href="http://www.agitar.com">software</a> that automates the creation of unit tests for an arbitrary piece of Java code. After going through the obligatory slides, they got to the meat of the presentation by generating a whole slew of tests for a samples piece of code (they call this process "agitation"). While it was impressive, I'm still not fully convinced that it can do this intelligently with a system it knows nothing about. A lot of the test cases were boundary conditions for methods while others were garbage type inputs to see if the code would break. While this type of input testing is very important it doesn't cover the whole spectrum of tests that need to be generated.</p>

<p>It would be extremely helpful if this tool could generate tests with input data particular to an application. For instance, if I were using this tool on <a href="http://www.ebay.com">eBay's</a> code, I'd want it to automatically create test auctions, test bidders, test sellers and so on. That way, you'd be exercising the application that's specific to the rules and objects of that application. In order to make this happen, the tool needs you, the developer, to write a slew of factories that create this application specific data. </p>

<p>It's still unclear to me whether the time taken to create all these factories is less than the time it would take to write out all the unit tests manually. If it is, then this tool has some real value. What's ironic is that at the end of the demo, their sales guy predicted people's skepticism by saying "you probably think this tool is not going to work on your program because you think your program is unique". I thought that was an accurate assessment of the situation. So he's going to come back in a couple of weeks time and redemo this tool against the company's program. Stay tuned...</p>

<p>I find this area fascinating since I feel this could be the next big thing to affect software quality. Automated test creation is one of those aspects of automated testing that has always remained manual (see my previous posts: Automated Testing is Very Manual) and I admire this company for attempting to bring this area to the same level of automation as test execution.</p>]]>

</content>
</entry>
<entry>
<title>Automated Testing is Very Manual</title>
<link rel="alternate" type="text/html" href="http://www.autotestguy.com/archives/2005/02/automated_testi_1.html" />
<modified>2005-02-18T12:30:58Z</modified>
<issued>2005-02-07T22:23:58Z</issued>
<id>tag:www.autotestguy.com,2005://1.6</id>
<created>2005-02-07T22:23:58Z</created>
<summary type="text/plain">I was reading about Autonomic Computing recently where computer systems can automate their own configuration and recover automatically from problems, like our bodies. This made me wonder how this concept can be applied to automated testing. Automated testing is conventionally...</summary>
<author>
<name>Misha Rybalov</name>
<url>http://www.autotestblog.com</url>
<email>blog@gomisha.com</email>
</author>
<dc:subject>General</dc:subject>
<content type="text/html" mode="escaped" xml:lang="en" xml:base="http://www.autotestguy.com/">
<![CDATA[<p>I was reading about <a href="http://ibm.com/developerworks/autonomic">Autonomic Computing</a> recently where computer systems can automate their own configuration and recover automatically from problems, like our bodies. This made me wonder how this concept can be applied to automated testing. Automated testing is conventionally thought of as automated test execution (i.e. the automatic running of tests). However, there are additional factors that remain a mostly manual process. I will expand on these factors below.</p>

<p><br />
<strong>Test Creation</strong></p>

<p>People are still used to creating tests manually. With the tools that I develop and use, test writers must write programming code to tell the tool what the test should do. Similarly, record-play back tools make the test writer record their actions and then later plays them back (aside: this is not way I support developing automated tests for a multitude of reasons - see future blogs). To get to the next generation of automated testing, test developers will need an automated way to create (or at least drastically reduce the time to create) test cases.</p>

<p><br />
<strong>Analyzing Test Failures</strong></p>

<p>The accepted way of analyzing test failures is to examine the test results log and determine, based on the discrepancy between the expected and actual values whether the test failure is a bug or a change in the application that requires an auto test update. If there are many test failures, this process can be very time consuming. Again, some form of automation in this area could greatly improve the automated testing process. Perhaps, the automated test tool could be trained (e.g. with a rule engine) to make decisions about whether a test failure is a bug or simply a cosmetic change to the application that warrants an update to the test.</p>

<p><br />
<strong>Updating Tests</strong></p>

<p>A reality of automated testing is that the applications that are being tested will inevitably change. When these changes occur, automated tests have to be updated accordingly. To minimize the impact of these changes, auto test developers can make use of <a href="http://www.pnsqc.org/conference04/tuesday.php#rybalov">design patterns that lower test case maintenance costs</a>. However, one must manually create these design patterns specifically for each application or module under test. I fully advocate this approach but the problem still remains that you have to manually create and then maintain these design patterns. A more mature approach would have the automated test tool automatically create design patterns for an application and then update that code automatically when the application changes.</p>

<p><br />
<strong>Entering Bug Reports</strong></p>

<p>Once again, this process is currently very manual. A company will often use a totally different system to enter bugs as it does to run the automated tests (this is the case at my company). So we have this great automated way to run our tests, but then have to rely on totally manual process to enter all the details about the test failure. With a more mature test automation process, the automated test tool could (after determining a test failure is a bug) automatically enter defect reports in the bug tracking system.</p>

<p><br />
<strong>Data Setup</strong></p>

<p>Automated testing involves verifying that the actual behaviour of the application matches the expected behaviour. Often, this type of behaviour verification involves checking that expected data matches actual data returned by the application. In order to configure the application to return the expected data, the data has to be pre-loaded into the application (usually into the application's database) before the automated tests are run. This pre-loading, or data setup, falls outside the scope of most automated test tools. Instead, the automated test developer is expected to manage this on their own. This leads to each company having to re-invent its own way of pre-loading its automated test data into its application.</p>

<p><br />
As I see it, automated testing is really in its infancy where tools are mostly focused on automating the test execution side of the testing process and don't adequately address the other aspects to testing such as test creation, test reporting, test updating, entering defects and data setup. With the introduction of these concepts in automated test tools, we can begin to apply principles of autonomic computing in the field of automated testing.</p>]]>

</content>
</entry>

</feed>