<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" version="2.0">

<channel>
	<title>distributedlife</title>
	
	<link>http://distributedlife.com/blog</link>
	<description>passionate about everything</description>
	<lastBuildDate>Thu, 11 Mar 2010 13:55:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Distributedlife" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="distributedlife" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Vanilla C with Sprinkles – file reading</title>
		<link>http://distributedlife.com/blog/2010/03/vanilla-c-with-sprinkles-file-reading.html</link>
		<comments>http://distributedlife.com/blog/2010/03/vanilla-c-with-sprinkles-file-reading.html#comments</comments>
		<pubDate>Thu, 11 Mar 2010 13:55:45 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[vanilla c]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=482</guid>
		<description><![CDATA[Time to write some posts on doing regular Service Testing things in Vanilla C and the added benefit of HP Service Test C; which adds a few handy functions. If you&#8217;re just using Vanilla C you can replace lr_set and lr_get with functions that set and get char* strings respectively.
First up are some file related [...]]]></description>
			<content:encoded><![CDATA[<p>Time to write some posts on doing regular Service Testing things in Vanilla C and the added benefit of HP Service Test C; which adds a few handy functions. If you&#8217;re just using Vanilla C you can replace lr_set and lr_get with functions that set and get char* strings respectively.</p>
<p>First up are some file related functions and today is reading a UTF-8 file. We care little for the file size so you better have enough memory. If you are trying to load in a large file then you need to consider techniques like paging the data in.</p>
<pre><code class="cplusplus">
void ReadFileUTF8 (const char* const Filename, const char* TargetParameter)
{
</code></pre>
<p>The TargetParameter is the string name of a HP Parameter where we will store the contents of the file. </p>
<pre><code class="cplusplus">
    const unsigned int SEEK_END = 2 ;

    long FileHandle = 0 ;
    long FileSizeInBytes = 0 ;

    char * DataBuffer = 0;

    int shifted = 0 ;

    size_t result = 0;
    long index = 0 ;

    //Set our TargetParameter to Failed incase we don't make it
    lr_set("FAILED", TargetParameter);

    FileHandle = fopen (Filename, "rb" );
    if (!FileHandle)
    {
        lr_error_message ("Failed to open the file \"%s\"", Filename) ;
        return ;
    }

    //Get the file size. We use this to allocate our data buffer.
    fseek (FileHandle , 0 , SEEK_END);
    FileSizeInBytes = ftell (FileHandle);
    rewind (FileHandle);

    // allocate memory to contain the whole file
    DataBuffer = (char*) malloc ((sizeof(char) * FileSizeInBytes) + 1) ;
    if (!DataBuffer)
    {
        lr_error_message ("Could not allocate memory for buffer") ;
        return ;
    }

    // copy the file into the DataBuffer:
    result = fread (DataBuffer, sizeof(char), FileSizeInBytes, FileHandle) ;
    if (result != FileSizeInBytes)
    {
        lr_error_message ("Could not copy file data into buffer") ;
        if (DataBuffer)
        {
            free (DataBuffer) ;
        }
    }

    //add null-terminating char
    DataBuffer[FileSizeInBytes] = '\0' ;

    //Skip BOM (if there is one)
    if (DataBuffer[0] == '\xff' &amp;&amp; DataBuffer[1] == '\xfe')
    {
        DataBuffer++ ;
        DataBuffer++ ;
        shifted = 1 ;
    }

</code></pre>
<p>If you don&#8217;t have HP Service Test then you can change this next line and at the end of the function return your DataBuffer pointer to the caller without freeing it. I prefer to use HP Service Test parameters where possible because they allow you to do away with memory management for strings.</p>
<pre><code class="cplusplus">
    lr_set (DataBuffer, TargetParameter);

    //Move back to start of string before freeing memory
    if (shifted == 1)
    {
        DataBuffer-- ;
        DataBuffer-- ;
    }

    fclose (FileHandle) ;
    free (DataBuffer) ;
}
</code></pre>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/5D5NzjxixfE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/vanilla-c-with-sprinkles-file-reading.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improving HP Service Testing Summary</title>
		<link>http://distributedlife.com/blog/2010/03/improving-hp-service-testing-summary.html</link>
		<comments>http://distributedlife.com/blog/2010/03/improving-hp-service-testing-summary.html#comments</comments>
		<pubDate>Wed, 10 Mar 2010 13:55:27 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[HP Service Test]]></category>
		<category><![CDATA[improvement]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[services]]></category>
		<category><![CDATA[summary]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=477</guid>
		<description><![CDATA[After 8 chapters it’s time to leave the direct improvements to HP Service Test for now. I have some upcoming posts on testing cross cutting concerns and I’ll formally document my approach to automation testing.
For now here is what I covered. If you’re doing work with HP Service Test then I highly recommend you read [...]]]></description>
			<content:encoded><![CDATA[<p>After 8 chapters it’s time to leave the direct improvements to HP Service Test for now. I have some upcoming posts on testing cross cutting concerns and I’ll formally document my approach to automation testing.</p>
<p>For now here is what I covered. If you’re doing work with HP Service Test then I highly recommend you read these and make the necessary changes. <a href="http://distributedlife.com/blog/contact">Send me an email if you get stuck</a>.</p>
<ol>
<li><a href="http://distributedlife.com/blog/2009/12/improving-hp-service-tests-%e2%80%93-part-1.html">one small step for writing less code</a></li>
<li><a href="http://distributedlife.com/blog/2010/02/improving-hp-service-tests-part-2.html">focus on the delta</a></li>
<li><a href="http://distributedlife.com/blog/2010/02/improving-hp-service-tests-part-3.html">configuring services for use</a></li>
<li><a href="http://distributedlife.com/blog/2010/02/improving-hp-service-test-part-4.html">surfing the pipeline</a></li>
<li><a href="http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-5.html">great fault expectations</a></li>
<li><a href="http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-6.html">validating fault behaviour</a></li>
<li><a href="http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-7.html">fixtures for validation</a></li>
<li><a href="http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-8.html">being executed as</a></li>
</ol>
<p>I hope this has helped.</p>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/cylZZUVNvyk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/improving-hp-service-testing-summary.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UX Addendum</title>
		<link>http://distributedlife.com/blog/2010/03/ux-addendum.html</link>
		<comments>http://distributedlife.com/blog/2010/03/ux-addendum.html#comments</comments>
		<pubDate>Wed, 10 Mar 2010 13:55:20 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[user experience]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[ryan bocuher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[ux]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=474</guid>
		<description><![CDATA[One thing that I forgot to mention yesterday with my post about UX and intersections is that the orange line helps reinforce positive behaviour. The approach of using traffic lights punishes those who err rather than teaching people how to make the correct decision more frequently.
When we are designing user interfaces we should be mindful [...]]]></description>
			<content:encoded><![CDATA[<p>One thing that I forgot to mention <a href="http://distributedlife.com/blog/2010/03/ux-for-intersections.html">yesterday with my post about UX and intersections</a> is that the orange line helps reinforce positive behaviour. The approach of using traffic lights punishes those who err rather than teaching people how to make the correct decision more frequently.</p>
<p>When we are designing user interfaces we should be mindful of this and help the user make the correct decision rather than punishing them when they make the wrong one.</p>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/PfA1H4wFIDY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/ux-addendum.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UX for Intersections</title>
		<link>http://distributedlife.com/blog/2010/03/ux-for-intersections.html</link>
		<comments>http://distributedlife.com/blog/2010/03/ux-for-intersections.html#comments</comments>
		<pubDate>Tue, 09 Mar 2010 13:55:43 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[user experience]]></category>
		<category><![CDATA[decision]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[intersection]]></category>
		<category><![CDATA[process]]></category>
		<category><![CDATA[red light]]></category>
		<category><![CDATA[road]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[spending]]></category>
		<category><![CDATA[traffic]]></category>
		<category><![CDATA[ux]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=469</guid>
		<description><![CDATA[You’re driving along the road and you’re approaching an intersection. You’re at the point where if the light goes orange you’re unsure whether you should stop or continue through the intersection1. We are making the assumption that you’re generally law abiding. The light turns orange and you’re still in this no-man’s-land.
If you leave it too [...]]]></description>
			<content:encoded><![CDATA[<p>You’re driving along the road and you’re approaching an intersection. You’re at the point where if the light goes orange you’re unsure whether you should stop or continue through the intersection<sup>1</sup>. We are making the assumption that you’re generally law abiding. The light turns orange and you’re still in this no-man’s-land.</p>
<p>If you leave it too late you could end up in the intersection; if you keep going then you may run the red-light.</p>
<p>To make it more interesting there is a red-light and speed camera; so you can’t speed up and you get fined if you don’t make it.</p>
<p>What do you do?</p>
<p>The issue is uncertainty there are too many variables to make an easy judgement call. Not all intersections are the same length, not all roads are at the same speed, you are not always going exactly the speed limit, you’re not always the same distance from the intersection when the light changes.</p>
<p>If you add additional factors like poor vision from eyesight, poor vision from bad weather or poor spatial skills it becomes even harder.</p>
<p>If you look at this problem as “should I keep going?” we can make a simple change that I think would remove the issue.</p>
<p>If you’re travelling at the speed limit there is a finite distance you can travel in the five seconds from when the light goes orange to when the light goes red.</p>
<p>If you travelling 80km/h then are moving at 22.2metres per second and if you’re travelling at 60km/h then you are moving at 16.6m/s.</p>
<p>If you have 5 seconds to cross the intersection then you are going to travel 111.1 or 83.3 metres respectively.</p>
<p>Now consider the example story and add a single orange line drawn across the lane at 110m from the far end of the intersection. If the light goes orange and you haven’t crossed the orange line then you are never going to make it. The decision is made for you. If you’ve crossed the line then you will make it and can continue at the speed limit.</p>
<p>The caveat is that all of these equations are based on the maximum speed of the road. If you’re travelling slower than the speed limit or there are poor conditions and you are outside the line you have more time to stop. If you’re inside the line then it comes back to the judgement call.</p>
<p>Some may argue that because it doesn’t solve the problem for all scenarios it won’t work or the government would get sued. The judgement call is the backup and is the current process. The orange line solves the problem in all scenarios where the driver is travelling at speed. In rainy or icy conditions it may even help drivers who are unsure whether their car will stop in time.</p>
<p>To me; all of this relates back to designing the User Experience and challenging the assumptions about what we think the user knows at the decision point. I feel we are often too focused on the outcome of a decision (user invokes behaviour) rather than the decision process.</p>
<p>If we’re in the mindset of “if the user wants to do X they can click here and if they want to do Y they can click there” or “if the driver wants to make it through they keep driving and if they want to stop they slow down” we need to take a step back and make sure the user can make the decision in time.</p>
<p>When you are next giving a user choice consider why and how the decision is made. It may be possible to better plan the flow so that no decision is ever necessary.</p>
<ol class="footnotes"><li id="footnote_0_469" class="footnote">if you&#8217;re turning left you will be travelling at a lower speed and better able to stop</li></ol><img src="http://feeds.feedburner.com/~r/Distributedlife/~4/AI_S5yBtTZY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/ux-for-intersections.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>finding bugs with luck</title>
		<link>http://distributedlife.com/blog/2010/03/finding-bugs-with-luck.html</link>
		<comments>http://distributedlife.com/blog/2010/03/finding-bugs-with-luck.html#comments</comments>
		<pubDate>Mon, 08 Mar 2010 13:55:16 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[feedback]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[user testing]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=464</guid>
		<description><![CDATA[Throwing lots of users at a system does not adequately test it. Earlier this month I wrote about Google Buzz and how it would have passed testing without any issues being raised. I just found a link to the BBC article where ‘Google admits Buzz social network testing flaws’ . It’s about two weeks old [...]]]></description>
			<content:encoded><![CDATA[<p>Throwing lots of users at a system does not adequately test it. Earlier this month I wrote about Google Buzz and how it would have passed testing without any issues being raised. I just found a link to the BBC article where ‘<a href="http://news.bbc.co.uk/2/hi/8517613.stm">Google admits Buzz social network testing flaws</a>’ . It’s about two weeks old now but it illustrates my point about the role testing plays in product development.</p>
<blockquote><p>&#8220;We&#8217;ve been testing Buzz internally at Google for a while. Of course, getting feedback from 20,000 Googlers isn&#8217;t quite the same as letting Gmail users play with Buzz in the wild.&#8221;</p></blockquote>
<p>Recently I’ve noticed a trend, and it goes with the whole crowd-sourcing thing, where through sheer weight of ‘tester’ numbers, all major bugs would be found. This isn’t a rigorous process, this is luck. 20,000 user’s using a system will give you information about the product but it is entirely based on the demographic of the users.</p>
<p>What is the demographic of a Google employee? I don’t know but a guess would be technically minded, open-minded, friends with other Google employees? <a href="http://blog.utest.com/testing-the-limits-with-patrick-copeland-part-iii/2010/02/">From this Q&amp;A with Patrick Copeland the Senior Engineering Director</a> he lists some advice on aspiring tech execs:</p>
<blockquote><p>“Be technical: At Google all of our engineering execs have very strong technical backgrounds. They were programmers and many of them can – and do – still program today. Advice: remember your computer science and stay sharp.”</p></blockquote>
<p>If your demographic isn’t varied enough you will end up having 20,000 of the same user testing the system.</p>
<p>In the rest of the BBC article, the author mentions the ‘Google Trusted Tester’ program:</p>
<blockquote><p>Many of the firm&#8217;s new services are tested by the so-called Google Trusted Tester program, a network of friends and family of Google employees who are given confidential access to products before they launch.</p>
<p>Buzz was not tested by this program.</p></blockquote>
<p>There is a better way.</p>
<p>When I test a system I have a list of items that can impact the outcome of a test from including, user, invocation method, input data, state data and the environment. The first of these is the user. This is what needs to be thought about before the requirements are defined:</p>
<p>•	How does the user’s cultural background impact the user of the system?</p>
<ul>
<li>How does the user’s psychological state impact the user of the system?</li>
<li>How does the user’s education impact the system?</li>
<li>What is the user’s motivation and how does it impact the system?</li>
</ul>
<p>I include more traditional testing impacts here as well:</p>
<ul>
<li>Mobility</li>
<li>Accessibility</li>
<li>Vision</li>
<li>Geography</li>
</ul>
<p>This is qualitative testing and this is where the bugs like the ones that plagued Buzz are found.</p>
<p>Throwing large numbers of users at a system will not find all the issues that a competent skilled tester will find. There is a chance that this mass of people will find no bugs. Asking users about a system is great way to get feedback; but don’t be fooled into thinking this is testing.</p>
<p>If I fill out a form about the service at my local restaurant am I testing or am I providing feedback? At Google you are testing the restaurant in the real world you a providing feedback to someone that may or may not care.</p>
<p>What irks me about the news post is that Google stated that they didn’t test it properly and the implication is that more users providing feedback will solve the issue. This isn’t a failure of testing; it’s a failure of management to think that user feedback replaces quality testing over the duration of the project.</p>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/2uWdoRaMrXI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/finding-bugs-with-luck.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HP Service Test – Protocols Configuration bug</title>
		<link>http://distributedlife.com/blog/2010/03/hp-service-test-protocols-configuration-bug.html</link>
		<comments>http://distributedlife.com/blog/2010/03/hp-service-test-protocols-configuration-bug.html#comments</comments>
		<pubDate>Fri, 05 Mar 2010 13:55:56 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[bug]]></category>
		<category><![CDATA[configuration]]></category>
		<category><![CDATA[defect]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[HP Service Test]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[service testing]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=459</guid>
		<description><![CDATA[I led into this yesterday when I talked about simplifying the way in which we specify which user is executing the test.
When HP Service Test starts execution it picks up the protocols.config and uses it for your service call. If you have multiple services to hit in your test that are invoked by your test [...]]]></description>
			<content:encoded><![CDATA[<p>I led into this <a href="http://distributedlife.com/blog/2010/03/hp-service-test-protocols-configuration-bug.html">yesterday</a> when I talked about simplifying the way in which we specify which user is executing the test.</p>
<p>When HP Service Test starts execution it picks up the protocols.config and uses it for your service call. If you have multiple services to hit in your test that are invoked by your test you can write a mapping file that maps each service to the appropriate protocols configuration file. If you are only hitting one service and that service calls other services on your behalf (an orchestration service) you only need the configuration for the service you directly consume.</p>
<p>Once that protocols.config is bound to the service, HP Service Test will not refresh the configuration until the iteration has complete. This is a particularly useless feature especially when you are trying to test multiple user configurations in the one project. As I <a href="http://distributedlife.com/blog/2009/10/structuring-hp-service-tests.html">outlined there are many ways to structure your service test projects</a> and having each action be a test is an issue here. The solution is one project file per configuration. Not a pleasant experience if you have a lot of user configurations to run and lots of services.</p>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/J1tutoJrHFA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/hp-service-test-protocols-configuration-bug.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improving HP Service Tests Part 8</title>
		<link>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-8.html</link>
		<comments>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-8.html#comments</comments>
		<pubDate>Thu, 04 Mar 2010 13:55:42 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[HP Service Test]]></category>
		<category><![CDATA[identity]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[service testing]]></category>
		<category><![CDATA[user]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=448</guid>
		<description><![CDATA[If your service implements security then you will need to include security configurations in your script. For basic HTTP authentication you can use the web_set_security method but for more complicated work you are going to create a protocols.config for your service request.
For any non-trivial service testing instillation you are may have to support multiple service [...]]]></description>
			<content:encoded><![CDATA[<p>If your service implements security then you will need to include security configurations in your script. For basic HTTP authentication you can use the web_set_security method but for more complicated work you are going to create a protocols.config for your service request.</p>
<p>For any non-trivial service testing instillation you are may have to support multiple service bindings and authentication mechanisms. Multiple these factors across services and endpoints and you start getting a configuration nightmare.</p>
<p>The solution of course is to generate the protocols.config file dynamically. I’m not going to provide a tutorial on how to generate this file. It’s dependant on your services and the environment you work in. I’ve only generated configurations for the three or four bindings we cater for. I’ll assume you can do the same.</p>
<p>What I am going to talk about is getting your actual test script so that it reads better when you combine security.</p>
<p>I like the fact that our tests look like this:</p>
<pre><code class="cplusplus">
ExecuteTestAsUser (MyServiceUser) ;

SetDefaultParameters () ;

CallService () ;
</code></pre>
<p>It’s a simple setup that makes your test readable and more robust. ExecuteTestAsUser is responsible for taking the identifier for a service user. We allocate one user per service. We do this because you are going to iterate through multiple security combinations (has access, no access, super user, banned, etc) if you had users set up in those security combinations and you attached <a href="http://distributedlife.com/blog/2009/10/identity-specific-and-anonymous-data.html">identity specific data to the use</a>r you have the potential to disrupt other tests running at the same time.</p>
<p>So it’s better to give each service a specific user and at the start of each test have code like so:</p>
<pre><code class="cplusplus">
GrantSuperUserToUser (MyServiceUser);
</code></pre>
<p>The implementation of such a function is dependent on the authorisation and authentication mechanisms in your environment.</p>
<p>Your users should be setup in an enumeration like so:</p>
<pre><code class="cplusplus">
enum UserScenarios
{
    DoNotSetSecurity,
    MyService1,
    MyService2
}
</code></pre>
<p>This helps to keep your user accounts type safe. You won’t misspell the username in your tests. Use a look up table to get to your username and passwords:</p>
<pre><code class="cplusplus">
char* usernames[] =
{
    "User001",
    "User002"
}

char* passwords[] =
{
    "PASSWORD",
    "PASSWORD"
}
</code></pre>
<p>The point of all this is that when you call ExecuteTestAsUser you can query the lookup tables using your identifier to resolve the username and password. This information is required for both web_set_security and protocols.config.</p>
<p>There is one caveat with protocols.config but I’ll discuss that tomorrow as there is no workaround as yet.</p>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/jF3vtIhWlB8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-8.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improving HP Service Tests Part 7</title>
		<link>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-7.html</link>
		<comments>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-7.html#comments</comments>
		<pubDate>Wed, 03 Mar 2010 13:55:31 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[abstraction]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[fixtures]]></category>
		<category><![CDATA[robust tests]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[service testing]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=439</guid>
		<description><![CDATA[Fixtures are generally used to provide common or centralised test setup. I use fixtures for validation as well. This allows us to remove a dependency on our data stores and to some extent, on our service response structures.
why would we want such an abstraction?
The data store abstraction is useful because as I discussed here on [...]]]></description>
			<content:encoded><![CDATA[<p>Fixtures are generally used to provide common or centralised test setup. I use fixtures for validation as well. This allows us to remove a dependency on our data stores and to some extent, on our service response structures.</p>
<h3>why would we want such an abstraction?</h3>
<p>The data store abstraction is useful because <a href="http://distributedlife.com/blog/2010/02/service-testing-what-are-we-checking.html">as I discussed here on my article about what to focus on in service tests</a> we need to go back to the original source to validate information. If that code is in every test and the data store changes you need to recode every test. A better solution is to get the information you need (as supplied by the service) and pass that to the validation fixture.</p>
<p>If the data store changes then you can rewrite the validation fixture without having to change a single test.</p>
<p>If the service response changes then you are going to change every test anyway but, the scope of your changes are reduced. <a href="http://distributedlife.com/blog/2010/02/improving-hp-service-test-part-4.html">If you’re using the pipeline</a> then you change your ExtractResult function and the code to pass those values into the validation fixture. This is a usually one-line change in each test (find and replace anyone?) and a pipeline change you had to make anyway.</p>
<h3>what will our code look like?</h3>
<pre><code class="cplusplus">
//Result Validation
{
    ExtractResult () ;

    CheckResultCountEquals (1) ;

    CheckAwesomePersonAgainstServiceResponse
    (
        lr_get ("{Result_AwesomePerson_1_Id}"),
        lr_get ("{Result_AwesomePerson_1_Name}"),
        lr_get ("{Result_AwesomePerson_1_Address}"),
        lr_get ("{Result_AwesomePerson_1_MobileNumber}")
    ) ;
}
</code></pre>
<p>As you can see we have an ExtractResult call as we always do. We verify the result count; this is always a useful check to put in every test that returns a collection. Sometimes you get more than you expect.</p>
<p>Finally, we have our function CheckAwesomePerson. It takes each of the properties from the service request as parameters. This is where we separate the service response from our test. We are just using properties now. If the service gets another property then you will have to update the tests that are impacted but tests that are not impacted won’t need to change.</p>
<p>If for example our additional property was a date/time of the request then we don’t need to validate that in this test; we’ll have it in a separate test focusing on that attribute. Here we are focussing on awesome people.</p>
<p>Next up is the implementation of our CheckAwesomePerson method and this is where we separate our test from the data store implementation. In this case it is d a database.</p>
<pre><code class="cplusplus">
void CheckAwesomePerson
(
    const char* const Id,
    const char* const Name,
    const char* const Address,
    const char* const MobileNumber
)
{
    lr_set (Id, "__CheckAwesomePerson_Id") ;

    GetRow ("AWESOME_PEOPLE", "ID", lr_get ("{__CheckAwesomePerson_Id}"), "__CheckAwesomePerson") ;

    VerifyRowValueEquals ("__CheckAwesomePerson", "ID", Id) ;
    VerifyRowValueEquals ("__CheckAwesomePerson", "FOLDER_NAME", Name) ;
    VerifyRowValueEquals ("__CheckAwesomePerson", "PARENT_ID", Address) ;
    VerifyRowValueEquals ("__CheckAwesomePerson", "FOLDER_TYPE", MobileNumber) ;
}
</code></pre>
<p>As you can see we get the row and validate it against the parameters. If the Awesome_People table ended up being moved to an xml-document or a web resource then we can change this implementation and the test themselves won’t need to change.</p>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/TcNjq1l_wbw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-7.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improving HP Service Tests Part 6</title>
		<link>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-6.html</link>
		<comments>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-6.html#comments</comments>
		<pubDate>Tue, 02 Mar 2010 13:55:48 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[faults]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[service testing]]></category>
		<category><![CDATA[soap]]></category>
		<category><![CDATA[validation]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=431</guid>
		<description><![CDATA[Validating fault behaviour is something that is tied to the business implementation of faults. How each business implements faults, will determine the implementation of your fault validation routines. What I will talk about is how to setup your fault validation routines so that you can write fault validation easily.
The goal is to have your service [...]]]></description>
			<content:encoded><![CDATA[<p>Validating fault behaviour is something that is tied to the business implementation of faults. How each business implements faults, will determine the implementation of your fault validation routines. What I will talk about is how to setup your fault validation routines so that you can write fault validation easily.</p>
<p>The goal is to have your service test code look like this:</p>
<pre><code class="cplusplus">
SetDefaultParameters () ;

FaultExpected () ;

CallService () ;

ExpectFaultWithCode ("ServiceEpicFailFault") ;
</code></pre>
<p>The above snippet is of course assuming that your services through fault codes with each fault.</p>
<p>What we are going for is a one-line validation of fault behaviour. If your faults have an additional information that you want to validate then pass it into the function. If you have different types of faults (UserFault, BusinessFault, SystemFault, ServiceFault, etc) then you will want to change the name of the function for each one.</p>
<p>It is better to have the following code:</p>
<pre><code class="cplusplus">
ExpectServiceFaultWithCode ("ServiceEpicFailFault") ;
</code></pre>
<p>Rather than</p>
<pre><code class="cplusplus">
ExpectFaultWithCode (“ServiceFault”, "ServiceEpicFailFault") ;
</code></pre>
<p>The reason being is that your fault type is now strongly typed (you could achieve the same with an enumeration) and spelling mistakes will not cause incorrect fault validation.</p>
<p>The basics of your fault validation code will be something like this:</p>
<pre><code class="cplusplus">
void ExpectGenericFault (void)
{
    int result = 0 ;

    result = lr_xml_extract
    (
        "XML={response}",
        "FastQuery=Envelope/Body/Fault",
        "XMLFragmentParam=Fault",
        "NotFound=Continue",
        LAST
    );

    if (!result)
    {
        lr_error_message("A generic fault was expected and not found") ;
    }
}
</code></pre>
<p>In this snippet we are expecting a generic fault; a SOAP fault with no additional information. We report an error if no fault is found.</p>
<p>If you have fault codes to validate then you will want a method signature like so:</p>
<pre><code class="cplusplus">
void ExpectGenericFault (const char* const FaultCode)
{
    //...
}
</code></pre>
<h3>the response document</h3>
<p>In our code we are dependency on the response document. We have done this all through our [pipeline] code. The reason why we do this is that if every service stores its results in a HP parameter called “response” we can take it for granted that when you want the current service response you use that parameter. This saves effort giving each response object a unique name and makes your code more readable. You have to be careful but in most cases when the response variable is not set HP Service Test will halt execution anyway.</p>
<h3>what fault code?</h3>
<p>Where do you get the expected fault codes from? If your developers are good then you can get documentation from them that include the faults and when they are expected. This is the kind of information they would provide another developer that is going to consume their service. If they don’t have this information then they are doing shoddy work.</p>
<p>If you’re waiting for information you can try the test and see. This is what I do when I’m waiting for information; test anyway.</p>
<ul>
<li>If you get a fault, did you expect it?</li>
<li>What about the fault code; does it make sense?</li>
<li>What about other fault information; is it useful to the consumer?</li>
</ul>
<p>Ponder that information and if it makes sense then move onto the next test. If it doesn’t make sense; raise a defect questioning the validity of the fault information. If you feel a defect is too strong then ask for a ‘request for clarification’.</p>
<h3>where fault code?</h3>
<p>I’m not going to provide code on how to validate a fault code response because I don’t know how your fault codes are stored. It&#8217;s basic XPATH validation like this:</p>
<pre><code class="cplusplus">
success = lr_xml_find
(
    "XML={source}",
    "FastQuery={xpath}",
    "Value={value}",
    "NotFound=Continue",
    LAST
);
</code></pre>
<p>But if you have multiple fault codes then it may be more like this:</p>
<pre><code class="cplusplus">
success = lr_xml_find
(
    "XML={source}",
    "Query={xpath}",
    "Value={value}",
    "NotFound=continue",
    "SelectAll=yes",
LAST
);
</code></pre>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/10ITm2a2AMw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-6.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improving HP Service Tests Part 5</title>
		<link>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-5.html</link>
		<comments>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-5.html#comments</comments>
		<pubDate>Mon, 01 Mar 2010 13:55:24 +0000</pubDate>
		<dc:creator>Ryan Boucher</dc:creator>
				<category><![CDATA[testing]]></category>
		<category><![CDATA[behaviour]]></category>
		<category><![CDATA[distributedlife]]></category>
		<category><![CDATA[fault]]></category>
		<category><![CDATA[ryan boucher]]></category>
		<category><![CDATA[rybo]]></category>
		<category><![CDATA[service testing]]></category>
		<category><![CDATA[services]]></category>

		<guid isPermaLink="false">http://distributedlife.com/blog/?p=426</guid>
		<description><![CDATA[In Part 4 we made a substantial change to how we write service tests. Those that have followed my direction in their own environment will have noticed that we can no longer control whether or not we are expecting a SoapFault or a SoapResult. You may have been using AnySoap which is ignoring a useful [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://distributedlife.com/blog/2010/02/improving-hp-service-test-part-4.html">In Part 4</a> we made a substantial change to how we write service tests. Those that have followed my direction in their own environment will have noticed that we can no longer control whether or not we are expecting a SoapFault or a SoapResult. You may have been using AnySoap which is ignoring a useful HP Service Test feature.</p>
<p>I’ve got the solution and it makes our tests a bit more explicit about our expectations. This is a good thing; the more someone can gather about the expected behaviour of the test, from the test, the better.</p>
<p>Rather than hard coding our expectations into the web request we want to get a setup that looks a bit like this:</p>
<pre><code class="cplusplus">
SetDefaultParameters () ;

FaultExpected () ;

CallService () ;
</code></pre>
<p>The benefit is that anyone reading the test will see that we are expecting a fault. If we don’t want a fault then we use the following code. Note that we don’t need any coding effort for services requests that don’t fault.</p>
<pre><code class="cplusplus">
SetDefaultParameters () ;

CallService () ;
</code></pre>
<p>To achieve this setup we need to make some small changes to our <a href="http://distributedlife.com/blog/2010/02/improving-hp-service-test-part-4.html">pipeline</a>.</p>
<p>The first change is in SetDefaultParameters; here we setup the default state for our service; which is a “SoapResult”. We store this in the ServiceFaultState parameter</p>
<pre><code class="cplusplus">
void SetDefaultParameters (void)
{
    lr_set ("SoapResult", "ServiceFaultState") ;
</code></pre>
<p>From here we write a new method called FaultExpected that sets the ServiceFaultState parameter to SoapFault. We don’t ever use the setting AnySoap. This allows anything through the gate and our services should behave in a deterministic way.</p>
<pre><code class="cplusplus">
void FaultExpected (void)
{
    lr_save_string ("SoapFault", "ServiceFaultState") ;
}
</code></pre>
<p>Finally with all that written we need to change each and every service request to date. Thankfully this can be done using a find and replace. We want to go from any of the following setups:</p>
<pre><code class="cplusplus">
"ExpectedResponse=SoapFault",

"ExpectedResponse=SoapResult",

"ExpectedResponse=AnySoap",
</code></pre>
<p>To</p>
<pre><code class="cplusplus">
"ExpectedResponse={ServiceFaultState}",
</code></pre>
<p>And in the context of a full web service call:</p>
<pre><code class="cplusplus">
web_service_call
(
    "StepName={Service}::{Method}",
    "SOAPMethod={Service}|{Binding}|{Method}",
    "ResponseParam=response",
    "Service={Service}",
    "ExpectedResponse={ServiceFaultState}",
    BEGIN_ARGUMENTS,
    END_ARGUMENTS,
    BEGIN_RESULT,
    END_RESULT,
    LAST
);
</code></pre>
<p>Tomorrow, I’ll talk a bit about how to validate service faults.</p>
<img src="http://feeds.feedburner.com/~r/Distributedlife/~4/ylqeYAYKlXI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://distributedlife.com/blog/2010/03/improving-hp-service-tests-part-5.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
