[TFUI] Re: [agile-testing] Re: Using examples to drive development

Phlip <[email protected]> Tue, 17 Mar 2009 19:34:21 -0700
Newsgroups gmane.comp.programming.test-first-user-interfaces
Message-ID <[email protected]>
--3V3TIiUe3Aj1ul16UtgVPvlYpRj3rNrl8Kf9Z2b
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Lisa Crispin wrote:

> We definitely want to do these investigative efforts. But I still feel 
> examples are a good way to start. What have other folks found on their 
> projects?

I have to confess a low rate of adoption for my assert_xpath project, to 
unit-test raw HTML. As a computer scientist and a DSL-zealot, I _like_ writing 
inhumanly elaborate queries, like '//fieldset[ following-sibling::input[ @name = 
"etc" ] ]'.

Someone on the net recently challenged a forum to write an assertion like that, 
but in this format, and I did it:

   assert_xhtml do
     form @action do
       fieldset do
         label 'first name'
         input :name => 'etc'
       end
     end
   end

Easier to read, huh? The HTML element names are all raw Ruby; they call 
method_missing(), to convert into XPath expressions like that, on the fly.

That forum was the RSpec mailing list, and this leads to an interesting 
observation. RSpec, and Behavior Driven Development, were _supposed_ to be about 
the customer tests. Yet these days the general Ruby on Rails community now 
considers TDD (and the test/unit library) to be OLD SCHOOL!

All the new, cool projects use RSpec. It appears that programmers like to 
specify their designs by example, too.

Here's that assertion's RSpec version:

   @response.body.should be_html_with{
     form @action do
       fieldset do
         label 'first name'
         input :name => 'etc'
       end
     end
   }

Like all good examples, those assertions skip over irrelevant details, such as 
intervening <table>, <div>, <li> tags, or whatever.

(Those of you with Ruby can try those by grabbing the assert2 gem; then calling 
require 'assert2/xhtml'.)

-- 
   Phlip
   http://www.zeroplayer.com/

--3V3TIiUe3Aj1ul16UtgVPvlYpRj3rNrl8Kf9Z2b
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit



<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
</head>




<body style="background-color: #ffffff;">

<!--~-|**|PrettyHtmlStartT|**|-~-->
<div id="ygrp-mlmsg" style="width:655px; position:relative;">
<div id="ygrp-msg" style="width: 470px; margin:0; padding:0 25px 0 0; float:left; z-index:1;">
<!--~-|**|PrettyHtmlEndT|**|-~-->

    <div id="ygrp-text">
            <p>Lisa Crispin wrote:<br>
<br>
&gt; We definitely want to do these investigative efforts. But I still feel <br>
&gt; examples are a good way to start. What have other folks found on their <br>
&gt; projects?<br>
<br>
I have to confess a low rate of adoption for my assert_xpath project, to <br>
unit-test raw HTML. As a computer scientist and a DSL-zealot, I _like_ writing <br>
inhumanly elaborate queries, like '//fieldset[ following-sibling:<wbr>:input[ @name = <br>
&quot;etc&quot; ] ]'.<br>
<br>
Someone on the net recently challenged a forum to write an assertion like that, <br>
but in this format, and I did it:<br>
<br>
assert_xhtml do<br>
     form @action do<br>
       fieldset do<br>
         label 'first name'<br>
         input :name =&gt; 'etc'<br>
       end<br>
     end<br>
   end<br>
<br>
Easier to read, huh? The HTML element names are all raw Ruby; they call <br>
method_missing(<wbr>), to convert into XPath expressions like that, on the fly.<br>
<br>
That forum was the RSpec mailing list, and this leads to an interesting <br>
observation. RSpec, and Behavior Driven Development, were _supposed_ to be about <br>
the customer tests. Yet these days the general Ruby on Rails community now <br>
considers TDD (and the test/unit library) to be OLD SCHOOL!<br>
<br>
All the new, cool projects use RSpec. It appears that programmers like to <br>
specify their designs by example, too.<br>
<br>
Here's that assertion's RSpec version:<br>
<br>
@response.body.<wbr>should be_html_with{<br>
     form @action do<br>
       fieldset do<br>
         label 'first name'<br>
         input :name =&gt; 'etc'<br>
       end<br>
     end<br>
   }<br>
