<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	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/"
		>
<channel>
	<title>Comments on: Defining unit tests</title>
	<atom:link href="http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/feed/" rel="self" type="application/rss+xml" />
	<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/</link>
	<description>Strong opinions, weakly held</description>
	<lastBuildDate>Thu, 23 May 2013 23:40:00 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.2</generator>
	<item>
		<title>By: ntcoding</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2798</link>
		<dc:creator>ntcoding</dc:creator>
		<pubDate>Fri, 14 Jan 2011 23:16:57 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2798</guid>
		<description>Jimmy,

I&#039;m loving your exploration of testing and I am on the journey with you. But how about chucking the odd example in here and there?

Judging by your comments, people seem to be drawing their own conclusions. I myself wonder how your theory translates to practical application.

And finally thanks for writing these intriguing posts.</description>
		<content:encoded><![CDATA[<p>Jimmy,</p>
<p>I&#8217;m loving your exploration of testing and I am on the journey with you. But how about chucking the odd example in here and there?</p>
<p>Judging by your comments, people seem to be drawing their own conclusions. I myself wonder how your theory translates to practical application.</p>
<p>And finally thanks for writing these intriguing posts.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Thuan</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2797</link>
		<dc:creator>Thuan</dc:creator>
		<pubDate>Fri, 14 Jan 2011 09:56:13 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2797</guid>
		<description>Regarding Michael Feathers&#039; definition, a colleague of mine said that it is too strict. He proposed a slightly change to it: A test is not a unit test if the SUT:
  - Talks to...
  - Communicates...

In other words, it will be acceptable, for example, to read a file to prepare data for a test case.
What do you think?</description>
		<content:encoded><![CDATA[<p>Regarding Michael Feathers&#8217; definition, a colleague of mine said that it is too strict. He proposed a slightly change to it: A test is not a unit test if the SUT:<br />
  &#8211; Talks to&#8230;<br />
  &#8211; Communicates&#8230;</p>
<p>In other words, it will be acceptable, for example, to read a file to prepare data for a test case.<br />
What do you think?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chris B</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2796</link>
		<dc:creator>Chris B</dc:creator>
		<pubDate>Thu, 13 Jan 2011 17:21:39 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2796</guid>
		<description>After pondering on it overnight, I realized that my definition of a unit test may cause the seams of the application to become visible at every level of abstraction above the seam.  It seems that it would be ideal if seams were only visible at the next higher level of abstraction.

For example, suppose you have Widgets that are read/written through an IWidgetRepository, and you also have a WidgetProcessor that does some sort of magical processing on the widgets.  Suppose your SUT exists at the same abstraction level as the WidgetProcessor and that it uses the WidgetProcessor. How would the SUT know what IWidgetRepository implementation to use to instantiate the WidgetProcessor?

If the SUT accepts an IWidgetRepository as a dependency, the seam has bubbled up to another level of abstraction. Now all objects that use the SUT must somehow resolve an IWidgetRepository implementation. The SUT&#039;s dependence on IWidgetRepository is only indirect, it only serves to allow the instantiation of the WidgetProcessor.

On the other hand, if the SUT accepts an IWidgetProcessor as a dependency, an artificial seam has been created in the application. This seam adds a small degree of abstraction by hiding the WidgetProcessor&#039;s dependencies, and some independence by letting you mock/stub the widget processor, but it isn&#039;t much. The IWidgetProcessor will probably only have one implementation, and exists only for the purposes of registering WidgetProcessor in the DI container.  I think this is a contributing factor to &quot;mocks everywhere&quot; and &quot;interfaces for everything&quot;, and can result in the types of tests which you mentioned previously.

There are also other solutions, like Service Locator and Factory patterns, but these are very similar to accepting the dependency as an argument. How is the factory or locator resolved? Do I have to write one for every environment (UT vs production)?

I&#039;m not really sure how to modify the definition so as to prevent this, or if there is a definition that would do so.  I do think that this is one of the biggest problems and areas of confusion when it comes to defining a UT strategy.  Maybe someday I&#039;ll have some sort of epiphany on how to solve it.</description>
		<content:encoded><![CDATA[<p>After pondering on it overnight, I realized that my definition of a unit test may cause the seams of the application to become visible at every level of abstraction above the seam.  It seems that it would be ideal if seams were only visible at the next higher level of abstraction.</p>
<p>For example, suppose you have Widgets that are read/written through an IWidgetRepository, and you also have a WidgetProcessor that does some sort of magical processing on the widgets.  Suppose your SUT exists at the same abstraction level as the WidgetProcessor and that it uses the WidgetProcessor. How would the SUT know what IWidgetRepository implementation to use to instantiate the WidgetProcessor?</p>
<p>If the SUT accepts an IWidgetRepository as a dependency, the seam has bubbled up to another level of abstraction. Now all objects that use the SUT must somehow resolve an IWidgetRepository implementation. The SUT&#8217;s dependence on IWidgetRepository is only indirect, it only serves to allow the instantiation of the WidgetProcessor.</p>
<p>On the other hand, if the SUT accepts an IWidgetProcessor as a dependency, an artificial seam has been created in the application. This seam adds a small degree of abstraction by hiding the WidgetProcessor&#8217;s dependencies, and some independence by letting you mock/stub the widget processor, but it isn&#8217;t much. The IWidgetProcessor will probably only have one implementation, and exists only for the purposes of registering WidgetProcessor in the DI container.  I think this is a contributing factor to &#8220;mocks everywhere&#8221; and &#8220;interfaces for everything&#8221;, and can result in the types of tests which you mentioned previously.</p>
<p>There are also other solutions, like Service Locator and Factory patterns, but these are very similar to accepting the dependency as an argument. How is the factory or locator resolved? Do I have to write one for every environment (UT vs production)?</p>
<p>I&#8217;m not really sure how to modify the definition so as to prevent this, or if there is a definition that would do so.  I do think that this is one of the biggest problems and areas of confusion when it comes to defining a UT strategy.  Maybe someday I&#8217;ll have some sort of epiphany on how to solve it.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Josh1</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2795</link>
		<dc:creator>Josh1</dc:creator>
		<pubDate>Wed, 12 Jan 2011 22:40:35 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2795</guid>
		<description>That definition given by Michael Feathers is the same one he uses in his book Working Effectively with Legacy Code (highly recommended by myself). In it he also states this about unit tests:

1. They run fast.
2. They help localise problems.

He goes on to say that a unit test that takes 1/10 sec to run is a SLOW unit test. The slower the tests, the less likely is it that a developer is going to keep running them. Which defeats the purpose.

Reducing the &quot;integration&quot; scope of a unit test from several classes to a few or a single class will speed up these tests. You can also see that DB or network access will totally kill the speed (and reduce localisation of problems).

I think his point about speed is very crucial.</description>
		<content:encoded><![CDATA[<p>That definition given by Michael Feathers is the same one he uses in his book Working Effectively with Legacy Code (highly recommended by myself). In it he also states this about unit tests:</p>
<p>1. They run fast.<br />
2. They help localise problems.</p>
<p>He goes on to say that a unit test that takes 1/10 sec to run is a SLOW unit test. The slower the tests, the less likely is it that a developer is going to keep running them. Which defeats the purpose.</p>
<p>Reducing the &#8220;integration&#8221; scope of a unit test from several classes to a few or a single class will speed up these tests. You can also see that DB or network access will totally kill the speed (and reduce localisation of problems).</p>
<p>I think his point about speed is very crucial.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: aNt</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2794</link>
		<dc:creator>aNt</dc:creator>
		<pubDate>Wed, 12 Jan 2011 22:26:03 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2794</guid>
		<description>I was introduced to &quot;The Way Of Testivus&quot; ( http://www.agitar.com/downloads/TheWayOfTestivus.pdf ) as part of last year&#039;s GTAC.

Write the test that needs to be written.</description>
		<content:encoded><![CDATA[<p>I was introduced to &#8220;The Way Of Testivus&#8221; ( <a href="http://www.agitar.com/downloads/TheWayOfTestivus.pdf" rel="nofollow">http://www.agitar.com/downloads/TheWayOfTestivus.pdf</a> ) as part of last year&#8217;s GTAC.</p>
<p>Write the test that needs to be written.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: bogardj</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2793</link>
		<dc:creator>bogardj</dc:creator>
		<pubDate>Wed, 12 Jan 2011 21:31:40 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2793</guid>
		<description>@Chris

That might be my favorite definition - things like a repository crosses a stream, which I&#039;d want to stub most of the time in a unit test.  But peer objects, objects of the same abstraction, I&#039;d want the real-deals in play.</description>
		<content:encoded><![CDATA[<p>@Chris</p>
<p>That might be my favorite definition &#8211; things like a repository crosses a stream, which I&#8217;d want to stub most of the time in a unit test.  But peer objects, objects of the same abstraction, I&#8217;d want the real-deals in play.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ben Scott</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2792</link>
		<dc:creator>Ben Scott</dc:creator>
		<pubDate>Wed, 12 Jan 2011 21:12:31 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2792</guid>
		<description>I don&#039;t think the point of @mfeathers post (or @bogardj&#039;s analysis) is that we shouldn&#039;t write the integration (as in data layer, network, fs) tests at all. The point was that these (slow) integration tests should be separated into another test harness, leaving the faster unit tests. Getting fussed about calling them &#039;integration tests&#039; vs &#039;unit tests&#039; is just semantics.

This doesn&#039;t require duplication of tests or mocking data access in unit tests.

Say we had two methods to test. &quot;CalculateCartCheckoutPrice&quot; is a complex calculation using a number of domain objects, and doesn&#039;t do any data access. &quot;SaveCartContentsToDatabase&quot; mainly does data access (saving the domain objects to a database) and not much logic.

&quot;CalculateCartCheckoutPrice&quot; tests would be considered unit tests, but &quot;SaveCartContentsToDatabase&quot; tests would be integration tests. The integration tests are then mainly testing the design of the database (tables, stored procedures) and data interface. The unit tests are separately testing the logic, and are where you want faster iterations of tests.</description>
		<content:encoded><![CDATA[<p>I don&#8217;t think the point of @mfeathers post (or @bogardj&#8217;s analysis) is that we shouldn&#8217;t write the integration (as in data layer, network, fs) tests at all. The point was that these (slow) integration tests should be separated into another test harness, leaving the faster unit tests. Getting fussed about calling them &#8216;integration tests&#8217; vs &#8216;unit tests&#8217; is just semantics.</p>
<p>This doesn&#8217;t require duplication of tests or mocking data access in unit tests.</p>
<p>Say we had two methods to test. &#8220;CalculateCartCheckoutPrice&#8221; is a complex calculation using a number of domain objects, and doesn&#8217;t do any data access. &#8220;SaveCartContentsToDatabase&#8221; mainly does data access (saving the domain objects to a database) and not much logic.</p>
<p>&#8220;CalculateCartCheckoutPrice&#8221; tests would be considered unit tests, but &#8220;SaveCartContentsToDatabase&#8221; tests would be integration tests. The integration tests are then mainly testing the design of the database (tables, stored procedures) and data interface. The unit tests are separately testing the logic, and are where you want faster iterations of tests.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Josh</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2791</link>
		<dc:creator>Josh</dc:creator>
		<pubDate>Wed, 12 Jan 2011 19:56:32 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2791</guid>
		<description>@Pete D.

If the web service is down or broken, that at least alerts someone to the issue. 9 out of 10 times I bet the exception is something generic and has no meaning if someone looked at it. Which means you write the exception ABCCompanyWebServiceDownAfter5Retries, vs the Remote Host Down after you get tired of looking up the error or decide to throw an &quot;inconclusive&quot;. I even bet that there is 0 retry logic in 99% of the code out there. Also if you have a single if statement in a stored proc, its code. So a simple &quot;update if exists, insert if it doesn&#039;t&quot; stored proc now contains logic. So it has to be tested to make sure everything is working as expected.
</description>
		<content:encoded><![CDATA[<p>@Pete D.</p>
<p>If the web service is down or broken, that at least alerts someone to the issue. 9 out of 10 times I bet the exception is something generic and has no meaning if someone looked at it. Which means you write the exception ABCCompanyWebServiceDownAfter5Retries, vs the Remote Host Down after you get tired of looking up the error or decide to throw an &#8220;inconclusive&#8221;. I even bet that there is 0 retry logic in 99% of the code out there. Also if you have a single if statement in a stored proc, its code. So a simple &#8220;update if exists, insert if it doesn&#8217;t&#8221; stored proc now contains logic. So it has to be tested to make sure everything is working as expected.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Chris B</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2790</link>
		<dc:creator>Chris B</dc:creator>
		<pubDate>Wed, 12 Jan 2011 18:07:28 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2790</guid>
		<description>I&#039;m not sure I can completely agree with that definition of unit test either. I hope the people working on NHibernate write tests that talk to databases, and I would consider those to be &quot;true&quot; unit tests. You can easily come up with analogs for the file system and the network as well. I also find it interesting that a unit test is defined in terms of what it is not.  I can&#039;t imagine how difficult it would be to define a circle this way.....

I think the database, file system, and network could be better classified as external systems. Web services and cooperative processes seem to be notable omissions that fall into this category.  External systems are one of the areas where we usually want to introduce seams into the application so that we do not depend on the external system in order to verify ours. We introduce seams into applications so that we can achieve new levels of abstraction and independence.

My best shot at defining a unit test would be: A unit test is a test that verifies one unit of functionality at a single level of abstraction, but may specify behavior at a seam.  Once a test crosses a seam, it becomes an integration test.

A unit of functionality could be a method, class,  user story, etc.... The SUT may use objects at multiple levels of abstraction to do its job, but the test is only aware of one of them.  Mocks/stubs are allowed as stand-ins only at the seam boundary. The test&#039;s abstraction level will probably be the same abstraction level at which the SUT exists. I&#039;m not sure if that is necessary though.

I think this also speaks to the problem you mentioned in your previous post.  The tests were aware of both the desired results (high abstraction level) and the implementation details (low abstraction level) of the SUT.  If the test only used mocks/stubs at seams, refactoring would probably be easier, as long as the APIs to the seams are less likely to change.</description>
		<content:encoded><![CDATA[<p>I&#8217;m not sure I can completely agree with that definition of unit test either. I hope the people working on NHibernate write tests that talk to databases, and I would consider those to be &#8220;true&#8221; unit tests. You can easily come up with analogs for the file system and the network as well. I also find it interesting that a unit test is defined in terms of what it is not.  I can&#8217;t imagine how difficult it would be to define a circle this way&#8230;..</p>
<p>I think the database, file system, and network could be better classified as external systems. Web services and cooperative processes seem to be notable omissions that fall into this category.  External systems are one of the areas where we usually want to introduce seams into the application so that we do not depend on the external system in order to verify ours. We introduce seams into applications so that we can achieve new levels of abstraction and independence.</p>
<p>My best shot at defining a unit test would be: A unit test is a test that verifies one unit of functionality at a single level of abstraction, but may specify behavior at a seam.  Once a test crosses a seam, it becomes an integration test.</p>
<p>A unit of functionality could be a method, class,  user story, etc&#8230;. The SUT may use objects at multiple levels of abstraction to do its job, but the test is only aware of one of them.  Mocks/stubs are allowed as stand-ins only at the seam boundary. The test&#8217;s abstraction level will probably be the same abstraction level at which the SUT exists. I&#8217;m not sure if that is necessary though.</p>
<p>I think this also speaks to the problem you mentioned in your previous post.  The tests were aware of both the desired results (high abstraction level) and the implementation details (low abstraction level) of the SUT.  If the test only used mocks/stubs at seams, refactoring would probably be easier, as long as the APIs to the seams are less likely to change.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: jdn</title>
		<link>http://lostechies.com/jimmybogard/2011/01/12/defining-unit-tests/#comment-2789</link>
		<dc:creator>jdn</dc:creator>
		<pubDate>Wed, 12 Jan 2011 18:03:56 +0000</pubDate>
		<guid isPermaLink="false">/blogs/jimmy_bogard/archive/2011/01/12/defining-unit-tests.aspx#comment-2789</guid>
		<description>@Jimmy

I understand that, but it is hard to swing a dead cat and not come across similar posts with sentiments like &quot;I&#039;ve been doing TDD for three years, and most of the time, I&#039;ve been doing it wrong.&quot;

I think there&#039;s a reason for that.</description>
		<content:encoded><![CDATA[<p>@Jimmy</p>
<p>I understand that, but it is hard to swing a dead cat and not come across similar posts with sentiments like &#8220;I&#8217;ve been doing TDD for three years, and most of the time, I&#8217;ve been doing it wrong.&#8221;</p>
<p>I think there&#8217;s a reason for that.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
