tag:blogger.com,1999:blog-16256560526458994312024-03-12T19:23:55.536-07:00Zen CodingThe philosophy, the mindset, the attitude of a professional, principled, disciplined software developer.Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.comBlogger72125tag:blogger.com,1999:blog-1625656052645899431.post-47473129684814948342014-09-11T08:55:00.001-07:002014-09-11T08:55:13.365-07:00Upcoming Speaking Engagement<div class="MsoNormal">
The Binary Language of Music - Take a fascinating
journey into how our minds work and discover how binary and mathematical
patterns found in music can be used to learn the underlying language of music
theory.</div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
When: Next Wednesday, September 17, 2014 @ 6:30pm</div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
Where: Fayard Hall room 107 or 109. (not sure which
one yet)<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<br />
<div class="MsoNormal">
Goodies/Freebies: Free Food, Free Drinks, Free Prizes,
Free Jobs, Free Capitalized Words For No Reason, Free knowledge, Free
Networking.</div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
<a href="https://www.facebook.com/events/1478657642401071/" target="_blank">More Info</a></div>
Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-36272948154854953402014-09-10T05:08:00.002-07:002014-09-10T05:08:55.306-07:00Upcoming Speaking EngagementTake a fascinating journey into how our minds work and discover how binary and mathematical patterns found in music can be used to learn the underlying language of music theory.<br />
<br />
Saturday September 25th, 2014<br />
The Binary Language of Music<br />
SQL Saturday Mobile<br />
9:00am<br />
<br />
<a href="http://www.sqlsaturday.com/viewsession.aspx?sat=342&sessionid=24542" target="_blank">More Info</a>Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-80059741472011268042014-02-21T06:17:00.001-08:002014-09-10T05:04:07.353-07:00From Coder to Craftsman in 48 Hours<div class="MsoNormal">
As the lone developer working for a large engineering
company, all of my training had been OTJ. It quickly became apparent that I
needed to find better ways to design, develop, and produce high quality software.
I began to read everything I could get my hands on about software, design,
usability, databases, design patterns, testing, and architecture. I was
particularly interested in design patterns. I had read several books on the
subject (my personal favorite being <a href="http://www.barnesandnoble.com/w/head-first-design-patterns-eric-freeman/1100152615?ean=9780596007126">Head
First Design Patterns</a>), and was looking for new examples of the patterns I
had already begun putting into practice. <o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
While browsing the shelves at a Barnes and Noble in Houston,
TX, I happened upon a book called <a href="http://www.barnesandnoble.com/w/agile-principles-patterns-and-practices-in-c-robert-c-martin/1101636951?ean=9780131857254">Agile
Principles, Patterns, and Practices in C#</a> by Robert Martin. I did not
realize it at the time, but that book would forever change me as a software
developer (I read the book cover-to-cover that weekend).<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This book is filled with a library of knowledge, but is
very well edited, removing the fluff and leaving the reader with only the white
meat. It often reads like the <a href="http://en.wikipedia.org/wiki/Tao_Te_Ching">Tao Te Ching</a>, offering insight and wisdom that
must be reflected upon and internalized in small pieces before eagerly moving on. Each chapter is succinct and provides simple and
appropriate working examples that can be put to use in your own code or process
right away - but it does something more.<o:p></o:p></div>
<div class="MsoNormal">
<br /></div>
<div class="MsoNormal">
This book uses the principles as a jumping off point to
introduce deeper programming concepts (“code smells”, design pattern usage,
TDD, assembly and dependency management, and refactoring). Rather than a
comprehensive compendium of rules and dogma (although Robert Martin does
provide anecdotes and evidence to support his assertions), it provides a
blueprint for agile philosophy, and you the reader, are left to implement them
in the manner best suited for your circumstance.<o:p></o:p></div>
<div class="MsoNormal">
<br />
<div class="MsoNormal">
I was profoundly affected and influenced by the substance of
this book and did not want the knowledge to end. It validated some of my
existing beliefs, gave new perspective to older ones, and provided me
an entirely new lexicon to pull from. The principles, concepts, and ideas
enumerated in this book form the basis of our core development philosophy at <a href="http://www.envoc.com/">Envoc</a>.</div>
<div class="MsoNormal">
<br /></div>
</div>
<div class="MsoNormal">
</div>
<div class="MsoNormal">
<a href="http://www.barnesandnoble.com/w/agile-principles-patterns-and-practices-in-c-robert-c-martin/1101636951?ean=9780131857254">Agile
Principles, Patterns, and Practices in C#</a> can be purchased for about $60, and
it is worth every penny. Put in the time, effort, energy, and erudition necessary
to absorb the information contained within and you will have no choice but to become a
better developer and professional.<o:p></o:p><br />
<br /></div>
Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com1tag:blogger.com,1999:blog-1625656052645899431.post-3974994288950996612013-06-05T08:44:00.001-07:002013-06-05T08:44:26.344-07:007 Stages of Design Pattern Adoption<p>When I first read the “<a href="http://www.amazon.com/Design-Patterns-Elements-Reusable-Object-Oriented/dp/0201633612">Gang of Four</a>” book, one message in particular really hit home with me – software developers face problems, the same problems over and over again, and design patterns provide reusable solutions to those problems. And I thought “Wow! I’m a software developer. I have problems that need better solutions, bring it on!”. It wasn’t until later that the realization struck that design patterns, and their usage and adoption, are much more subtle than that.</p> <p>At the beginning of my career, I was completely unaware of design patterns or <a href="http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)">SOLID principles</a>, or even object-oriented programming. As I progressed and matured as a developer, it became obvious that I needed to find better ways to craft software. In that process I went through several stages of professional development leading to the eventual adoption and assimilation of design patterns into my coding process.</p> <p><strong>Stage 1: Denial</strong></p> <p>“Patterns? We don’t need no stinking patterns!” </p> <p>Due to ignorance, inexperience, or resistance, many developers just flat refuse to invest time in learning about patterns, SOLID design principles, or the basic building blocks of object-oriented programming. This only serves to stifle their professional growth and credibility.</p> <p><strong>Stage 2: Curiosity</strong></p> <p>“So what were those design patterns you were telling me about?” </p> <p>Eventually there comes a time when the tried and true methods of the novice developer run directly into a wall, or necessity leads them in search of new frontiers. The rot has overtaken the project and killed new development, created a maintenance nightmare, caused several to question their career decision, and accumulated a mountain of technical debt.</p> <p><strong>Stage 3: The <b>Maslow's </b>Hammer</strong></p> <p>“Get me some nails because I have a hammer, and its name is Strategy!” </p> <p>New knowledge leads to excitement but can often lead to blinders. Until we’ve had time to disassemble the information, experiment with and implement it, and put in the requisite time to internalize it, the whole world looks like it fits into the (state your pattern name here) pattern.</p> <p><strong>Stage 4: Erudition</strong></p> <p>“Strategy does not work for everything. What else you got?”</p> <p>Soon we realize that not all of our problems can be solved by, or forced to fit a single pattern. Now is the time for study. Not just study, but understanding, and for design patterns one of the most significant moments of eureka comes when you grasp the concept of intent. What is the intent of the pattern? What specific problem was identified as needing a solution and thus the pattern defined because of?</p> <p><strong>Stage 5: Restraint</strong></p> <p>“With great knowledge comes great responsibility” </p> <p>The more seasoned pattern aficionado sparingly begins to introduce patterns that meet the specific criteria of the challenge they face into the domain. SOLID becomes more of a conscious decision. Analysis of the code and design becomes a deeper and richer experience. </p> <p><strong>Stage 6: Emergence</strong></p> <p>“First you learn the instrument, then you learn the music, then you forget all that and just play” </p> <p>You have spent so much time, effort, energy, and erudition, that patterns naturally begin to find their way into your code. You still consciously recognize a Factory, Strategy, Façade, or Proxy, but it is merely an acknowledgement of its existence rather than an effort to find a place to introduce a pattern. There is a measurable change and improvement in the quality and structure of the code and the coding process. </p> <p><strong>Stage 7: Mastery</strong></p> <p>“Those who call themselves masters are not masters”</p> <p>At this level, ideas flow directly from your mind to the keyboard without hesitation, without impediment, and without fear. But the master is restless and never satisfied, always evaluating and re-evaluating where he is and how he can be better every moment. The master sees the code not in terms of methods or classes but as an organic system of maintainable order.</p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-39550010523588395092012-08-28T05:00:00.001-07:002012-08-28T05:57:03.382-07:00A Religious DiscussionHave you ever heard a DBA prattle on incessantly about the importance of the database and their apotheotic role in maintaining the space-time continuum? Me too. And while databases (and occasionally DBAs) have their place in software, I would contend it is not at the same level as the code or UI. <br />
<br />
So I am throwing down the gauntlet to all of you database gurus. I challenge you to construct a lucid, well thought out, logical argument that disproves any or all of these statements: <br />
<ul>
<li>A database is for storing and retrieving data period. </li>
<li>Business logic does not belong in the database period. </li>
<li>SQL server is not a software development platform period.</li>
</ul>
Let the conversation begin.Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com4tag:blogger.com,1999:blog-1625656052645899431.post-73023125957639706532012-02-22T07:58:00.002-08:002012-02-22T07:59:21.442-08:00Sql + RegEx = Awesome<p><strong>NOTE</strong>: This is not a post about regex (if you want more info check out <a href="http://www.regular-expressions.info/">http://www.regular-expressions.info/</a> or <a href="http://www.zytrax.com/tech/web/regex.htm">http://www.zytrax.com/tech/web/regex.htm</a> and <a href="http://gskinner.com/RegExr/">http://gskinner.com/RegExr/</a> is a great tool for testing your regular expressions).</p> <p>One of my clients called and asked me to create an auto-complete list of employee names – no problem. I cracked open the table and started looking at the data only to realize that there were names that were “not valid”, i.e., they contained invalid characters, numbers, periods, etc. When I questioned them about it, the response was “just filter those out”. Now I was ready to get to work.</p> <p>Step 1, filter out all the names that begin with a number: </p> <pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 400px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; height: 16px; font-size: 12px">SELECT<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName, LastName<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">FROM<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> dbo.Employee<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">WHERE<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '1%'<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '2%'<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '3%' <br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> ...<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '9%' </pre></pre><br />Great, now on to step 2, filter out names that begin with a dash, period, comma, or backslash:<br /><pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 400px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">SELECT<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName, LastName<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">FROM<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> dbo.Employee<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">WHERE<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '1%'<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '2%'<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '3%' <br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> ...<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '9%' <br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '-%'<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '.%'<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE ',%' <br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> AND<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '\%' </pre></pre><br />Awesome, step 3, abandon all of that and find a better way. In reality, step 2 never happened and step 1 only lasted past the first where condition. I knew there had to be a better way and it is inline RegEx, and it is good.<br /><span style="font-size: 100%; ">Let’s rewrite the above query so you can see what it looks like using RegEx:</span><br /><pre style="border-bottom: #cecece 1px solid; border-left: #cecece 1px solid; padding-bottom: 5px; background-color: #fbfbfb; min-height: 40px; padding-left: 5px; width: 400px; padding-right: 5px; overflow: auto; border-top: #cecece 1px solid; border-right: #cecece 1px solid; padding-top: 5px"><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">SELECT<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName, LastName<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">FROM<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> dbo.Employee<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px">WHERE<br /></pre><pre style="background-color: #fbfbfb; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 12px"> FirstName NOT LIKE '[0-9-\.,\\]%'</pre></pre><p>It’s that simple!</p><p>In my case, it was the best solution for filtering out data, but you could just as easily use this technique to create complex select statements too. Give it a try and enjoy!</p>Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-58074755434492014152012-01-26T07:39:00.001-08:002012-01-30T05:51:44.860-08:00Structuring Unit Tests<p>Phil Haack wrote an article entitled "<a href="http://haacked.com/archive/2012/01/02/structuring-unit-tests.aspx?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed%3A+haacked+%28you%27ve+been+HAACKED%29&utm_content=Google+Feedfetcher">Structuring Unit Tests</a>" (I highly recommend reading it) and it started us talking about how we could adopt this method of test structuring in our projects. The basic structure is a test class that contains test classes for each system under test.</p> <p>We are a test-first shop and use MSTest as our testing tool of choice. So, step 1, write some tests that follow the structure (I am just going to reproduce Phil’s example using MSTest):</p> <pre class="code">[<span style="color: #2b91af">TestClass</span>]<br /><span style="color: blue">public class </span><span style="color: #2b91af">TitleizerTests<br /></span>{<br />[<span style="color: #2b91af">TestClass</span>]<br /><span style="color: blue">public class </span><span style="color: #2b91af">TheTitleizerMethod<br /></span>{<br /> [<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue">public void </span>ReturnsDefaultTitleForNullName()<br /> {<br /> <span style="color: #ff8000">//test code<br /> </span>}<br /><br /> [<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue">public void </span>AppendsTitleToName()<br /> {<br /> <span style="color: #ff8000">//test code<br /> </span>}<br />}<br /><br />[<span style="color: #2b91af">TestClass</span>]<br /><span style="color: blue">public class </span><span style="color: #2b91af">TheKnightifyMethod<br /></span>{<br /> [<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue">public void </span>ReturnsDefaultTitleForNullName()<br /> {<br /> <span style="color: #ff8000">//test code<br /> </span>}<br /><br /> [<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue">public void </span>AppendsSirToMaleNames()<br /> {<br /> <span style="color: #ff8000">//test code<br /> </span>}<br /><br /> [<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue">public void </span>AppendsDameToFemaleNames()<br /> {<br /> <span style="color: #ff8000">//test code<br /> </span>}<br />}<br />}</pre><p>Right away we noticed two problems. When you use the keyboard shortcut Ctrl+R, C all tests in the class are run. This works great using this structure because it runs all tests in the SUT class allowing you to isolate the scope of tests to run. The problem is when you want to run all tests in the top level class. If you try Ctrl+R, C at the top level, all tests in the namespace get run. This was easily solved by creating a unique namespace for the test class to reside in:</p><p><span style="color: blue">namespace </span>TestStructure.UnitTests.TitleizerTestContainer<br />{<br />[<span style="color: #2b91af">TestClass</span>]<br /><span style="color: blue; ">public class </span><span style="color: #2b91af">TitleizerTests<br /></span>{<br /><span class="Apple-tab-span" style="white-space:pre"> </span>[<span style="color: #2b91af">TestClass</span>]<br /> <span style="color: blue"><span class="Apple-tab-span" style="white-space:pre"> </span>public class </span><span style="color: #2b91af">TheTitleizerMethod<br /> </span><span class="Apple-tab-span" style="white-space:pre"> </span>{<br /><span class="Apple-tab-span" style="white-space:pre"> </span>[<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue"><span class="Apple-tab-span" style="white-space:pre"> </span>public void </span>ReturnsDefaultTitleForNullName()<br /><span class="Apple-tab-span" style="white-space:pre"> </span>{<br /> <span style="color: #ff8000"><span class="Apple-tab-span" style="white-space:pre"> </span>//test code<br /> </span><span class="Apple-tab-span" style="white-space:pre"> </span>}<br /><br />Now we can run all tests in the class without issue.</p><p>The second problem is code duplication. If some setup is required for my class before I can perform my tests, I have to repeat it for each class because nested classes do not have access to their parent members. Our solution to this is to make all of the children inherit from the parent test class like this:</p><pre class="code">[<span style="color: #2b91af">TestClass</span>]<br /><span style="color: blue">public class </span><span style="color: #2b91af">TitleizerTests<br /></span>{<br /><span style="color: blue">protected </span><span style="color: #2b91af">Titleizer </span>target;<br /><br />[<span style="color: #2b91af">TestInitialize</span>]<br /><span style="color: blue">public void </span>Init()<br />{<br /> target = <span style="color: blue">new </span><span style="color: #2b91af">Titleizer</span>();<br />}<br /><br />[<span style="color: #2b91af">TestClass</span>]<br /><span style="color: blue">public class </span><span style="color: #2b91af">TheTitleizerMethod </span>: <span style="color: #2b91af">TitleizerTests<br /></span>{<br /> [<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue">public void </span>ReturnsDefaultTitleForNullName()<br /> {<br /> <span style="color: #ff8000">//act<br /> </span><span style="color: blue">string </span>result = target.Titleize(<span style="color: blue">null</span>);<br /><br /> <span style="color: #ff8000">//assert<br /> </span><span style="color: #2b91af">Assert</span>.AreEqual(result, <span style="color: #a31515">"Your name is now Phil the Foolish"</span>);<br /> }<br /><br /> [<span style="color: #2b91af">TestMethod</span>]<br /> <span style="color: blue">public void </span>AppendsTitleToName()<br /> {<br /> <span style="color: #ff8000">//act<br /> </span><span style="color: blue">string </span>result = target.Titleize(<span style="color: #a31515">"Brian"</span>);<br /><br /> <span style="color: #ff8000">//assert<br /> </span><span style="color: #2b91af">Assert</span>.AreEqual(result, <span style="color: #a31515">"Brian the awesome hearted"</span>);<br /> }<br />}</pre><p>This is obviously a contrived case where no actual setup is required, but now the TestInitialize method will run before each test in my child classes.</p><p>Plus the test are much easier to read:<br /><br /><a href="http://lh6.ggpht.com/-ZUbdbYIgD9o/TyFzpiVyH7I/AAAAAAAAADI/eP_61bCWSqo/s1600-h/image%25255B3%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh3.ggpht.com/-SYwNPWC8w48/TyFzp86yWEI/AAAAAAAAADM/vKf9N-WKrwQ/image_thumb%25255B1%25255D.png?imgmax=800" width="476" height="108" /></a></p><p><a href="http://lh6.ggpht.com/-vXZHJ-Gx3PA/TyFzqFQkfmI/AAAAAAAAADU/fPceRjbotmk/s1600-h/image%25255B8%25255D.png"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://lh6.ggpht.com/-WOdat3Gr2rY/TyFzqbZXS0I/AAAAAAAAADc/n9jtd0ksv3U/image_thumb%25255B4%25255D.png?imgmax=800" width="473" height="266" /></a></p>We are just stating to experiment with this test structure, but so far it looks very promising.Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com15tag:blogger.com,1999:blog-1625656052645899431.post-57700299210638409622011-08-17T05:08:00.001-07:002011-08-17T05:08:21.030-07:00Decisions, decisions<p>As developers, we are constantly making decisions about how to implement a feature, a business rule, a data schema, etc. Sometimes we even find ourselves questioning the decisions of others. For example, have you ever been visiting a website, or using a mobile application and asked yourself “why did the developer choose to do it that way?”</p> <p>Last night, I stumbled upon an article that describes how some of the decisions made at the language level affect us as developers, and their cost impact on businesses. The choice of the C language to use NULL terminated strings may be the most expensive mistake in the history of programming!</p> <p>Enjoy.</p> <p>Warning: this really is for the geekiest among you.</p> <p><a href="http://queue.acm.org/detail.cfm?id=2010365">http://queue.acm.org/detail.cfm?id=2010365</a></p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-58371695540484373632011-08-02T04:39:00.001-07:002011-08-02T05:28:24.878-07:00Upcoming Speaking Engagement<p>Come join the largest free tech conference in Louisiana – there are already over 500 registrations! Come by and get your day started off with my Zen Coding session.</p> <p>Saturday August 5th, 2011 <br /><font style="font-weight: normal">Zen Coding </font> <br /><font style="font-weight: normal">SQL Saturday Baton Rouge</font> <br /><font style="font-weight: normal">8:30-9:30pm </font> <br /><a href="http://sqlsaturday.com/64/eventhome.aspx">More Info</a><font style="font-weight: normal"></font><font style="font-weight: normal"> </font></p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-89320389106211565012011-02-02T04:31:00.001-08:002011-02-02T04:31:08.552-08:00Parking Lot Programmer<p>In this industry, we are all familiar with the term "duct tape developer". Those who throw caution to the wind, who turn their noses up at such things as design, test coverage, and the acquisition of new knowledge. Those who scoff at the notion of principles, patterns, and discipline. Those who ride their proverbial Ford F-150 full speed ahead, blindfolded, with a can of on sale malted beverage in one hand and honking the horn with the other. They leave behind a cloud of burnt fossil fuels, a mighty “YEEHAW” ringing in the minds of those within earshot, the indelible afterimage of a “git ‘er done” bumper sticker, and skid marks in the codebase. Well today I am going to simplify that image and take it out of the pickup and move it to the parking lot.</p> <p>A parking lot programmer is like a buddy who gets drunk and loses his keys in the parking lot. You go out to check on him and he's looking for the keys under a streetlight even though he knows he lost them somewhere else. So you ask him "why are you looking here?" and he looks up and says confidently "because there's more light here".</p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com1tag:blogger.com,1999:blog-1625656052645899431.post-84907755404298615162011-01-27T04:45:00.001-08:002011-01-27T04:45:17.523-08:00Upcoming Speaking Engagements<h5>Saturday January 30th, 2011 <br /><font style="font-weight: normal">Zen Coding </font> <br /><font style="font-weight: normal">SQL Saturday Houston </font> <br /><font style="font-weight: normal">11:00-12:00pm </font> <br /><a href="http://www.sqlsaturday.com/57/eventhome.aspx"><font style="font-weight: normal">More Info</font></a><font style="font-weight: normal"> </font></h5> <h5>Tuesday February 1st, 2011 <br /><font style="font-weight: normal">Tales from the Code</font> <br /><font style="font-weight: normal">11:00-12:00pm</font> <br /><font style="font-weight: normal">Fayard Hall Room 218</font> <br /><font style="font-weight: normal">Southeastern University</font> <br /><a href="http://www.selu.edu/acad_research/depts/cs_it/"><font style="font-weight: normal">More Info</font></a></h5> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com2tag:blogger.com,1999:blog-1625656052645899431.post-85422461105859065672010-12-29T05:05:00.001-08:002013-09-04T10:12:48.345-07:00TDD – But What do I Test?I am a huge proponent of <a href="http://en.wikipedia.org/wiki/Test-driven_development" target="_blank">Test Driven Development</a> (TDD) and have written blogs and given presentations on the subject. The one question that is asked most frequently is “what do I test?”. As this profession is rife with the ubiquitous and inescapable use of acronyms, I too shall add to the growing lexicon with two that help to answer the “what do I test” question - FAST and BEER.<br />
<br />
<strong>FAST </strong>FAST is not actually an answer to the question, but a setup. FAST describes what makes a good test or suite of tests. <br />
<br />
<strong>F</strong>ast – yes, the word associated with the first letter is the same and the acronym itself. Even a unit test project with thousands of tests should take no longer than a few seconds to run.<br />
<strong><br /></strong>
<strong>A</strong>tomic – unit tests should test one and only one piece of functionality or behavior. Atomic also means the test is not dependent on outside systems such as a web server or service, the file system, or a database. Those should all be represented by abstractions to support the F in FAST. We should be able to write and test our domain without a UI or data store.<br />
<strong><br /></strong>
<strong>S</strong>tatic – once a test is written, it should not change. This does not mean tests can never be refactored, but if you are practicing TDD, then you are setting up expectations of how the system should behave before writing any code. The implementation of that expectation may and probably will change, but the underlying test for the behavior should remain unchanged.<br />
<strong><br /></strong>
<strong>T</strong>horough – unit tests should test as many conditions as the system under test will face during its lifetime. Testing just a single passing case does not really exercise the code fully or completely. It may not be possible for us to test every edge case, but we can put the code through its paces and ensure its behavior, stability, effectiveness, and graceful failing.<br />
<strong><br /></strong>
<strong>BEER </strong>Now on to what needs to be tested. BEER describes a set of cases or circumstances that require reflection and attention when writing tests and designing our APIs. The B in BEER does not stands for behavior - that is just a little too vague to be instructive.<br />
<strong><br /></strong>
<strong>B</strong>oundary Conditions – a value that exceeds the maximum or minimum allowed value. If we are testing a validation rule for a string that is required and cannot be more than fifty characters, we need to write a series of tests that address each a series of conditions - a null string, a zero-length string, a string with one character, a string with a length greater than one and less than fifty, a string with fifty characters, and a string with more than fifty characters. The same would apply to numbers or dates. This follows the T in FAST.<br />
<strong><br /></strong>
<strong>E</strong>xistence – Not <a href="http://en.wikipedia.org/wiki/Cogito_ergo_sum" target="_blank">Cartesian</a> existence, but nulls and state. We often see this when testing repositories and services. Unit testing persistence requires inserting an object into the data store (represented by an abstractions such as a repository - remember the A in FAST) and retrieving it to make sure it was correctly saved. The opposite, removing an object from the data store, requires a test to assert that it was correctly deleted. This also applies to an object’s state. We want to write tests for state transitions and verify that our objects behave appropriately in each case.<br />
<strong><br /></strong>
<strong>E</strong>xceptions – although we may not be able to foresee all possible conditions, we can test for certain exception conditions and ensure they are handled gracefully. Does an object in an invalid state throw an exception? Does the exception give the user an out? Does the exception provide useful information to either the user or other developer for resolving the issue?<br />
<strong><br /></strong>
<strong>R</strong>ange Conditions – This would include things like a start date occurring before an end date or an invalid enumerator or case in a switch statement. Testing a sorting algorithm where the first element is less than the proceeding one would fall under range conditions.<br />
<strong><br /></strong>
<strong>Conclusion </strong>Unit testing is not just about one case or single event. It is about proving our code works in different environments and conditions. Is is also about <a href="http://blogs.sftsrc.com/stuart/archive/2007/05/07/23.aspx" target="_blank">falsifiability</a>. When we are writing tests, focus on the negative cases and taking a defensive coding posture. What can go wrong and how will my code react? When outside forces assert pressure on the system how will it handle them?<br />
<br />
Following these guidelines will help you achieve not just higher test coverage, but higher quality test coverage.Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com4tag:blogger.com,1999:blog-1625656052645899431.post-81651459321521209052010-12-15T05:05:00.001-08:002010-12-15T05:05:35.646-08:00What is a Professional Redux?<p>One definition might be getting paid to do something. Another might be a commitment to performing at the highest level, to give your best at all times. Yet another may be exhibiting a courteous, conscientious, and generally businesslike manner in the workplace. While all of these are partially correct, there are many facets to being a true professional.</p> <blockquote> <p>There are two parts to learning craftsmanship: knowledge and work. You must gain the knowledge of principles, patterns, practices, and heuristics that a craftsman knows, and you must also grind that knowledge into your fingers, eyes, and gut by working hard and practicing. </p> <p>It requires more than just the knowledge of principles and patterns. You must sweat over it. You must practice it yourself, and watch yourself fail. You must watch others practice it and fail. You must see them stumble and retrace their steps. You must see them agonize over decisions and see the price they pay for making those decisions the wrong way. <br />- Robert Martin, Clean Code</p> </blockquote> <p>A professional has specialized skills and knowledge that required independent erudition and effort on their part to attain. They engage in a process of constant evaluation and improvement. A professional makes decisions based on their dedication to the craft and not the current circumstance. The characteristic that separates the professional from the dilettante is an uncompromising commitment to excellence – doing what is required to get the job done at its highest level, even when it is inconvenient. An amateur is capable of doing some things well under the right conditions, but a professional, as a matter of course, does it well regardless of the situation. </p> <p>A professional is passionate, motivated, and punctual. A professional respects the respectable, but admires the inspirational. A professional is a seeker of knowledge but also a teacher. A professional is disciplined, has the highest standards, and is engaged in the constant pursuit of un-attainable perfection. A professional is restless and never satisfied, always evaluating and re-evaluating where they’ve come and finding ways to do what they are doing better now, today, moment to moment. </p> <p><span style="font-family: 'Times New Roman'; font-size: medium; -webkit-border-horizontal-spacing: 1px; -webkit-border-vertical-spacing: 1px" class="Apple-style-span"></span></p> <blockquote>I have offended God and mankind because my work did not reach the quality it should have. <br />- Leonardo da Vinci, artist, d. 1519, last words</blockquote> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-2968854885743025772010-12-08T05:28:00.001-08:002010-12-08T06:08:14.433-08:00Project Estimates, the Silent Killer<p>I have <a href="http://zendeveloper.blogspot.com/2010/01/estimate-is-not-commitment.html" target="_blank">written about estimating</a> in the past. That article discussed some of the inherent challenges of software project estimating. This time I want to focus on deliverables that are NOT code. </p> <p>When creating a project estimate, we tend to concentrate on development time while neglecting common and important tasks that require hours and should be considered when defining an estimate. These are the areas where overages tend to occur precisely because they were overlooked. <br /> <br /><em>These are just guidelines and should be modified for your specific situation. </em></p> <p><strong>Project setup</strong> <br />This includes setting up the development, QA, staging, and production environments, installing 3<sup>rd</sup> party software, getting access to client servers, VPN, remote desktop, web services etc. – minimum 8 hours.</p> <p><strong>QA time <br /></strong>This number should be provided after the project scope and business requirements have been establish and estimated. Ideally, this number would be provided by a qualified QA specialist. </p> <p><strong>Code Reviews <br /></strong>This is an invaluable step in maintaining code throughout the project - one hour per week of the project.</p> <p><strong>Meetings <br /></strong>This includes design meetings, internal and external, client meetings, phone calls, email conversations, etc. -<strong> </strong>minimum one hour per week of the project per team member working on the project.</p> <p><strong>Demos <br /></strong>You are planning on showing something to the client right? One hour per iteration.</p> <p><strong>UAT <br /></strong>Let’s not forget that we must have user acceptance testing. One hour per iteration.</p> <p><strong>Post Implementation Meeting <br /></strong>This is another invaluable tool in fine-tuning the process of constant improvement over the lifetime of the project and the developer. Half hour per iteration per team member working on the project.</p> <p><strong>Deployment <br /></strong>This includes creating a deployment and rollback plans, database update scripts, deployment to QA and staging environments during development, etc. - minimum 8 hours.</p> <p><strong>Post Implementation Client Support <br /></strong>This is support supplied to the client after a production release - minimum 2 hours.</p> <p><strong>UI/UX Design</strong> <br />If a project requires graphic design, then it requires a graphic designer – minimum 24 hours for design, CSS, html, images, etc.</p> <p>And those are just the minimum requirements. Check out this more comprehensive list from Steve McConnell’s <em><a href="http://www.amazon.com/Software-Estimation-Demystifying-Practices-Microsoft/dp/0735605351" target="_blank">Software Estimation. Demystifying the Black Art</a></em></p> <p><a href="http://lh5.ggpht.com/_HWIDpeNnZ_E/TP-REZ9A3NI/AAAAAAAAAC4/oErWF-ss3WA/s1600-h/estimatingtasks%5B4%5D.jpg" target="_blank"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="estimatingtasks" border="0" alt="estimatingtasks" src="http://lh3.ggpht.com/_HWIDpeNnZ_E/TP-REvE5ZZI/AAAAAAAAAC8/d2RCabIc3lA/estimatingtasks_thumb%5B2%5D.jpg?imgmax=800" width="172" height="244" /></a></p>Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-7531439499305476522010-12-01T05:23:00.001-08:002010-12-01T05:23:40.930-08:00Visual Layout Design Help<p>As software developers, most of us are expected to be many things to our customers and employers: an architect, estimator, tester, technical writer, project manager, diplomat, usability expert, visual/UI designer, etc.</p> <p>In an effort to pass along knowledge that may be helpful to support education in the realm of visual layout, I wanted to share <a href="http://960.gs/" target="_blank">this</a>. It is a CSS layout based on the “optimal” on-screen layout of 960 pixels. It has an HTML, CSS generator and you can download templates for more than a dozen platforms (Fireworks, Photoshop, Visio, etc.)</p> <p>You can check out more of the background details <a href="http://sonspring.com/journal/960-grid-system" target="_blank">here</a>.</p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-49637431562187058302010-11-24T04:22:00.001-08:002010-11-24T04:48:34.788-08:00Zen Testing Extension Methods<p>After my last Zen Testing presentation, numerous requests have come in to share the unit test extension methods I use. They are attached at the end of this post (this class is currently setup to use MSTest, but it can be easily adapted to use other test frameworks). </p> <p>The intent for creating these extension methods was to make for more readable assertions in my unit tests. So rather than:</p> <pre class="code"><span style="color: #ff8000">//arrange<br /></span><span style="color: blue">string </span>expected = <span style="color: #a31515">"Testing123"</span>;<br /><span style="color: #2b91af">Person </span>person = <span style="color: blue">new </span><span style="color: #2b91af">Person</span>();<br />person.Name = expected;<br /><br /><span style="color: #ff8000">//act<br /></span><span style="color: blue">string </span>result = person.Name;<br /><br /><span style="color: #ff8000">//assert<br /></span><span style="color: #2b91af">Assert</span>.AreEqual(expected, result);</pre>I wanted my assertions to read like:<br /><pre class="code"><span style="color: #ff8000">//assert<br /></span>result.ShouldBe(expected);</pre>The usage.ShouldBe(easy to follow).<br /><br />I do want to point out one special case for testing exceptions. The normal way of testing an exception and its message looks something like this:<br /><pre class="code">[<span style="color: #2b91af">TestMethod</span>]<br />[<span style="color: #2b91af">ExpectedException</span>(<span style="color: blue">typeof</span>(<span style="color: #2b91af">InvalidOperationException</span>))]<br /><span style="color: blue">public void </span>Save_InvalidPerson_ThrowsInvalidOperationException()<br />{<br /> <span style="color: #ff8000">//arrange<br /> </span><span style="color: #2b91af">PersonService </span>service = <span style="color: blue">new </span><span style="color: #2b91af">PersonService</span>();<br /><br /> <span style="color: blue">try<br /> </span>{<br /> <span style="color: #ff8000">//act<br /> </span>service.Save(<span style="color: blue">new </span><span style="color: #2b91af">Person</span>());<br /> }<br /> <span style="color: blue">catch </span>(<span style="color: #2b91af">Exception </span>exp)<br /> {<br /> <span style="color: #2b91af">Assert</span>.AreEqual(<span style="color: #a31515">"Person is invalid"</span>, exp.Message);<br /> <span style="color: blue">throw</span>;<br /> }<br />}</pre>This is a very simple example, but it is also rather verbose for what you get. Using a simple delegate reduces the amount of test code required to achieve the same result and increases the readability:<br /><pre class="code">[<span style="color: #2b91af">TestMethod</span>]<br /><span style="color: blue">public void </span>Save_InvalidPerson_ThrowsInvalidOperationException()<br />{<br /> <span style="color: #ff8000">//arrange<br /> </span><span style="color: #2b91af">PersonService </span>service = <span style="color: blue">new </span><span style="color: #2b91af">PersonService</span>();<br /><br /> <span style="color: #ff8000">//act<br /> </span><span style="color: #2b91af">Action </span>action = () => service.Save(<span style="color: blue">new </span><span style="color: #2b91af">Person</span>());<br /><br /> <span style="color: #ff8000">//assert<br /> </span>action.ShouldThrow<<span style="color: #2b91af">InvalidOperationException</span>>(<span style="color: #a31515">"Person is invalid."</span>);<br />}</pre>Just include the UnitTestExtensions class in your unit test project and take it for a spin. I hope that this will help you on the path to Zen Testing.<br /><pre class="code"><span style="color: blue">using </span>System;<br /><span style="color: blue">using </span>System.Collections.Generic;<br /><span style="color: blue">using </span>System.Linq;<br /><span style="color: blue">using </span>System.Text;<br /><span style="color: blue">using </span>Microsoft.VisualStudio.TestTools.UnitTesting;<br /><br /><span style="color: blue">namespace </span>Envoc.Core.UnitTests.Extensions<br />{<br /> <span style="color: blue">public static class </span><span style="color: #2b91af">UnitTestExtensions<br /> </span>{<br /> <span style="color: blue">public static void </span>ShouldBe<T>(<span style="color: blue">this </span>T actual, T expected)<br /> {<br /> ShouldBe(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBe<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message)<br /> {<br /> <span style="color: #2b91af">Assert</span>.AreEqual(expected, actual, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotBe<T>(<span style="color: blue">this </span>T actual, T expected)<br /> {<br /> ShouldNotBe(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotBe<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message)<br /> {<br /> <span style="color: #2b91af">Assert</span>.AreNotEqual(expected, actual, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldContain(<span style="color: blue">this string </span>actual, <span style="color: blue">string </span>expected)<br /> {<br /> ShouldContain(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldContain(<span style="color: blue">this string </span>actual, <span style="color: blue">string </span>expected, <span style="color: blue">string </span>message)<br /> {<br /> <span style="color: #2b91af">Assert</span>.IsTrue(actual.Contains(expected), message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotContain(<span style="color: blue">this string </span>actual, <span style="color: blue">string </span>expected)<br /> {<br /> ShouldNotContain(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotContain(<span style="color: blue">this string </span>actual, <span style="color: blue">string </span>expected, <span style="color: blue">string </span>message)<br /> {<br /> <span style="color: #2b91af">Assert</span>.IsFalse(actual.Contains(expected), message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeSameAs<T>(<span style="color: blue">this </span>T actual, T expected) <span style="color: blue">where </span>T : <span style="color: blue">class<br /> </span>{<br /> ShouldBeSameAs(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeSameAs<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message) <span style="color: blue">where </span>T : <span style="color: blue">class<br /> </span>{<br /> <span style="color: #2b91af">Assert</span>.AreSame(actual, expected, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotBeSameAs<T>(<span style="color: blue">this </span>T actual, T expected) <span style="color: blue">where </span>T : <span style="color: blue">class<br /> </span>{<br /> ShouldNotBeSameAs(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotBeSameAs<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message) <span style="color: blue">where </span>T : <span style="color: blue">class<br /> </span>{<br /> <span style="color: #2b91af">Assert</span>.AreNotSame(actual, expected, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeEqual<T>(<span style="color: blue">this </span>T actual, T expected)<br /> {<br /> ShouldBeEqual(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeEqual<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message)<br /> {<br /> <span style="color: #2b91af">Assert</span>.AreEqual(actual, expected, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotBeEqual<T>(<span style="color: blue">this </span>T actual, T expected)<br /> {<br /> ShouldNotBeEqual(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotBeEqual<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message)<br /> {<br /> <span style="color: #2b91af">Assert</span>.AreNotEqual(actual, expected, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeLessThan<T>(<span style="color: blue">this </span>T actual, T expected) <span style="color: blue">where </span>T : <span style="color: #2b91af">IComparable<br /> </span>{<br /> ShouldBeLessThan(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeLessThan<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message) <span style="color: blue">where </span>T : <span style="color: #2b91af">IComparable<br /> </span>{<br /> <span style="color: #2b91af">Assert</span>.IsTrue(actual.CompareTo(expected) < 0, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeGreaterThan<T>(<span style="color: blue">this </span>T actual, T expected) <span style="color: blue">where </span>T : <span style="color: #2b91af">IComparable<br /> </span>{<br /> ShouldBeGreaterThan(actual, expected, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeGreaterThan<T>(<span style="color: blue">this </span>T actual, T expected, <span style="color: blue">string </span>message) <span style="color: blue">where </span>T : <span style="color: #2b91af">IComparable<br /> </span>{<br /> <span style="color: #2b91af">Assert</span>.IsTrue(actual.CompareTo(expected) > 0, message);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldBeNull(<span style="color: blue">this object </span>value)<br /> {<br /> <span style="color: #2b91af">Assert</span>.IsNull(value);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldNotBeNull(<span style="color: blue">this object </span>value)<br /> {<br /> <span style="color: #2b91af">Assert</span>.IsNotNull(value);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldThrow<T>(<span style="color: blue">this </span><span style="color: #2b91af">Action </span>action) <span style="color: blue">where </span>T : <span style="color: #2b91af">Exception<br /> </span>{<br /> ShouldThrow<T>(action, <span style="color: blue">string</span>.Empty);<br /> }<br /><br /> <span style="color: blue">public static void </span>ShouldThrow<T>(<span style="color: blue">this </span><span style="color: #2b91af">Action </span>action, <span style="color: blue">string </span>message) <span style="color: blue">where </span>T : <span style="color: #2b91af">Exception<br /> </span>{<br /> <span style="color: blue">string </span>failMessage = <span style="color: blue">string</span>.Format(<span style="color: #a31515">"did not throw expected exception {0}."</span>, <span style="color: blue">typeof</span>(T).Name);<br /><br /> <span style="color: blue">try<br /> </span>{<br /> action();<br /> <span style="color: #2b91af">Assert</span>.Fail(failMessage);<br /> }<br /> <span style="color: blue">catch </span>(<span style="color: #2b91af">Exception </span>ex)<br /> {<br /> <span style="color: blue">if </span>(!<span style="color: blue">string</span>.IsNullOrWhiteSpace(message))<br /> {<br /> <span style="color: #2b91af">Assert</span>.AreEqual(message, ex.Message);<br /> }<br /><br /> <span style="color: #2b91af">Assert</span>.AreEqual(<span style="color: blue">typeof</span>(T), ex.GetType(), failMessage);<br /> }<br /> }<br /> }<br />}</pre>Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-6099857190914751012010-11-17T04:38:00.001-08:002010-11-17T04:38:32.372-08:00History of the World Part IV<p><a href="http://zendeveloper.blogspot.com/2010/10/history-of-world-part-i.html" target="_blank">History of the World Part I</a> - Douglas Engelbart <br /><a href="http://zendeveloper.blogspot.com/2010/11/history-of-world-part-ii.html" target="_blank">History of the World Part II</a> – Ada Lovelace <br /><a href="http://zendeveloper.blogspot.com/2010/11/history-of-world-part-iii.html" target="_blank">History of the World Part III</a> – H. Edward Roberts</p> <p>This time I want to talk about one of the most misunderstood, over-adopted methodologies in software development, and the man who inadvertently introduced us to it – Winston Royce. </p> <p>Dr. Winston W. Royce (1929–1995) was a computer scientist, director at Lockheed Software Technology Center in Austin, Texas, and the man who described the Waterfall model for software development.</p> <p>Agile, SCRUM, and XP were a response to the failures of traditional software design and development methodology commonly referred to as waterfall. How the waterfall methodology came to be used as the central software development method used by most companies is an interesting tale. In the 1970′s, the DOD (Department of Defense) was researching methods to handle software development to better report on where money and resources were being spent. A member of the team assigned to this task went to the Institute of Electrical and Electronics Engineers (IEEE), to look for articles on the subject. He found an article named “Managing the Development of Large Software Systems: Concepts and Techniques”. He opened the first diagram – a graph representing the waterfall method – titled “Implementation steps to develop a large computer program for delivery to a customer”. It was from this that the DOD established the <a href="http://www.barringer1.com/mil_files/DOD-2167.pdf" target="_blank">Military Standard 2167</a> which used the waterfall graph as a template – without actually having read the article. </p> <p>All the vendors that supported the DOD had to accept the new standard of developing software. NATO was also looking for a way to work with software and found the DOD had done a research project on the subject and they too adopted waterfall. Soon, the software industry also followed suit and before you knew it, everyone was working with this new method, called the Waterfall method.</p> <p>Had they taken the time to actually read the article, they would have found that Dr. Royce goes into detail about why the waterfall method does not work. Namely, waterfall has testing and documentation at the end of the project. It assumes that all the preceding stages are accurate. It also assumes that the estimate of work is exact. We know, however, that when the schedule starts to slip, those things at the end of the project are done hastily or dropped. What’s at the end of the project? Testing and documentation.</p> <p>For the next several decades the <a href="http://technicallead.wordpress.com/2008/08/26/some-quotes-on-waterfall/" target="_blank">DOD recorded a 60-90% failure rate</a> on software development projects. Eventually, they rescinded the Military Standard 2167. </p> <p>For the rest of his life, Dr. Royce fought to clear his name. Below is a video that nicely illustrates what happened. Enjoy.</p> <div style="padding-bottom: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; float: none; padding-top: 0px" id="scid:5737277B-5D6D-4f48-ABFC-DD9C333F4C5D:48b493d1-f2c3-42e5-82f3-80b207584664" class="wlWriterEditableSmartContent"><div id="407aae52-f5a0-4be7-87c4-87b235948a2d" style="margin: 0px; padding: 0px; display: inline;"><div><a href="http://www.youtube.com/watch?v=X1c2--sP3o0" target="_new"><img src="http://lh3.ggpht.com/_HWIDpeNnZ_E/TOPMx5QAy7I/AAAAAAAAAC0/vlO42XuROec/video825b2cc2d89b%5B24%5D.jpg?imgmax=800" style="border-style: none" galleryimg="no" onload="var downlevelDiv = document.getElementById('407aae52-f5a0-4be7-87c4-87b235948a2d'); downlevelDiv.innerHTML = "<div><object width=\"480\" height=\"385\"><param name=\"movie\" value=\"http://www.youtube.com/v/X1c2--sP3o0?hl=en&hd=1\"><\/param><embed src=\"http://www.youtube.com/v/X1c2--sP3o0?hl=en&hd=1\" type=\"application/x-shockwave-flash\" width=\"480\" height=\"385\"><\/embed><\/object><\/div>";" alt=""></a></div></div><div style="width:480px;clear:both;font-size:.8em">Waterfail</div></div> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com2tag:blogger.com,1999:blog-1625656052645899431.post-4080125250957040082010-11-16T05:35:00.001-08:002010-11-16T05:35:12.767-08:00Upcoming Speaking EngagementsSELU Department of Computer Science and Industrial Technology  <br />Tales from the Code  <br />3:30-4:30pm <br />Fayard Hall Room 218 <br />Southeastern University Campus Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com2tag:blogger.com,1999:blog-1625656052645899431.post-41324948106506130712010-11-10T04:13:00.001-08:002010-11-10T04:13:36.038-08:00History of the World Part III<p><a href="http://zendeveloper.blogspot.com/2010/10/history-of-world-part-i.html" target="_blank">History of the World Part I</a> - Douglas Engelbart <br /><a href="http://zendeveloper.blogspot.com/2010/11/history-of-world-part-ii.html" target="_blank">History of the World Part II</a> – Ada Lovelace</p> <p>Today we honor Henry Edward "Ed" Roberts (September 13, 1941 – April 1, 2010), commonly referred to as "the father of the personal computer". He co-founded <a href="http://en.wikipedia.org/wiki/Micro_Instrumentation_and_Telemetry_Systems">Micro Instrumentation and Telemetry Systems</a> (MITS) in Albuquerque in 1969 and served as its president. The company made and sold rocket kits and then calculators, but their true contribution was the <a href="http://en.wikipedia.org/wiki/Altair_8800">Altair 8800</a> personal computer that used the new <a href="http://en.wikipedia.org/wiki/Intel_8080">Intel 8080</a> microprocessor. <a href="http://lh4.ggpht.com/_HWIDpeNnZ_E/TNqMalsX4MI/AAAAAAAAACs/S92d2jjdCys/s1600-h/popular-electronics-january-19756.jpg"><img style="background-image: none; border-right-width: 0px; margin: 9px 15px 0px 0px; padding-left: 0px; padding-right: 0px; display: inline; float: left; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="popular-electronics-january-1975" border="0" alt="popular-electronics-january-1975" align="left" src="http://lh5.ggpht.com/_HWIDpeNnZ_E/TNqMb2m_V5I/AAAAAAAAACw/mo5cUGrynJE/popular-electronics-january-1975_thu.jpg?imgmax=800" width="184" height="244" /></a>It was featured on the cover of the January 1975 issue of <i>Popular Electronics</i>, and hobbyists flooded MITS with orders for this $397 computer kit. It so inspired <a href="http://en.wikipedia.org/wiki/Bill_Gates">Bill Gates</a> and <a href="http://en.wikipedia.org/wiki/Paul_Allen">Paul Allen</a> that they moved to Albuquerque and joined MITS to develop software and <a href="http://en.wikipedia.org/wiki/Altair_BASIC">Altair BASIC</a>, <a href="http://en.wikipedia.org/wiki/Microsoft">Microsoft's</a> first product. Roberts sold MITS in 1977 and retired to Georgia where he farmed, studied medicine, and eventually became a small-town doctor. He died on April 1, 2010 of pneumonia, but the effect of his contribution to our industry cannot be measured.</p> <p>He may not have invented the PC, but he surely invented the PC industry<em>.</em></p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-13372992030837433202010-11-08T10:33:00.001-08:002010-11-08T10:33:37.666-08:00Upcoming Speaking EngagementsSELU Department of Computer Science and Industrial Technology <br />Zen Coding <br />12:00-1:00pm <br />Fayard Hall Room 205 <br />Southeastern University Campus <br /><a href="http://www.selu.edu/acad_research/depts/cs_it/">More Info</a> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-3819308643786235532010-11-03T04:42:00.001-07:002010-11-03T04:42:01.856-07:00History of the World Part II<p>In the <a href="http://zendeveloper.blogspot.com/2010/10/history-of-world-part-i.html" target="_blank">first article</a> of this series, we talked about why learning about our history as developers is an important endeavor, and introduced Douglas Engelbart.</p> <p>This time we will talk about the person attributed with the distinction of being the first software developer, Ada Lovelace.<img style="margin: 8px 17px 5px 0px; display: inline; float: left" align="left" src="http://t3.gstatic.com/images?q=tbn:EHFX4bXgFxTkZM:http://learn.gcus.net/file.php/368/Team_Names/ada.jpeg&t=1" width="136" height="183" /></p> <p>Ada Lovelace wrote a paper in 1843 that anticipated the development of computer software, artificial intelligence, and computer music. Daughter of the poet <a href="http://en.wikipedia.org/wiki/Lord_Byron" target="_blank">Lord Byron</a>, Ada Lovelace was known as the "enchantress of numbers" who collaborated with <a href="http://inventors.about.com/library/inventors/blCharlesBabbage.htm">Charles Babbage</a>, the inventor of the first mechanical thinking/calculating machine.</p> <p>At the age of 17, Ada was introduced to <a href="http://en.wikipedia.org/wiki/Mary_Somerville" target="_blank">Mary Somerville</a>. It was at a dinner party at Mrs. Somerville's in November 1834 that Ada first heard Babbage's ideas for a new calculating machine, the Analytical Engine. What if a calculating engine could not only foresee but could act on that foresight?</p> <p>Babbage worked on plans for this new engine and reported on the developments at a seminar in Turin, Italy in the fall of 1841. <a href="http://en.wikipedia.org/wiki/Federico_Luigi,_Conte_Menabrea" target="_blank">Luigi Menabrea</a> wrote a summary of what Babbage described and published an article about the development. Ada translated Menabrea’s memoir, appending her own notes, including a method for calculating <a href="http://en.wikipedia.org/wiki/Bernoulli_number" target="_blank">Bernoulli numbers</a> with the machine – and is attributed as the first computer program. </p> <p>Understanding that computers could do a lot more than just crunch numbers, Ada suggested that the Analytical Engine “might compose elaborate and scientific pieces of music of any degree of complexity or extent”, produce graphics, and would be used for both practical and scientific use. </p> <p>She never had the chance to fully explore the possibilities of either Babbage’s inventions or her own understanding of computing. She died at age 36 on 27th November 1852 of cancer.</p> <p>Her contribution to our profession is so significant, in 1979 the U.S. Department of Defense developed a computer language named "Ada" in her honor, March 24th is recognized as “Ada Lovelace Day”, and a movie about her life called “<a href="http://www.thenod.com/blog/?p=2740" target="_blank">Enchantress of Numbers</a>” is slated for release in 2011.</p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-13616234010429471812010-10-27T04:38:00.001-07:002010-10-27T04:38:32.834-07:00Upcoming Speaking Engagements<p></p> <h5>Thursday October 28th, 2010</h5> SELU .NET User Group <br />Zen Testing <br />6:30-8:00pm <br />Fayard Hall Room 126 <br />Southeastern University Campus <br /><a href="http://www.facebook.com/event.php?eid=164163143611256">More Info</a> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-31804029854691088372010-10-20T04:26:00.001-07:002010-10-21T07:34:44.071-07:00History of the World Part I<p>As software practitioners, we are in pursuit of two things: the acquisition of skill, and the acquisition of knowledge. It is the acquisition of the latter that I want to focus on in the next series of articles – specifically history. </p> <p>Many developers are deficient in the knowledge or concern of how our profession was born and how it has evolved, or why that information matters. This is, in part, due to the fact that we live in the present, and plan for the future. But, historical perspective provides us with insight that cannot be derived from the present. Studying our history provides reason and basis for the ideas, principles, techniques, and practices that have shaped this industry and craft. It also provides the context in which these concepts were incubated, developed, extended, and, in some cases, abandoned. </p> <p>In this installment, I would like to introduce you to Douglas Engelbart. He, among other things, invented one of the most ubiquitous computer peripherals, the mouse. He and his team also introduced the world to hypertext and computer networking. Among his other contributions are: collaborative hypermedia, knowledge management, community networking, and organizational transformation, display editing, windows, cross-file editing, outline processing, hypermedia, and groupware. <a href="http://www.thocp.net/biographies/engelbart_douglas.html" target="_blank">Mr. Engelbart’s biography</a> is truly impressive, inspirational, and worth taking a few minutes to read.</p> <p>On December 9, 1968, at the Fall Joint Computer Conference (FJCC) in San Francisco, he demonstrated the first computer mouse, as well as interactive text, video conferencing, teleconferencing, email, hypertext and a collaborative real-time editor. This demonstration has been posthumously named "The Mother of all Demos". The original 100-minute video of this event is part of the Engelbart Collection in Special Collections of Stanford University and can be viewed <a href="http://sloan.stanford.edu/mousesite/1968Demo.html" target="_blank">here</a>. Enjoy.</p>Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com2tag:blogger.com,1999:blog-1625656052645899431.post-67561163609842853082010-10-13T04:50:00.001-07:002010-10-13T04:50:12.553-07:00The Myth of User Error<p>Have you ever had the “sounds like user error” knee-jerk response without taking the time to find the real cause of the problem? Have you ever heard a colleague do likewise? The concept of user error is so prevalent, we have created our own set of slang - “Problem exists between keyboard and chair”, “Problem in chair not in computer”, “<a href="http://en.wikipedia.org/wiki/ID-Ten-T_Error">ID-10T error</a>”, etc. But is the user really to blame? I say the answer is no.</p> <p>I once inherited a codebase where all lookup lists were implemented as <a href="http://en.wikipedia.org/wiki/Singleton_pattern">Singletons</a>. When the administrator went to add a new lookup value, it never showed up in the web form that displayed the list, so she re-booted her machine and then it “magically” appeared the next time she fired up the application. She blamed herself for the issue. She figured it was something she had done wrong, not that it was in fact an issue with the code.</p> <p>Every problem a user encounters while using your application was created by you, the developer. You allowed it to happen. You put the user in a position to, or gave them the opportunity to fail. Whether it be from a lack of ability, QA, testing, or education, domain ignorance, laziness, or just a simple oversight, you are to blame. If you do get burnt, do not take it personally. Take responsibility and view it as an opportunity to learn and grow as a professional.</p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0tag:blogger.com,1999:blog-1625656052645899431.post-42679138914976568472010-10-06T04:30:00.001-07:002010-10-06T04:30:56.360-07:00Upcoming Speaking Engagements<h5>Saturday October 9th, 2010</h5> <p>Houston TechFest  <br />Zen Coding <br />12:00-1:15pm <br />University of Houston Campus </p> <p><a href="http://www.houstontechfest.com/dotnetnuke/default.aspx">More Info</a></p> Brian Rigsbyhttp://www.blogger.com/profile/09217041706921143546noreply@blogger.com0