<?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>Ryan Greenhall &#187; testing</title>
	<atom:link href="http://www.ryangreenhall.com/category/testing/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ryangreenhall.com</link>
	<description>Thoughts on Software Development</description>
	<lastBuildDate>Sun, 21 Aug 2011 15:28:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Exposed Scenario Implementation</title>
		<link>http://www.ryangreenhall.com/2008/10/exposed-scenario-implementation/</link>
		<comments>http://www.ryangreenhall.com/2008/10/exposed-scenario-implementation/#comments</comments>
		<pubDate>Tue, 21 Oct 2008 08:13:00 +0000</pubDate>
		<dc:creator>Ryan Greenhall</dc:creator>
				<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.ryangreenhall.com/2008/10/exposed-scenario-implementation/</guid>
		<description><![CDATA[In my previous post I refactored a noisy scenario method so that it communicated the required scenario steps more clearly.  Although this was a huge improvement in terms of readability the SignInAcceptanceScenarios class still has a significant weakness; maintainability due to the exposure of a number of implementation details.
Here is the current state of [...]]]></description>
			<content:encoded><![CDATA[<p>In my previous post I refactored a <a href="http://ryangreenhall.blogspot.com/2008/10/noisy-scenario-methods.html">noisy scenario method</a> so that it communicated the required scenario steps more clearly.  Although this was a huge improvement in terms of readability the SignInAcceptanceScenarios class still has a significant weakness; maintainability due to the exposure of a number of implementation details.</p>
<p>Here is the current state of the sign-in scenario:</p>
<pre><span style="color: blue;">public class</span> SignInAcceptanceScenarios {

   <span style="color: blue;">private</span> WebDriver <span style="color: darkviolet;">driver</span>;

   <span style="color: darkgoldenrod;">@Before</span>   <span style="color: blue;">
   public void</span> setup() {
       <span style="color: darkviolet;">driver</span> = new HtmlUnitDriver();
   }

   <span style="color: darkgoldenrod;">@Test</span>
   <span style="color: blue;">public void</span> shouldPresentKnownUserWithTheWelcomePage() {

       Credentials credentials = new Credentials(<span style="color: green;">"ryangreenhall"</span>, <span style="color: green;">"password"</span>);

       givenAnExistingUserWith(credentials);
       whenUserLogsInWith(credentials);
       thenTheUserIsPresentedWithTheWelcomePage();
   }

   <span style="color: blue;">private void</span> givenAnExistingUserWith(Credentials credentials) {
       User user = new UserBuilder().withCredentials(credentials).build();

       UserRespository respository = new UserRespository();
       respository.create(user);
   }

   <span style="color: blue;">private void</span> whenUserLogsInWith(Credentials credentials) {
       browseToHomePage();
       enterUsernameAndPassword(credentials);
       clickSignInButton();
   }

   <span style="color: blue;">private</span> WebDriver browseToHomePage() {
       <span style="color: darkviolet;">driver</span>.get(<span style="color: green;">"http://www.example.com/sign-in"</span>);
       return <span style="color: darkviolet;">driver</span>;
   }

   <span style="color: blue;">private void</span> enterUsernameAndPassword(Credentials credentials) {       <span style="color: darkviolet;">
       driver</span>.findElement(By.id(<span style="color: green;">"username"</span>)).sendKeys(credentials.getUserName());
       <span style="color: darkviolet;">driver</span>.findElement(By.id(<span style="color: green;">"password"</span>)).sendKeys(credentials.getPassword());
   }

   <span style="color: blue;">private void</span> pressSignInButton() {
       <span style="color: darkviolet;">driver</span>.findElement(By.id(<span style="color: green;">"login"</span>)).submit();
   }

   <span style="color: blue;">private void</span> thenTheUserIsPresentedWithTheWelcomePage() {
       Assert.assertEquals(<span style="color: green;">"Welcome"</span>, driver.getTitle());
   }
}</pre>
<h3>Violating the Single Responsibility Principle</h3>
<p>Following the <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">Single Responsibility Principle</a> we know that a class should have only one reason to change.  The SignInAcceptanceScenario is responsible for ensuring that the identified sign-in scenarios execute correctly.  Let&#8217;s consider how many reasons it has to change:</p>
<ol>
<li>The sign in resource changes: e.g. /log-in;</li>
<li>We want to replace Web Driver with another web testing framework;</li>
<li>The parameter names for username and password change;</li>
<li>The title of the welcome page changes;</li>
<li>The behaviour of the application changes;</li>
</ol>
<p>We have identified that our scenario class has five reasons to change! The only valid reason for this class to change is when the behaviour of the sign in process changes. For example, rather than presenting the user with the welcome page they are taken to their profile page, a common feature for most social networking sites these days.</p>
<p>Clearly with so many reasons to change, acceptance scenarios written in this style have the potential to require many changes throughout the lifetime of the application.</p>
<h3>Abstraction and Encapsulation to the Rescue</h3>
<p>Wouldn&#8217;t it be great if we could encapsulate our scenarios from implementation details such as the location of the sign-in resource and the parameter names used to communicate the users credentials? This would allow the implementation of the application to change without modifying our scenarios.</p>
<p>Currently when implementing the sign in scenario we are thinking in terms of the abstractions provided by the Web, for example, browse to the home page and submit parameters to a sign-in resource. Wouldn&#8217;t it be great if we could raise the level of abstraction and just sign in to the application using credentials, asking the resulting page if it is the welcome page?</p>
<p>Let&#8217;s briefly consider one possible approach.</p>
<h3>Fluent Navigation</h3>
<p>Rather than exposing the implementation details of how we are interacting with application we need a suitable abstraction.  One such abstraction involves representing each page in the application as a Page Object.  The <a href="http://code.google.com/p/webdriver/wiki/PageObjects">Page Object Model</a>, introduced to me by my colleague <a href="http://dan.bodar.com/">Dan Bodart</a> and also recommended by the <a href="http://code.google.com/p/webdriver">WebDriver</a> team, nicely encapsulates the internal representation of a page and provides methods for appropriate interactions.  Another nice feature of the Page Object Model is that we can make use of a <a href="http://www.martinfowler.com/bliki/FluentInterface.html">fluent interface</a> to allow seamless navigation through any number of pages.</p>
<p>The goal here is to demonstrate the value of introducing a suitable abstraction for interacting with the application.  I will therefore leave detailed descriptions of the implementation in the interest of brevity.</p>
<h3>SignInPage</h3>
<p>Given that the scenario in the example involves signing in to the application we will need a SignInPage that allows credentials to be entered and submitted.</p>
<p>For example:</p>
<pre><span style="color: blue;">import</span> com.example.domain.Credentials;

<span style="color: blue;">public class</span> SignInPage implements Page {

    <span style="color: blue;">public</span> SignInPage() {
    }

    <span style="color: blue;">public</span> SignInPage with(Credentials credentials) {        <span style="color: purple;">
        // enter the username and password</span>
        return this;
    }

    <span style="color: blue;">public</span> Page submit() {        <span style="color: purple;">
        // submit the username and password to the sign-in resource
        // and return a Page representation</span>
        <span style="color: purple;">// of the response.</span>
    }

    <span style="color: blue;">public</span> String getTitle() {        

    }
}
</pre>
<h3>Application Facade</h3>
<p>Now that we have a SignInPage how can our SignInAcceptanceScenarios class get hold of one?  The SignInPage will be dispensed by a class called MyApp, which acts a facade for the application providing methods to access various pages in the application. This approach nicely decouples the scenario from the URLs used to address pages in the application.</p>
<p>For example:</p>
<pre><span style="color: blue;">import </span>com.example.web.pages.HomePage;<span style="color: blue;">import </span>com.example.web.pages.Page;<span style="color: blue;">import </span>com.example.web.pages.SignInPage;

<span style="color: blue;">public</span> <span style="color: blue;">class</span> MyApp {

    <span style="color: blue;">public</span> static SignInPage signIn() {        <span style="color: purple;">
        // GET the sign in page and return a sign in page object</span>
    }
}</pre>
<h3>Matching Pages</h3>
<p>We now have the ability to navigate to the sign-in page, enter the users credentials and submit, receiving a resultant page.  The only remaining functionality required by the sign-in scenario is to ensure that the page returned as a result of submitting user credentials is the welcome page. How can we encapsulate the sign-in scenario from knowing the internals of the welcome page?  This sounds like a job for a <a href="http://code.google.com/p/hamcrest/">Hamcrest</a> matcher.  We will create a WelcomePageMatcher that knows if a given page is the welcome page by inspecting the title of the page.</p>
<p>For example:</p>
<pre><span style="color: blue;">import </span>org.hamcrest.BaseMatcher;<span style="color: blue;">
import </span>org.hamcrest.Description;<span style="color: blue;">
import </span>com.example.web.pages.Page;

<span style="color: blue;">public class </span>WelcomePageMatcher extends BaseMatcher {

    <span style="color: blue;">public</span> boolean matches(Object actualPage) {
        return <span style="color: green;">"Welcome"</span>.equals(((Page)actualPage).getTitle());
    }

    <span style="color: blue;">public</span> void describeTo(Description description) {
    }

    <span style="color: blue;">public</span> static WelcomePageMatcher isWelcomePage() {
        return <span style="color: blue;">new</span> WelcomePageMatcher();
    }
}
</pre>
<h3>Bringing Everything Together</h3>
<p>The application facade, SignInPage and WelcomePageMatcher can be combined to provide a very concise specification of the behaviour required when users sign-in to the example application.</p>
<pre><span style="color: blue;">import</span> com.example.domain.builders.UserBuilder;<span style="color: blue;">
import</span> com.example.domain.Credentials;<span style="color: blue;">
import</span> com.example.domain.User;<span style="color: blue;">
import</span> com.example.persistence.UserRespository;<span style="color: blue;">
import</span> static com.example.web.MyApp.signIn;
<span style="color: blue;">import</span> com.example.web.pages.Page;
<span style="color: blue;">import</span> static com.example.web.pages.matchers.WelcomePageMatcher.isWelcomePage;
<span style="color: blue;">import</span> org.junit.Test;

<span style="color: blue;">public class</span> SignInAcceptanceScenarios {

   <span style="color: darkgoldenrod;">@Test</span>
   <span style="color: blue;">public void</span> shouldPresentKnownUserWithTheWelcomePage() {
       Page pageAfterLogIn = null;
       Credentials credentials = new Credentials(<span style="color: green;">"ryangreenhall"</span>, <span style="color: green;">"password"</span>);

       givenAnExistingUserWith(credentials);
       whenUserLogsInWith(credentials, pageAfterLogIn);
       thenUserIsPresentedWithTheWelcomePage(pageAfterLogIn);
   }

   <span style="color: purple;">// Alternatively we could have:</span>
   <span style="color: darkgoldenrod;">@Test</span>
   <span style="color: blue;">public void</span> shouldPresentKnownUserWithTheWelcomePage() {
       Credentials credentials = new Credentials(<span style="color: green;">"ryangreenhall"</span>, <span style="color: green;">"password"</span>);

       <span style="color: purple;">// Given</span>
       givenAnExistingUserWith(credentials);

       <span style="color: purple;">// When</span>
       Page pageAfterLogin = signIn().with(credentials).submit();

       <span style="color: purple;">// Then</span>
       ensureThat(pageAfterLogin, isWelcomePage());
   }

   <span style="color: purple;">// Alternatively we can combine the when and then steps in a single line:</span>   <span style="color: darkgoldenrod;">
   @Test</span>
   <span style="color: blue;">public void</span> shouldPresentKnownUserWithTheWelcomePage() {
       Credentials credentials = new Credentials(<span style="color: green;">"ryangreenhall"</span>, <span style="color: green;">"password"</span>);

       givenAnExistingUserWith(credentials);

       ensureThat(signIn().with(credentials).submit(), respondsWithWelcomePage());
   }

   <span style="color: blue;">private void</span> givenAnExistingUserWith(Credentials credentials) {
       User user = new UserBuilder().withCredentials(credentials).build();

       UserRespository respository = new UserRespository();
       respository.create(user);
   }

   <span style="color: blue;">private void</span> whenUserLogsInWith(Credentials credentials, Page pageAfterLogIn) {
       pageAfterLogIn = signIn().with(credentials).submit();
   }

   <span style="color: blue;">private void</span> thenUserIsPresentedWithTheWelcomePage(Page pageAfterLogin) {
       ensureThat(page, isWelcomePage());
   }
}</pre>
<h3>Summary</h3>
<p>We have seen that the introduction of a simple internal <a href="http://martinfowler.com/bliki/DomainSpecificLanguage.html">DSL</a> to interact with the application has greatly improved the readability of this scenario. Furthermore the SignInAcceptanceScenarios class is now completely decoupled from the implementation of the application making it less susceptible to change.</p>
<p>We can now change the following concerns without modifying the SignInAcceptanceScenario:</p>
<ol>
<li>Location of the sign in resource (encapsulated in the SignInPage class);</li>
<li>Web testing framework (encapsulated in both the Application Facade and Page classes);</li>
<li>The parameter names for username and password (encapsulated in the SignInPage);</li>
<li>The title of the welcome page changes (encapsulated in the WelcomePageMatcher);</li>
</ol>
<p>The SignInAcceptanceScenarios class now has only one responsibility; defining the behaviour of the application and thus should only require modification when the behaviour of the application changes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ryangreenhall.com/2008/10/exposed-scenario-implementation/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Noisy Scenario Methods</title>
		<link>http://www.ryangreenhall.com/2008/10/noisy-scenario-methods/</link>
		<comments>http://www.ryangreenhall.com/2008/10/noisy-scenario-methods/#comments</comments>
		<pubDate>Sun, 19 Oct 2008 14:34:00 +0000</pubDate>
		<dc:creator>Ryan Greenhall</dc:creator>
				<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.ryangreenhall.com/2008/10/noisy-scenario-methods/</guid>
		<description><![CDATA[This is the second entry in a series of posts that provide practical advice on how to avoid or refactor away from common functional testing smells.
Noisy scenario methods can generally be identified by the presence of long methods, which fail to highlight the important interactions with the application clearly.  The code driving the application [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second entry in a series of posts that provide practical advice on how to avoid or refactor away from common functional testing smells.</p>
<p>Noisy scenario methods can generally be identified by the presence of long methods, which fail to highlight the important interactions with the application clearly.  The code driving the application will typically be at a low level of abstraction adding to the noise.  For web applications this will involve requesting resources, posting parameters and ensuring the expected response is returned.  For example:</p>
<pre>    <span style="color: blue;">public class</span> SignInAcceptanceScenarios {

        <span style="color: darkgoldenrod;">@Test</span>
        <span style="color: blue;">public void</span> shouldPresentKnownUserWithTheWelcomePage() {

            User user = new UserBuilder().withUsername(<span style="color: green;">"ryangreenhall"</span>).withPassword(<span style="color: green;">"password"</span>).build();

            UserRespository respository = new UserRespository();            r
            respository.create(user);

            WebDriver driver = new HtmlUnitDriver();
            driver.get(<span style="color: green;">"http://www.example.com"</span>);

            driver.findElement(By.id(<span style="color: green;">"username"</span>)).sendKeys(<span style="color: green;">"ryangreenhall"</span>);
            driver.findElement(By.id(<span style="color: green;">"password"</span>)).sendKeys(<span style="color: green;">"password"</span>);
            driver.findElement(By.id(<span style="color: green;">"login"</span>)).submit();

            Assert.assertEquals(<span style="color: green;">"Welcome"</span>, driver.getTitle());
     }
}</pre>
<p>When reading scenarios I like to see clear descriptions of the steps that are taken when interacting with the application. The main problem with noisy scenario methods is that the reader has to filter through the noise to figure out the following: what is the starting state of the system? What interactions occur? An additional problem is that the reader is required to think at a low level of abstraction.  Rather than thinking about signing in to the application we are forced to think in terms of posting parameters representing the username and password to a sign-in resource.</p>
<h3>Discovering the Scenario Steps</h3>
<p>Reading the example scenario we can see that ensuring a known user is presented with the welcome page requires the following steps:</p>
<ol>
<li>Create a user</li>
<li>Navigate to the applications home page</li>
<li>Fill in the sign in form with known credentials</li>
<li>Submit the signin form</li>
<li>Ensure that the user is taken to the welcome page</li>
</ol>
<p>Some would argue that the example scenario could be improved with the introduction of comments prior to each step.  However, I favour scenarios that are composed of small methods, whose names clearly describe: the starting state of the application, the interactions with the application and the expected outcomes. This allows the scenario to be expressed in terms of the domain without distracting the reader with the implementation details.</p>
<p>The Given-When-Then scenario format popularised by <a href="http://dannorth.net/introducing-bdd/">Behaviour Driven Development</a> is a good starting point for structuring scenarios.</p>
<h3>Making Your Code Read Like a Scenario</h3>
<p>The following example shows how the original scenario has been improved using a series of Extract Method refactorings in order to communicate the important steps in the scenario, namely: create a new user, sign in with known credentials and ensure that the user is presented with the welcome page.</p>
<pre>     <span style="color: blue;">public class</span> SignInAcceptanceScenarios {

        <span style="color: blue;">private</span> WebDriver <span style="color: darkviolet;">driver</span>;

        <span style="color: darkgoldenrod;">@Before</span>        <span style="color: blue;">
        public void</span> setup() {
            <span style="color: darkviolet;">driver</span> = new HtmlUnitDriver();
        }

        <span style="color: darkgoldenrod;">@Test</span>
        <span style="color: blue;">public void</span> shouldPresentKnownUserWithTheWelcomePage() {

            Credentials credentials = new Credentials(<span style="color: green;">"ryangreenhall"</span>, <span style="color: green;">"password"</span>);

            givenAnExistingUserWith(credentials);
            whenUserLogsInWith(credentials);
            thenTheUserIsPresentedWithTheWelcomePage();
        }

        <span style="color: blue;">private void</span> givenAnExistingUserWith(Credentials credentials) {
            User user = new UserBuilder().withCredentials(credentials).build();

            UserRespository respository = new UserRespository();
            respository.create(user);
        }

        <span style="color: blue;">private void</span> whenUserLogsInWith(Credentials credentials) {
            browseToHomePage();
            enterUsernameAndPassword(credentials);
            clickSignInButton();
        }

        <span style="color: blue;">private</span> WebDriver browseToHomePage() {
            <span style="color: darkviolet;">driver</span>.get(<span style="color: green;">"http://www.example.com/sign-in"</span>);
            return <span style="color: darkviolet;">driver</span>;
        }

        <span style="color: blue;">private void</span> enterUsernameAndPassword(Credentials credentials) {
            <span style="color: darkviolet;">driver</span>.findElement(By.id(<span style="color: green;">"username"</span>)).sendKeys(credentials.getUserName());            <span style="color: darkviolet;">
            driver</span>.findElement(By.id(<span style="color: green;">"password"</span>)).sendKeys(credentials.getPassword());
        }

        <span style="color: blue;">private void</span> pressSignInButton() {
            <span style="color: darkviolet;">driver</span>.findElement(By.id(<span style="color: green;">"login"</span>)).submit();
        }

        <span style="color: blue;">private void</span> thenTheUserIsPresentedWithTheWelcomePage() {
            Assert.assertEquals(<span style="color: green;">"Welcome"</span>, driver.getTitle());
        }
    }</pre>
<p>Structuring scenario methods in this style allows the reader to quickly understand the behaviour expected of the application in the context of a given scenario. Furthermore given that they read like written scenarios in terms of the problem domain they can be used to assist in conversations with QAs and Business Analysts, in addition to serving as useful documentation for future maintainers.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ryangreenhall.com/2008/10/noisy-scenario-methods/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>The Rise of Modern Legacy Code</title>
		<link>http://www.ryangreenhall.com/2008/09/the-rise-of-modern-legacy-code/</link>
		<comments>http://www.ryangreenhall.com/2008/09/the-rise-of-modern-legacy-code/#comments</comments>
		<pubDate>Tue, 30 Sep 2008 14:29:00 +0000</pubDate>
		<dc:creator>Ryan Greenhall</dc:creator>
				<category><![CDATA[development]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.ryangreenhall.com/2008/09/the-rise-of-modern-legacy-code/</guid>
		<description><![CDATA[Legacy code, as defined by Michael Feathers in Working Effectively with Legacy Code, is code that is without tests and difficult to change. I would like to suggest that there is a new breed of legacy code emerging with the increasing adoption of Test Driven Development and more recently Behaviour Driven Development; Modern legacy code.
These [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">Legacy code, as defined by <span style="font-family: helvetica, arial, sans;">Michael </span>Feathers in <a href="http://www.objectmentor.com/resources/books.html">Working Effectively with Legacy Code</a>, is code that is without tests and difficult to change. I would like to suggest that there is a new breed of legacy code emerging with the increasing adoption of Test Driven Development and more recently Behaviour Driven Development; Modern legacy code.</p>
<p style="text-align: left;">These days, if you are lucky, you may encounter code bases with large suites of both unit and functional tests (perhaps I should say examples, specs or scenarios these days!).  However, in some cases, although these tests serve as a reliable regression suite guarding against defects being introduced when adding new features, they may fail to clearly describe the desired behaviour of the system clearly.</p>
<p style="text-align: left;">In my opinion modern legacy code is code that has good functional and unit test coverage, but where the tests (especially functional) fail to clearly communicate the desired behaviour of the application increasing the cost of maintenance.  This is a shame as with a little care and focus on readability it is possible to write functional tests that really do serve as documentation describing the behaviour of the application.</p>
<p style="text-align: left;">Should the concept of modern legacy be used as an excuse to not write functional tests?  Absolutely not.  Modern legacy should be a term that is used both to encourage teams to search for better ways to express their tests with the goal of improving readability and to seek out approaches that make functional tests easier to write.  Modern legacy is a huge improvement over traditional legacy but there is still plenty of room for improvement in how we ensure that our applications are behaving themselves.</p>
<p style="text-align: left;">In a future post I plan to identify common functional test smells that I have encountered and to provide practical advice on how to spruce them up so that they describe the behaviour of the application more clearly.</p>
<p style="text-align: left;">In the meantime have a look at the functional tests in your application.  Do they clearly describe the behaviour of your application?  A good acid test is to ask a developer from another team if they can understand what your application is supposed to do by reading the functional tests for a given functional area.  If you observe a puzzled stare followed by a series of WTFs then you may have some modern legacy code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ryangreenhall.com/2008/09/the-rise-of-modern-legacy-code/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