<br>
Like all good examples, those assertions skip over irrelevant details, such as <br>
intervening &lt;table&gt;, &lt;div&gt;, &lt;li&gt; tags, or whatever.<br>
<br>
(Those of you with Ruby can try those by grabbing the assert2 gem; then calling <br>
require 'assert2/xhtml'<wbr>.)<br>
<br>
-- <br>
   Phlip<br>
   <a href="http://www.zeroplayer.com/">http://www.zeroplay<wbr>er.com/</a><br>
</p>
 

    </div>  

    <!--~-|**|PrettyHtmlStart|**|-~-->
    <div width="1" style="color: white; clear: both;">__._,_.___</div>

             
    <!-- Start the section with Message In topic -->
    <div id="ygrp-actbar" style="clear: both; margini-bottom: 25px; white-space:nowrap; color: #666; text-align: right;">
              <span class="left" style="float: left; white-space:nowrap;">
          <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/message/1041;_ylc=X3oDMTM0Y3ZkMGVqBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BG1zZ0lkAzEwNDEEc2VjA2Z0cgRzbGsDdnRwYwRzdGltZQMxMjM3MzQzNjY1BHRwY0lkAzEwNDE-">
            Messages in this topic          </a> (<span class="bld" style="font-weight:bold;">1</span>)
        </span>
        <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/post;_ylc=X3oDMTJwMGI2czJnBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BG1zZ0lkAzEwNDEEc2VjA2Z0cgRzbGsDcnBseQRzdGltZQMxMjM3MzQzNjY1?act=reply&messageNum=1041">
          <span class="bld" style="font-weight:bold;">
            Reply          </span> (via web post)
        </a>  | 
        <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/post;_ylc=X3oDMTJldjdpajQwBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA250cGMEc3RpbWUDMTIzNzM0MzY2NQ--" class="bld" style="font-weight:bold;">
          Start a new topic        </a>
          </div> 
    <!-------     Start Nav Bar  ------>
    <!-- |**|begin egp html banner|**| -->
    <div id="ygrp-vitnav" style="padding-top: 10px; font-family: Verdana; font-size: 77%; margin: 0;">
                <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/messages;_ylc=X3oDMTJlcWs2Y3FtBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA21zZ3MEc3RpbWUDMTIzNzM0MzY2NQ--">Messages</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/files;_ylc=X3oDMTJmZTNwdDVxBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2ZpbGVzBHN0aW1lAzEyMzczNDM2NjU-">Files</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/photos;_ylc=X3oDMTJlZm1zY3FxBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA3Bob3QEc3RpbWUDMTIzNzM0MzY2NQ--">Photos</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/links;_ylc=X3oDMTJmMDAwc3NpBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2xpbmtzBHN0aW1lAzEyMzczNDM2NjU-">Links</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/database;_ylc=X3oDMTJjM2lhbjc5BF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2RiBHN0aW1lAzEyMzczNDM2NjU-">Database</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/polls;_ylc=X3oDMTJmNnA3dGJiBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA3BvbGxzBHN0aW1lAzEyMzczNDM2NjU-">Polls</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/members;_ylc=X3oDMTJlMDJ1ZmhrBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA21icnMEc3RpbWUDMTIzNzM0MzY2NQ--">Members</a>  
            |    <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/calendar;_ylc=X3oDMTJkcjFjczFvBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2NhbARzdGltZQMxMjM3MzQzNjY1">Calendar</a>  
    </div>  
    <!-- |**|end egp html banner|**| -->

                        <div id="ygrp-grft" style="font-family: Verdana; font-size: 77%; padding: 15px 0;">
          

        </div>
      
                  <div id="ygrp-mkp">
      <div id="hd">MARKETPLACE</div>
      <div id="ads">
                  <div class="ad" style="color:#628C2A; font-family:Arial; font-weight:bold;">
            <hr noshade="noshade" size="1"><a href="http://us.ard.yahoo.com/SIG=14ksk43r7/M=493064.12016295.13271503.10835568/D=groups/S=1705007207:MKP1/Y=YAHOO/EXP=1237350865/L=/B=kDuQUUPDhE8-/J=1237343665979836/K=TYq6yTfxpPY_Uw9.nijW_A/A=5530388/R=0/SIG=11nuutlas/*http://explore.yahoo.com/groups/kraftmealsmadesimple/">From kitchen basics to easy recipes - join the Group from Kraft Foods
