<?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"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Lazy Tester</title>
	<atom:link href="http://www.thelazytester.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thelazytester.com</link>
	<description>Work smarter, not harder</description>
	<lastBuildDate>Tue, 04 Aug 2009 03:45:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Designing Tests With Actions &#8211; Part 1</title>
		<link>http://www.thelazytester.com/2009/08/03/designing-tests-with-actions-part-1/</link>
		<comments>http://www.thelazytester.com/2009/08/03/designing-tests-with-actions-part-1/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 03:42:33 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Articles]]></category>

		<guid isPermaLink="false">http://www.thelazytester.com/?p=40</guid>
		<description><![CDATA[There are many ways to design tests. In this article we will look at how to design tests by breaking an application down into actions. Designing a test case based on actions allows you to create tests at multiple layers of abstraction, which helps let you: a) Create tests earlier. b) Create more thorough tests. [...]]]></description>
			<content:encoded><![CDATA[<p>There are many ways to design tests. In this article we will look at how to design tests by breaking an application down into actions. Designing a test case based on actions allows you to create tests at multiple layers of abstraction, which helps let you:</p>
<p>a) Create tests earlier.<br />
b) Create more thorough tests.<br />
c) Find starting points for exploratory testing.<br />
<span id="more-40"></span><br />
Let&#8217;s start with the definition of an action. An action consists of the action itself, the preconditions required for the action, and the effects of that action. For this article, we will use logging in as an example. Let&#8217;s look at one way of defining a &#8220;login&#8221; action.</p>
<table class="action">
<tr>
<td colspan="2" class="actionheader">Login</td>
</tr>
<tr>
<td class="columnheaderleft">Preconditions</td>
<td class="columnheaderright">Effects</td>
</tr>
<tr>
<td class="columnleft">
<p>Valid username</p>
<p>Valid password</p>
</td>
<td class="columnright">
<p>User is authenticated</p>
</td>
</tr>
</table>
<p>This is a basic login action. In order to log in, you need a valid username and password. If you have that and you log in, you will be authenticated as the user you entered. This simple definition gives us our first test.</p>
<div class="test">
<p class="step">1) Using a valid username and password, attempt to login.</p>
<p class="verification">a) Verify that you are authenticated as the entered user.</p>
</div>
<p>Or abstractly, prepare preconditions, perform actions, and verify effects.</p>
<p>There are several things to notice here. First, this test makes no assumptions about the application interface. It is abstract enough that you could run it against a GUI or an API. We will look at what happens when you refine a test to use a specific interface in another article.</p>
<p>The second thing to notice is that the verification is also abstract, too abstract to effectively execute. This is the first place we have found to &#8220;test the spec&#8221;. Does the application&#8217;s specification document explain what it means for a user to be authenticated in enough detail to be able to tell unambiguously that a user is authenticated? If not, it&#8217;s time to start asking questions and get that information added to the spec.</p>
<p>This is also the first place where we can &#8220;peek inside the box&#8221;. What happens under the hood when a user is authenticated? If it&#8217;s a web application, is a session cookie sent to the user, and a session started on the server? If it&#8217;s a function in an API, are we given an authentication token? These are questions that can both make your test more detailed, and provide a starting point for exploratory testing. Exploratory testing will be covered in a later article.</p>
<p>Now let&#8217;s take another look at our login action. The definition given above is a &#8220;perfect&#8221; test. If we have &#8220;perfect&#8221; preconditions and we perform the &#8220;perfect&#8221; action we expect the &#8220;perfect&#8221; results. What happens if the preconditions are different? Here is the action for an expected failure.</p>
<table class="action">
<tr>
<td colspan="2" class="actionheader">Login</td>
</tr>
<tr>
<td class="columnheaderleft">Preconditions</td>
<td class="columnheaderright">Effects</td>
</tr>
<tr>
<td class="columnleft">
<p>Valid username and invalid password</p>
<p>OR invalid username and a valid password</p>
<p>OR invalid username and invalid password</p>
</td>
<td class="columnright">
<p>User is not authenticated</p>
</td>
</tr>
</table>
<p>We have taken the two previous preconditions, reversed each of them, and turned them into all of the possible combinations of the preconditions where we expect a failure. If either the username or password is invalid, or both are invalid, and we attempt to login, the user should not be authenticated. This gives us our next tests.</p>
<div class="test">
<p class="step">2) Using a valid username and an invalid password, attempt to login.</p>
<p class="verification">a) Verify that the user is not authenticated.</p>
</div>
<div class="test">
<p class="step">3) Using an invalid username and a valid password, attempt to login.</p>
<p class="verification">a) Verify that the user is not authenticated.</p>
</div>
<div class="test">
<p class="step">4) Using an invalid username and an invalid password, attempt to login.</p>
<p class="verification">a) Verify that the user is not authenticated.</p>
</div>
<p>The preconditions and the action are no more complicated than before, but now the verification has a small problem. It is verifying that something does <em>not</em> happen. If we have received our unambiguous definition of what being authenticated means, then on the surface this doesn&#8217;t seem difficult. But what happens in the code is another matter. Not only do we as testers often not have the access we need to verify that nothing has changed, but it would be difficult for a developer with full access to everything to demonstrate that nothing has changed in a non-trivial application.</p>
<p>How do we solve this problem? We need more to test. It is possible that absolutely nothing will happen if an invalid login attempt is made, but more likely, there will be a positive testable effect as well. Here is another chance to test the spec; What other effects will occur because of this invalid login attempt? It might look like this.</p>
<table class="action">
<tr>
<td colspan="2" class="actionheader">Login</td>
</tr>
<tr>
<td class="columnheaderleft">Preconditions</td>
<td class="columnheaderright">Effects</td>
</tr>
<tr>
<td class="columnleft">
<p>Valid username and invalid password</p>
<p>OR invalid username and a valid password</p>
<p>OR invalid username and invalid password</p>
</td>
<td class="columnright">
<p>User is not authenticated</p>
<p>An error occurs indicating that the username or password is invalid</td>
</tr>
</table>
<p>Now we have something else to verify. We can add the following to the three tests above.</p>
<div class="test">
<p class="verification">b) Verify that an error occurs indicating that the username or password is invalid.</p>
</div>
<p>Now we have something testable, but this still doesn&#8217;t help us verify point a) of these tests. To do that, we need to use another action. There should be at least one action where &#8220;User is not authenticated&#8221; is a precondition. Let&#8217;s use this one.</p>
<table class="action">
<tr>
<td colspan="2" class="actionheader">View a restricted web page</td>
</tr>
<tr>
<td class="columnheaderleft">Preconditions</td>
<td class="columnheaderright">Effects</td>
</tr>
<tr>
<td class="columnleft">User is not authenticated</td>
<td class="columnright">An error occurs indicating that the user is not authenticated</td>
</tr>
</table>
<p>For the sake of simplicity, we will use a more concrete action than the ones we have been looking at so far.</p>
<p>If we try to perform this action at the point where we expect the user is not authenticated, then we expect to see an error. If we see the effect, then we know that the precondition is correct assuming that the action is working correctly. If we do not see the expected effect, then we have another problem. Is it the precondition that is wrong or the action that is not working? Still, this gives us a way, uncertain as it may be, to test our original verification. Let&#8217;s reorder our tests and add our new steps.</p>
<div class="test">
<p class="step">2) Using a valid username and an invalid password, attempt to login.</p>
<p class="verification">a) Verify that an error occurs indicating that the username or password is invalid.</p>
<p class="step">3) Attempt to view a restricted web page.</p>
<p class="verification">b) Verify that an error occurs indicating that the user is not authenticated.</p>
</div>
<div class="test">
<p class="step">4) Using an invalid username and a valid password, attempt to login.</p>
<p class="verification">a) Verify that an error occurs indicating that the username or password is invalid.</p>
<p class="step">5) Attempt to view a restricted web page.</p>
<p class="verification">b) Verify that an error occurs indicating that the user is not authenticated.</p>
</div>
<div class="test">
<p class="step">6) Using an invalid username and an invalid password, attempt to login.</p>
<p class="verification">a) Verify that an error occurs indicating that the username or password is invalid.</p>
<p class="step">7) Attempt to view a restricted web page.</p>
<p class="verification">b) Verify that an error occurs indicating that the user is not authenticated.</p>
</div>
<p>You might be wondering how to pick an action to test the negative effect, or you might be wondering if one action is enough. After all, there will usually be more than one action that uses the precondition we want to test.  You&#8217;re also depending on the action that you are testing with to work correctly. This is part of the art of testing. Which action do you use, and how many do you use, before you are comfortable that the results are probably accurate? That will be up to your discretion.</p>
<p>This is just the beginning of creating tests for logging in. In the next article we will look at what happens when you combine an action with a concrete interface.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thelazytester.com/2009/08/03/designing-tests-with-actions-part-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Linear Workflow Automation</title>
		<link>http://www.thelazytester.com/2009/06/30/linear-workflow-automation/</link>
		<comments>http://www.thelazytester.com/2009/06/30/linear-workflow-automation/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 05:31:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://www.thelazytester.com/?p=33</guid>
		<description><![CDATA[If you need to create a script to automate an applet or an installation that follows a linear or wizard-style workflow, here&#8217;s a way of quickly automating it. This AutoIt script will automate the installation of Opera 9.64 into a custom directory. MsgBox(64, "Waiting", "Start the Opera installer.") AutoItSetOption("SendKeyDelay", 200) Dim $done $done = False [...]]]></description>
			<content:encoded><![CDATA[<p>If you need to create a script to automate an applet or an installation that follows a linear or wizard-style workflow, here&#8217;s a way of quickly automating it.<br />
<span id="more-33"></span><br />
This AutoIt script will automate the installation of Opera 9.64 into a custom directory.</p>
<pre class="codesample">MsgBox(64, "Waiting", "Start the Opera installer.")

AutoItSetOption("SendKeyDelay", 200)

Dim $done
$done = False

While Not $done
	If WinExists("Opera", "has successfully installed") Then
		WinActivate("Opera")
		Send("{SPACE}") ; Close the installer
		$done = true
	ElseIf WinExists("Opera", "Click Install to begin") Then
		WinActivate("Opera")
		Send("{SPACE}") ; Begin the install
	ElseIf WinExists("Opera", "Specify which icons") Then
		WinActivate("Opera")
		Send("{SPACE}") ; Install default icons
	ElseIf WinExists("Opera", "Install Opera") Then
		WinActivate("Opera")
		Send("{TAB}{SPACE}") ; Open the directory dialog
		Send("C:\Opera") ; Change the install directory to C:\Opera
		Send("{ENTER}") ; Close the directory dialog
		Send("{TAB}{TAB}{TAB}{SPACE}") ; Tab to next button and continue
	ElseIf WinExists("Opera", "Custom") Then
		WinActivate("Opera")
		Send("{SPACE}") ; Disable making Opera the default browser
		Send("{TAB}{TAB}") ; Tab to radio buttons
		Send("{DOWN}") ; Select custom install
		Send("{TAB}{TAB}{TAB}{TAB}{SPACE}") ; Tab back to next button and Continue
	ElseIf WinExists("Opera", "agree to this license") Then
		WinActivate("Opera")
		Send("{SPACE}") ; Select I Accept
	ElseIf WinExists("Opera", "Start Setup") Then
		WinActivate("Opera")
		Send("{SPACE}") ; Select Start Setup
	EndIf
WEnd</pre>
<p>The basic structure of this style is:</p>
<pre class="codesample">While not done
   If screen 1 text exists then
      do stuff
   Else if screen 2 text exists then
      do stuff
   Else if final screen text exists then
      do stuff
      done=true</pre>
<p>Each if statement matches with one screen in the program. Each if statement looks for text or an object unique to a screen, and then executes code to handle that particular screen. On the final screen, you break out of the loop to end your script.</p>
<p>The benefits of this style are:</p>
<ul>
<li>No need to code delays. The script keeps looking for the screen that comes after the install is complete.</li>
<li>It&#8217;s quick to write. Manually run through the install once, and note the text on each screen and the steps to be done on each screen.</li>
<li>It is more maintainable than a script with just a sequence of keystrokes.</li>
<li>Adding screens only means adding another small block of code.</li>
<li>It happens to handle a quirk of Windows Installer; each screen is a completely new window.</li>
</ul>
<p>This style is not good for automating programs with non-linear workflows, such as if the same actions repeat or branch with different data.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thelazytester.com/2009/06/30/linear-workflow-automation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Definition of Testing</title>
		<link>http://www.thelazytester.com/2009/06/16/the-definition-of-testing/</link>
		<comments>http://www.thelazytester.com/2009/06/16/the-definition-of-testing/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 00:11:44 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>

		<guid isPermaLink="false">http://www.thelazytester.com/?p=19</guid>
		<description><![CDATA[The first step of being a tester is understanding what testing entails. Let&#8217;s start with a very simple definition. Testing is making sure that the application does what it is supposed to do and does not do what it is not supposed to do. That doesn&#8217;t sound so bad, but what are the implications of [...]]]></description>
			<content:encoded><![CDATA[<p>The first step of being a tester is understanding what testing entails. Let&#8217;s start with a very simple definition. Testing is making sure that the application does what it is supposed to do and does not do what it is not supposed to do.</p>
<p>That doesn&#8217;t sound so bad, but what are the implications of this definition?<br />
<span id="more-19"></span></p>
<h2>the application does <em>what it is supposed to do</em></h2>
<p>If we&#8217;re going to test an application, we first have to know what it is supposed to do. Ideally this is answered by other people. Requirements, specifications, and design documents help to answer this question. Common sense should be able to fill in the gaps.</p>
<p>In practice, this never happens. You will always run into a scenario when writing test cases and even while testing where you cannot answer the question, &#8220;What is this supposed to do?&#8221; Knowing who can answer that question and having an open communication channel to those people is important.</p>
<p>Even with a perfect specification, what an application is supposed to do can be affected by physical limits. For example, a spec may say that an application should support an infinite number of users, but this is practically impossible. Even if you owned every hard drive in the world, there will still be a limited amount of space to store those users in. What an application would really do is, &#8220;support a large enough number of users so as to be effectively infinite.&#8221; Now you have the question of, &#8220;What is &#8216;a large enough number&#8217;?&#8221;</p>
<h2><em>making sure</em> that the application <em>does</em></h2>
<p>Once we know what an application is supposed to do, we have to decide how to verify that it does that. This might seem simple, but once again, it proves to be a significant challenge. Consider a program that is a fibonacci sequence generator. A fibonacci sequence is a sequence of numbers where each number in the sequence is the sum of the previous two numbers. The beginning of the sequence goes like this: 1, 1, 2, 3, 5, 8, 13.</p>
<p>Now think about how you would test this. Would you hand calculate the sequence and compare what the program generates to your sequence? If you decide to do that, I hope you really like where you&#8217;re sitting. The sequence is infinite, which means you are going to spend the rest of your life trying to test the generator in this way.</p>
<p>Don&#8217;t worry. In reality the sequence generator would stop working before that. Unfortunately, it stops working when it crashes. When this happens will depend on multiple factors including the language it was programmed in and what platform it was running on. These affect the implementation of the generator, and it may result in the program crashing when the value passes 4,294,967,296 or 2,147,483,647 or 65,536. Or it may not crash at all and suddenly start spitting out negative numbers. It all depends on how it is implemented in code, and that is generally hidden to testers.</p>
<h2><em>does not do what it is not supposed to do</em></h2>
<p>We already have the problem of testing a program that in theory never ends when it is working correctly. Now we have to consider everything that the sequence generator is not supposed to do. It is not supposed to:</p>
<ul>
<li>Output numbers not in the sequence.</li>
<li>Crash.</li>
<li>Erase the hard drive.</li>
<li>Invest your cash in stock in Euro Disney.</li>
<li>Cause hurricanes.</li>
<li>Bring you life-long happiness. Sorry.</li>
</ul>
<p>OK, so the last three are practically impossible, but they are still in the realm of things that the program is not supposed to do. But the first two are reasonable, and even likely, and the third is not as <a href="http://thedailywtf.com/Articles/The-Opposite-of-Backup.aspx">farfetched as</a> <a href="http://thedailywtf.com/Articles/WellIntentioned-Destruction.aspx">it may seem</a>.</p>
<p>Add to this the problem of making sure that something <em>doesn&#8217;t</em> happen. This is not always impossible, but it is very difficult. You might find that it crashes when calculating the 5,627th number. You still don&#8217;t know if it will crash when calculating the 9,321st number.</p>
<h2>The Art of Testing</h2>
<p>So by examining our simple definition of testing we&#8217;ve gone from difficult, to impossible, to soul-crushingly impossible. This is where the art of testing comes in. A tester&#8217;s skill is in covering enough of this infinite space to demonstrate that a user is unlikely to encounter a defect during the time that they use the program. Finding the answers to the question of what an application is supposed to do, figuring how how to make sure it is doing what it is supposed to do, predicting possible points of failure, and finding the failures that nobody ever thought were possible: These are just some of the things that an experienced tester is capable of doing.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thelazytester.com/2009/06/16/the-definition-of-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using AutoIt in scripting</title>
		<link>http://www.thelazytester.com/2009/06/09/using-autoit-in-scripting/</link>
		<comments>http://www.thelazytester.com/2009/06/09/using-autoit-in-scripting/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 01:23:30 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Tips]]></category>

		<guid isPermaLink="false">http://www.thelazytester.com/?p=13</guid>
		<description><![CDATA[Sometimes you just need to do a little quick automation of a third-party program, and don&#8217;t care about testing anything on it. If you&#8217;re not using a tool that can handle the program, you can often use AutoIt to do what you need to do and move on with your test. AutoIt comes with a [...]]]></description>
			<content:encoded><![CDATA[<p>Sometimes you just need to do a little quick automation of a third-party program, and don&#8217;t care about testing anything on it. If you&#8217;re not using a tool that can handle the program, you can often use <a href="http://www.autoitscript.com/autoit3/">AutoIt</a> to do what you need to do and move on with your test.<br />
<span id="more-13"></span><br />
AutoIt comes with a COM DLL called AutoItX that can be called by just about anything. All you have to do is install the <a href="http://www.autoitscript.com/autoit3/downloads.shtml">full package</a> and call functions on the COM object. Nearly all functions available in a normal AutoIt script are also available as functions on the object.</p>
<p>Here&#8217;s a simple example of a Ruby script using AutoItX. Using AutoItX with Ruby might be useful if you&#8217;re using WatiR, and run into an ActiveX control or Java applet.</p>
<pre class="codesample">require 'win32ole'

autoit = WIN32OLE.new('AutoItX3.Control')

if autoit.WinExists("Untitled - Notepad") == 1
	autoit.WinActivate("Untitled - Notepad")
	autoit.Send("Hello world!")
end</pre>
<p>Here&#8217;s the same example with C#. You have to add a reference to the AutoItX dll first.</p>
<pre class="codesample">using AutoItX3Lib;
/* Other usings and application code */

public void HelloWorld()
{
	AutoItX3Class automator = new AutoItX3Class();

	if (automator.WinExists("Untitled - Notepad", "") == 1)
	{
		automator.WinActivate("Untitled - Notepad", "");
		automator.Send("Hello world!", 0);
	}
}</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.thelazytester.com/2009/06/09/using-autoit-in-scripting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why The Lazy Tester?</title>
		<link>http://www.thelazytester.com/2009/06/03/why-the-lazy-tester/</link>
		<comments>http://www.thelazytester.com/2009/06/03/why-the-lazy-tester/#comments</comments>
		<pubDate>Thu, 04 Jun 2009 02:31:58 +0000</pubDate>
		<dc:creator>James</dc:creator>
				<category><![CDATA[Articles]]></category>

		<guid isPermaLink="false">http://www.thelazytester.com/?p=3</guid>
		<description><![CDATA[Why is this blog called The Lazy Tester? In the world of computers, laziness is a good thing. It&#8217;s often said that the best programmers are lazy programmers. This is not because lazy programmers are trying to do less work, but because they are trying to work more efficiently. The same can be true for [...]]]></description>
			<content:encoded><![CDATA[<p>Why is this blog called The Lazy Tester? In the world of computers, laziness is a good thing. It&#8217;s often said that the best programmers are lazy programmers. This is not because lazy programmers are trying to do less work, but because they are trying to work more efficiently. The same can be true for software testers. Why do more work than you have to? If you can test more in less time, why not do it? If you can get a tool to do your work for you, why not use it?</p>
<p>As this implies, a large focus of this blog will be automated testing and other testing tools. But I also intend to discuss other parts of testing practice. If you don&#8217;t know the basic manual practice of testing, no tool in the world is going to make you a good tester. Everything posted here is meant to make you a more effective tester, and to make testing more interesting and rewarding.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thelazytester.com/2009/06/03/why-the-lazy-tester/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