</a>          </div>
                          <div class="ad" style="color:#628C2A; font-family:Arial; font-weight:bold;">
                          <hr size=1 noshade>
                        <a href="http://us.ard.yahoo.com/SIG=14k8jllhu/M=730914.13354441.13465017.10835568/D=groups/S=1705007207:MKP1/Y=YAHOO/EXP=1237350865/L=/B=kTuQUUPDhE8-/J=1237343665979836/K=TYq6yTfxpPY_Uw9.nijW_A/A=5667010/R=0/SIG=12elpv1ko/*http://www.socialtrack.net/redir.aspx?CID=11125&AFID=32673&DID=50240&SID=Ad3 ">Do you think you're Smart? Find out your IQ today. Take our quiz at Quizyou.net.</a>          </div>
                      </div>
    </div>
      
    <!-- yahoo logo -->
    <!-- |**|begin egp html banner|**| -->
    <div id="ygrp-ft" style="font-family: verdana; font-size: 77%; border-top: 1px solid #666; padding: 5px 0;">
      <a href="http://groups.yahoo.com/;_ylc=X3oDMTJkcXRzZWZzBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2dmcARzdGltZQMxMjM3MzQzNjY1">
      <img src="http://us.i1.yimg.com/us.yimg.com/i/yg/img/logo/ma_grp_160.gif" height="15" width="106" border="0" alt="Yahoo! Groups"></a> <br>
      <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces/join;_ylc=X3oDMTJmY2o0OHVyBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA3N0bmdzBHN0aW1lAzEyMzczNDM2NjU-">Change settings via the Web</a> (Yahoo! ID required) <br>
      Change settings via email: <a href="mailto:TestFirstUserInterfaces-digest-hHKSG33TihhbjbujkaE4pw@public.gmane.org?subject=Email Delivery: Digest">Switch delivery to Daily Digest</a> | <a href = "mailto:TestFirstUserInterfaces-traditional-hHKSG33TihhbjbujkaE4pw@public.gmane.org?subject=Change Delivery Format: Traditional">Switch format to Traditional</a> <br>

      <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces;_ylc=X3oDMTJkMGFhcmduBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwNmdHIEc2xrA2hwZgRzdGltZQMxMjM3MzQzNjY1">
        Visit Your Group 
      </a> |
      <a href="http://docs.yahoo.com/info/terms/">
        Yahoo! Groups Terms of Use      </a> |
      <a href="mailto:TestFirstUserInterfaces-unsubscribe-hHKSG33TihhbjbujkaE4pw@public.gmane.org?subject=">
        Unsubscribe      </a> 
    </div>     <!-- |**|end egp html banner|**| -->
  </div> <!-- ygrp-msg -->

  
  <!-- Sponsor -->
  <!-- |**|begin egp html banner|**| -->
  <div id="ygrp-sponsor" style="width:160px; float:right; clear:none; margin:0 0 25px 0; background: white;">
    <!-- Network content -->
    
<!-- Start Recommendations -->
<div id="ygrp-reco">
     </div>
<!-- End Recommendations -->

	    <!-- Start vitality -->
	    <div id="ygrp-vital" style="background-color: #e0ecee; margin-bottom: 20px; padding: 2px 0 8px 8px;">
	      		<div id="vithd" style="font-size: 77%; font-family: Verdana; font-weight: bold; color: #333; text-transform: uppercase;">Recent Activity</div>
		<ul style="list-style-type:none; padding: 0; margin: 2px 0;">
		    
		    
		    
		    
		    
		    
		</ul>
	      	      <a href="http://groups.yahoo.com/group/TestFirstUserInterfaces;_ylc=X3oDMTJlaDE5ZmIxBF9TAzk3MzU5NzE0BGdycElkAzg3NDQ3MDQEZ3Jwc3BJZAMxNzA1MDA3MjA3BHNlYwN2dGwEc2xrA3ZnaHAEc3RpbWUDMTIzNzM0MzY2NQ--">
		Visit Your Group	      </a>
	    </div> 
	    	    	      
	    <!-- Network content -->
	    	      <div style="background-color:#EEEEEE; margin-bottom:20px; padding:10px 8px;">    <div id="nc">
              <div class="ad" style="color:#628C2A; font-family:Arial; font-weight:bold;">
                      <div id="hd1">Check out the</div> 
<p><a href="http://us.ard.yahoo.com/SIG=14hd6u3nj/M=493064.12016258.12582637.8674578/D=groups/S=1705007207:NC/Y=YAHOO/EXP=1237350865/L=/B=kjuQUUPDhE8-/J=1237343665979836/K=TYq6yTfxpPY_Uw9.nijW_A/A=5191952/R=0/SIG=112mhte3e/*http://www.ygroupsblog.com/blog/">Y! Groups blog</a></p> 
<p>Stay up to speed</p> 
<p>on all things Groups!</p>                  </div>
                    <div class="ad" style="color:#628C2A; font-family:Arial; font-weight:bold;">
                      <div id="hd1">Yahoo! Groups</div> 
<p><a href="http://us.ard.yahoo.com/SIG=14hdugr00/M=493064.12717544.13455789.8674578/D=groups/S=1705007207:NC/Y=YAHOO/EXP=1237350865/L=/B=kzuQUUPDhE8-/J=1237343665979836/K=TYq6yTfxpPY_Uw9.nijW_A/A=5658250/R=0/SIG=11ptgj47g/*http://advision.webevents.yahoo.com/autoenthusiastzone/">Auto Enthusiast Zone</a></p> 
<p>Auto Enthusiast Zone</p> 
<p>Car groups and more!</p>                  </div>
                    <div class="ad" style="color:#628C2A; font-family:Arial; font-weight:bold;">
                      <div id="hd1">Get in Shape</div> 
<p><a href="http://us.ard.yahoo.com/SIG=14iqmj6lv/M=493064.12016300.12445692.11323196/D=groups/S=1705007207:NC/Y=YAHOO/EXP=1237350865/L=/B=lDuQUUPDhE8-/J=1237343665979836/K=TYq6yTfxpPY_Uw9.nijW_A/A=5170417/R=0/SIG=11b5gu1oe/*http://new.groups.yahoo.com/specialKgroup">on Yahoo! Groups</a></p> 
<p>Find a buddy</p> 
<p>and lose weight.</p>                  </div>
          </div>
</div>
	    
	  </div> 	  <!-- |**|end egp html banner|**| -->
	  <div style="clear:both; color: #FFF; font-size:1px;">.</div>
	</div> 		  <img src="http://geo.yahoo.com/serv?s=97359714/grpId=8744704/grpspId=1705007207/msgId=1041/stime=1237343665/nc1=5191952/nc2=5658250/nc3=5170417" width="1" height="1"> <br>
	
	<div style="color: white; clear: both;">__,_._,___</div>
	<!--~-|**|PrettyHtmlEnd|**|-~-->
	</body>
	<!--~-|**|PrettyHtmlStart|**|-~-->
	<head>
<style type="text/css">
<!--
#ygrp-mkp{
  border: 1px solid #d8d8d8;
  font-family: Arial;
  margin: 14px 0px;
  padding: 0px 14px;
}
#ygrp-mkp hr{
  border: 1px solid #d8d8d8;
}
#ygrp-mkp #hd{
  color: #628c2a;
  font-size: 85%;
  font-weight: bold;
  line-height: 122%;
  margin: 10px 0px;
}
#ygrp-mkp #ads{
  margin-bottom: 10px;
}
#ygrp-mkp .ad{
  padding: 0 0;
}
#ygrp-mkp .ad a{
  color: #0000ff;
  text-decoration: none;
}
-->
</style>
</head>
	<head>
<style type="text/css">
<!--
#ygrp-sponsor #ygrp-lc{
  font-family: Arial;
}
#ygrp-sponsor #ygrp-lc #hd{
  margin: 10px 0px;
  font-weight: bold;
  font-size: 78%;
  line-height: 122%;
}
#ygrp-sponsor #ygrp-lc .ad{
  margin-bottom: 10px;
  padding: 0 0;
}
-->
</style>
</head>
	<head>
	<style type="text/css">
	<!--
	#ygrp-mlmsg {font-size:13px; font-family: arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
	#ygrp-mlmsg table {font-size:inherit;font:100%;}
	#ygrp-mlmsg select, input, textarea {font:99% arial,helvetica,clean,sans-serif;}
	#ygrp-mlmsg pre, code {font:115% monospace;*font-size:100%;}
	#ygrp-mlmsg * {line-height:1.22em;}
	#ygrp-text{
	    font-family: Georgia;	
	}
	#ygrp-text p{
	    margin: 0 0 1em 0;
	}

	dd.last p a {
          font-family: Verdana;
          font-weight: bold;
	}

	#ygrp-vitnav{
		padding-top: 10px;
		font-family: Verdana;
		font-size: 77%;
		margin: 0;
	}
	#ygrp-vitnav a{
		padding: 0 1px;
	}
	#ygrp-mlmsg #logo{
	  padding-bottom: 10px;
	}

	#ygrp-reco {
	margin-bottom: 20px;
	padding: 0px;
	}
	#ygrp-reco #reco-head {
		font-weight: bold;
		color: #ff7900;
	}

	#reco-category{
        	font-size: 77%;
	}
	#reco-desc{
        	font-size: 77%;
	}

	#ygrp-vital a{
		text-decoration: none;
	}

	#ygrp-vital a:hover{
	  text-decoration: underline;
	}

	#ygrp-sponsor #ov ul{
		padding: 0 0 0 8px;
		margin: 0;
	}
	#ygrp-sponsor #ov li{
		list-style-type: square;
		padding: 6px 0;
		font-size: 77%;
	}
	#ygrp-sponsor #ov li a{
		text-decoration: none;
		font-size: 130%;
	}
	#ygrp-sponsor #nc{
	  background-color: #eee;
	  margin-bottom: 20px;
	  padding: 0 8px;
	}
	#ygrp-sponsor .ad{
		padding: 8px 0;
	}
	#ygrp-sponsor .ad #hd1{
		font-family: Arial;
		font-weight: bold;
		color: #628c2a;
		font-size: 100%;
		line-height: 122%;
	}
	#ygrp-sponsor .ad a{
		text-decoration: none;
	}
	#ygrp-sponsor .ad a:hover{
		text-decoration: underline;
	}
	#ygrp-sponsor .ad p{
		margin: 0;
	}
	o{font-size: 0; }
	.MsoNormal{
	   margin: 0 0 0 0;
	}
	#ygrp-text tt{
	  font-size: 120%;
	}
	blockquote{margin: 0 0 0 4px;}
	.replbq{margin:4}

dd.last p span {
  margin-right: 10px;
  font-family: Verdana;
  font-weight: bold;
}

dd.last p span.yshortcuts {
  margin-right: 0;
}

div.photo-title a,
div.photo-title a:active,
div.photo-title a:hover,
div.photo-title a:visited {
    text-decoration: none;
}

div.file-title a,
div.file-title a:active,
div.file-title a:hover,
div.file-title a:visited {
    text-decoration: none;
}

#ygrp-msg p {
    clear: both;
    padding: 15px 0 3px 0;
    overflow: hidden;
}

#ygrp-msg p span {
    color: #1E66AE;
    font-weight: bold;
}

div#ygrp-mlmsg #ygrp-msg p a span.yshortcuts {
    font-family: Verdana;
    font-size: 10px;
    font-weight: normal;
}

#ygrp-msg p a {
    font-family: Verdana;
    font-size: 10px;
}

#ygrp-mlmsg a {
    color: #1E66AE;
}

div.attach-table div div a {
    text-decoration: none;
}

div.attach-table {
    width: 400px;
}

	-->
	</style>
	</head>
	<!--~-|**|PrettyHtmlEnd|**|-~-->
	</html><!--End group email -->


--3V3TIiUe3Aj1ul16UtgVPvlYpRj3rNrl8Kf9Z2b--