<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/stylesheets/rss.css" type="text/css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Tom Moertel's Weblog: Tag lectrotest</title>
    <link>http://blog.moertel.com/articles/tag/lectrotest?tag=lectrotest</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Quality rants on programming theory and stuff geeks like</description>
    <item>
      <title>Mini-review of CafePress's direct-printed t-shirts</title>
      <description>&lt;p&gt;As you may recall &lt;a href="http://blog.moertel.com/articles/2006/06/27/lectrotest-new-release-new-talk-and-the-new-lectrotest-emporium"&gt;from a previous
post&lt;/a&gt;,
I set up a &lt;a href="http://www.cafepress.com/"&gt;CafePress&lt;/a&gt; store to
&lt;a href="http://www.cafepress.com/lectrotest"&gt;sell LectroTest Robot&amp;#8211;branded stuff&lt;/a&gt; such as t-shirts, hats, mouse
pads, magnets, and so on.  CafePress does a good job of making their
products appear to be of the highest quality, but I am naturally
skeptical about such claims.&lt;/p&gt;


	&lt;p&gt;In particular, I wondered about their t-shirts.
The results of their heat-transfer printing process &amp;#8211; previously the
only option &amp;#8211; did not make me happy.  Images with transparent
areas revealed the transfer background, which over time yellowed
and made the image seem to float on a sea of urine.&lt;/p&gt;


	&lt;p&gt;So when I set up &lt;a href="http://www.cafepress.com/lectrotest"&gt;The LectroTest
Emporium&lt;/a&gt;, I specified the use of
CafePress&amp;#8217;s newer &amp;#8220;direct-printing&amp;#8221; process for t-shirts, hats, and
every other product for which it was offered.  Still, I wondered about
the quality.&lt;/p&gt;


	&lt;p&gt;So I ordered up a LectroTest Robot t-shirt and put it to the test.&lt;/p&gt;


	&lt;h3&gt; Test one: the eyeball and the scanner&lt;/h3&gt;


	&lt;p&gt;When the t-shirt arrived, my initial impression was that it
looked pretty darn good.  The Robot came out perfectly, and even the
pointy parts of the LectroTest lightning rendered without problems.
The colors were true, if a little less saturated than I would have
preferred.&lt;/p&gt;


	&lt;p&gt;Compared to silkscreen, the direct-printing process seems to produce
results that are a bit less saturated and a bit less crisp.  It&amp;#8217;s like
an airbrush artist rendered the Robot onto a billboard-sized shirt
that was carefully shrunken to normal size.&lt;/p&gt;


	&lt;p&gt;Next, I threw the t-shirt on a flatbed scanner.  The results are
below.  The first image is an overall view of the Robot logo.  The
second is a 300-dpi close-up of the lettering, where you can see the
air-brush effect.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://community.moertel.com/~thor/pix/20060705/lectro-shirt-before-wash-small.jpg" title="LectroTest Robot on CafePress white t-shirt" alt="LectroTest Robot on CafePress white t-shirt" /&gt;&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://community.moertel.com/~thor/pix/20060705/lectro-shirt-before-wash-300dpi.jpg" title="Close-up of LectroTest Robot on CafePress white t-shirt" alt="Close-up of LectroTest Robot on CafePress white t-shirt" /&gt;&lt;/p&gt;


	&lt;h3&gt; Test two: the iron&lt;/h3&gt;


	&lt;p&gt;To check for color offsetting, I turned the shirt inside out and
ironed it on a full-steam, cotton setting.  Throughout the ironing,
the face of the front-side image was pressed into the white cotton of
the back side of the shirt.  Nevertheless, none of the ink migrated.
The pure white remained pure white.&lt;/p&gt;


	&lt;h3&gt; Test three: the washer&lt;/h3&gt;


	&lt;p&gt;For the final test, I washed the shirt on a normal warm/cold cycle
with a small load of other clothes.  I then dried the clothing on a
medium cycle.  (CafePress recommends washing in cold water and drying on
low, but nobody pampers their t-shirts like that, and so I tested under
more typical conditions.)&lt;/p&gt;


	&lt;p&gt;When I took the shirt from the dryer, I didn&amp;#8217;t see any signs of
shrinkage or fading.  To double-check, I ironed the shirt and threw it
back on the flatbed scanner.&lt;/p&gt;


	&lt;p&gt;Doing a before-and-after comparison of the
scans in &lt;a href="http://www.gimp.org/"&gt;the Gimp&lt;/a&gt;, I was able to see some
shrinkage and fading (see image below).  Top to bottom, the shirt
shrank by about 4.5 percent; left to right, the shirt actually &lt;em&gt;grew&lt;/em&gt;
by about 1.8 percent.  Minor fading was apparent, especially in the
solid black areas.  Neither the shrinkage nor the fading were
concerning, however; both are typical for t-shirts, especially on the
initial washing.  The bottom line is that the shirt&amp;#8217;s coolness
was untarnished.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://community.moertel.com/~thor/pix/20060705/lectro-shirt-before-and-after-wash-small.jpg" title="T-shirt before and after its first wash cycle" alt="T-shirt before and after its first wash cycle" /&gt;&lt;/p&gt;


	&lt;h3&gt;Summary&lt;/h3&gt;


	&lt;p&gt;It&amp;#8217;s a good t-shirt.  It looked cool out of the box and fully captured
the metallic fierceness of the beloved LectroTest Robot.  The shirt
handled a hot-steam ironing without any ink offsetting.  It shrank and
faded a bit on its initial wash, but neither change detracted
meaningfully from the shirt.  In sum, CafePress&amp;#8217;s direct-printed
t-shirts seem like the real deal: they look good and stand up to
typical wear and washing.&lt;/p&gt;</description>
      <pubDate>Wed, 05 Jul 2006 23:48:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:036b99a85e6847d8401d5769858970f3</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/07/05/mini-review-of-cafepresss-direct-printed-t-shirts</link>
      <category>reviews</category>
      <category>perl</category>
      <category>marketing</category>
      <category>lectrotest</category>
      <category>cafepress</category>
      <category>t</category>
      <category>shirts</category>
      <category>reviews</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/75</trackback:ping>
    </item>
    <item>
      <title>LectroTest: new release, new talk, and the new LectroTest Emporium!</title>
      <description>&lt;div class="centered"&gt;
&lt;img src="http://community.moertel.com/ss/space/LectroTest/LectroTestLogoSmall.png" title="LectroTest Robot" alt="LectroTest Robot" /&gt;
&lt;/div&gt;

	&lt;p&gt;I have a bunch of &lt;a href="http://community.moertel.com/LectroTest"&gt;LectroTest&lt;/a&gt; news.  LectroTest, as you may know, is a specification-based,
automatic testing system for Perl.  It may look like Haskell&amp;#8217;s &lt;a href="http://www.cs.chalmers.se/~rjmh/QuickCheck/"&gt;QuickCheck&lt;/a&gt;, but it tastes like sweet, sweet Perl.&lt;/p&gt;


	&lt;h3&gt;LectroTest 0.3500 was released&lt;/h3&gt;


	&lt;p&gt;This version adds automatic tools for recording and playing back
failures.  Using them, you can automatically build regression-testing
suites and incorporate them into your testing plan.  All it takes
is one new line of code:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;use Test::LectroTest
    regressions =&amp;gt; "regressions.txt";   # &amp;lt;-- that's it!
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;See the &lt;a href="http://search.cpan.org/dist/Test-LectroTest/"&gt;docs on &lt;span class="caps"&gt;CPAN&lt;/span&gt;&lt;/a&gt; for more.&lt;/p&gt;


	&lt;p&gt;My thanks to Steffen Müller, who suggested the feature and is already
using it in cool stuff such as &lt;a href="http://search.cpan.org/dist/Number-WithError/"&gt;Number::WithError&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;Slides from &amp;#8220;Testing Tips with LectroTest&amp;#8221; are now online&lt;/h3&gt;


	&lt;p&gt;You can get the slides from my talk to the Pittsburgh Perl Mongers on
2006-06-14 here: &lt;a href="http://community.moertel.com/ss/space/Talks/Testing+Tips+with+LectroTest"&gt;Talk / Testing Tips with
LectroTest&lt;/a&gt;.
In the talk, I covered some of the newer LectroTest features, such as
regression testing and Test::LectroTest::Compat, which lets you mix
LectroTest with other Perl testing modules.&lt;/p&gt;


	&lt;h3&gt;The LectroTest Emporium opens!&lt;/h3&gt;


	&lt;p&gt;I have very little artistic ability.  Nevertheless, alarming numbers
of people seem to love the fiercely metallic mascot I created for
LectroTest.&lt;/p&gt;


	&lt;p&gt;At the last Perl Mongers meeting, for example, people
actually told me (somewhat sternly) I should put the adorable LectroTest Robot on
t-shirts.  I am now delighted to announce that I have taken their
advice:&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Introducing: &lt;em&gt;&lt;a href="http://www.cafepress.com/lectrotest"&gt;The LectroTest Emporium&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Some important points:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Yes, it&amp;#8217;s a CafePress store&lt;/li&gt;
		&lt;li&gt;I&amp;#8217;m not making any money on these things&lt;/li&gt;
		&lt;li&gt;I&amp;#8217;m using &lt;em&gt;direct printing&lt;/em&gt;, not heat-transfer printing, so
  the Robot won&amp;#8217;t crack, feel stiff, or suffer from a yellowish
  transfer background.  (CafePress has a &lt;a href="http://www.cafepress.com/cp/info/help/help_printingprocess.aspx"&gt;comparison of the methods&lt;/a&gt; if you want the full details.)&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Some items I have moral reservations about offering:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://www.cafepress.com/lectrotest.63672177"&gt;LectroTest Robot Teddy Bear&lt;/a&gt; -
  Who would be so reckless as to allow something as fierce and as powerful
  as the LectroTest Robot to come into &lt;em&gt;direct contact&lt;/em&gt; with a defenseless, cuddly
  teddy bear?&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.cafepress.com/lectrotest.63669666"&gt;LectroTest Robot Baby Bib&lt;/a&gt; -
  Actually, this is a great idea: your infant and the Robot 
  exist in a symbiotic relationship.  When your baby gets food all over the
  bib, the Robot will consume it (using a electrochemical process not
  entirely dissimilar to our human concept of &amp;#8220;digestion&amp;#8221;).  Thus is the
  baby cleaned and the Robot fueled.  It&amp;#8217;s win-win.&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://www.cafepress.com/lectrotest.63672178"&gt;LectroTest Robot Dog T-Shirt&lt;/a&gt; -
  I am fairly certain that the immense weight of the Robot would easily
  crush any smaller animal.  This product strikes me as a very bad idea.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;&lt;a href="http://www.cafepress.com/lectrotest#apparel"&gt;The T-shirts&lt;/a&gt;, on the other hand, are the robot&amp;#8217;s meow.  Check out the
full collection at &lt;a href="http://www.cafepress.com/lectrotest"&gt;The LectroTest Emporium&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Tue, 27 Jun 2006 14:21:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:eb99eca33b05593075a39ab873549308</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2006/06/27/lectrotest-new-release-new-talk-and-the-new-lectrotest-emporium</link>
      <category>perl</category>
      <category>fun stuff</category>
      <category>testing</category>
      <category>marketing</category>
      <category>talks</category>
      <category>perl</category>
      <category>testing</category>
      <category>lectrotest</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/72</trackback:ping>
    </item>
    <item>
      <title>When worlds collide and then dance: Test::LectroTest meets Test::Builder</title>
      <description>&lt;p&gt;It seems that &lt;a href="http://community.moertel.com/ss/space/LectroTest"&gt;LectroTest&lt;/a&gt; is picking up in popularity because I am starting to get regular requests and feedback. Recently, two related requests came in regarding something that I had put off: Figuring out how to merge specification-based testing, which samples thousands of trials per property check, with case-based testing, which  runs one trial per case.&lt;/p&gt;


	&lt;p&gt;The rub is that case-base testing in Perl is managed by &lt;a href="http://search.cpan.org/perldoc?Test::Builder"&gt;Test::Builder&lt;/a&gt; and a related family of modules that are designed to make that kind of testing easy. One convenience they offer is that calling test functions like &lt;em&gt;cmp_ok&lt;/em&gt; not only performs a test, in this case a general comparison, but also reports the result of the test to the test harness.&lt;/p&gt;


	&lt;p&gt;So what happens if somebody wants to perform a &lt;em&gt;cmp_ok&lt;/em&gt; test from within a LectroTest property specification? When the property is checked, LectroTest will test whether the property holds by sampling a thousand random trials (by default), each of which will end up calling &lt;em&gt;cmp_ok&lt;/em&gt;. Can you see where this is going? Yup, the test harness will end up seeing one thousand separate tests instead of the single test of the property.&lt;/p&gt;


	&lt;p&gt;The solution to this problem, as to all problems of distinction, is hackery. The Test::* family of modules ends up filtering all calls to test functions such as &lt;em&gt;cmp_ok&lt;/em&gt; down to the Test::Builder module&amp;#8217;s &lt;em&gt;ok&lt;/em&gt; method. This method does two things. First, it reports the result of the test to the test harness without giving us a chance to say otherwise. (Naughty!) Second, it returns the result of the test back to the original caller. As far as property checks are concerned, the first part is bad, and the second is good.&lt;/p&gt;


	&lt;p&gt;To get rid of the bad part, I redefine the &lt;em&gt;ok&lt;/em&gt; method during property checks.   I put the implementation into a new module, Test::LectroTest::Compat, that exports a single function &lt;em&gt;holds&lt;/em&gt;. This function is used to inject a property check into a plain-old Test::Simple- or Test::More-style test plan. For example, here&amp;#8217;s a test plan that uses the new module:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;use Test::More tests =&amp;gt; 2;
use Test::LectroTest::Compat;

my $prop_nonnegative = Property {
    ##[ x &amp;lt;- Int, y &amp;lt;- Int ]##
    cmp_ok(my_function( $x, $y ), '&amp;gt;=', 0);
}, name =&amp;gt; "my_function output is non-negative" ;

holds( $prop_nonnegative ); # assert that the prop holds
cmp_ok( 0, '&amp;lt;', 1, "trivial 0&amp;lt;1 test" ); # a "normal" assertion
# ... and so on ...
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;What does &lt;em&gt;holds&lt;/em&gt; do when called? It redefines Test::Builder&amp;#8217;s &lt;em&gt;ok&lt;/em&gt; method, runs the property-check trials, restores &lt;em&gt;ok&lt;/em&gt;, and finally reports the property check&amp;#8217;s result via the newly-restored &lt;em&gt;ok&lt;/em&gt;. From there, Test::Builder takes over and does the magic necessary to incorporate the result into the test session&amp;#8217;s &lt;a href="http://perldoc.perl.org/Test/Harness/TAP.html" title="Test Anything Protocol"&gt;&lt;span class="caps"&gt;TAP&lt;/span&gt;&lt;/a&gt; output.&lt;/p&gt;


	&lt;p&gt;The code that does all this is as follows:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;sub holds {
    my ($diag_store, $results) = check_property(@_);
    my $success = $results-&amp;gt;success;
    (my $name   = $results-&amp;gt;summary) =~ s/^.*?- /property /;
    $Test-&amp;gt;ok($success, $name);
    my $details = $results-&amp;gt;details;
    $details =~ s/^.*?\n//;     # remove summary line
    $details =~ s/^\# /    /mg; # replace commenting w/ indent
    $Test-&amp;gt;diag(@$diag_store) if @$diag_store;
    $Test-&amp;gt;diag($details) if $details;
    return $success;
}

sub check_property {
    no strict 'refs';
    no warnings;
    my $diag_store = [];
    my $property = shift;
    local *Test::Builder::ok = \&amp;#38;disconnected_ok;
    local *Test::Builder::diag = sub { shift; push @$diag_store, @_ };
    return ( $diag_store, 
             Test::LectroTest::TestRunner-&amp;gt;new(@_)-&amp;gt;run($property) );
}

sub disconnected_ok { $_[1] ? 1 : 0 }
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;You can see that there is one extra bit of hackery going on. I also redefine Test::Builder&amp;#8217;s &lt;em&gt;diag&lt;/em&gt; method to capture any diagnostic output that may be emitted during the trials. Typically, this occurs only when a trial fails, and in that case the output is almost certainly worth passing back to the user in context. To ensure that the user sees it in context, I hold on to the captured output until the property check is complete and then roll it into the normal LectroTest diagnostic output. It looks great:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;not ok 3 - property 'x is a natural number' falsified in 2 attempts
#     Failed test (t/compat.t at line 32)
#     '0'
#         &amp;gt;
#     '0'
#     Counterexample:
#     $x = 0;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;In the first part you see the typical &lt;em&gt;cmp_ok&lt;/em&gt; output that the assertion 0 &amp;gt; 0 failed. The second part is the LectroTest counterexample that shows at what part of the test space the assertion failed.&lt;/p&gt;


	&lt;p&gt;It takes some complicated footwork, but the resulting dance is beautiful. To see two markedly different testing systems &amp;#8211; and in some ways markedly different testing philosophies &amp;#8211; working in step with one another is gratifying. I suspect that most real-world testing problems can be solved better by a combination of the two approaches than by either alone. Thus I am especially happy about this integration.&lt;/p&gt;


	&lt;p&gt;After some more refinement, I am going to incorporate Test::LectroTest::Compat into the main distribution. For now, you can get a copy in the &lt;a href="http://community.moertel.com/ss/space/LectroTest/FAQs"&gt;LectroTest/FAQs&lt;/a&gt; section of the &lt;a href="http://community.moertel.com/"&gt;Community Projects site&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Tue, 08 Feb 2005 12:00:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:08b12d2a0fdce3d861ee958238ebef60</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2005/02/08/when-worlds-collide-and-then-dance-test-lectrotest-meets-test-builder</link>
      <category>perl</category>
      <category>testing</category>
      <category>perl</category>
      <category>testing</category>
      <category>lectrotest</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/39</trackback:ping>
    </item>
    <item>
      <title>LectroTest: An automatic, specification-based testing tool for Perl</title>
      <description>&lt;p&gt;Just a quick note to mention &lt;a href="http://community.moertel.com/ss/space/LectroTest"&gt;LectroTest&lt;/a&gt;, a Perl project I have been working on recently. It&amp;#8217;s inspired by &lt;a href="http://community.moertel.com/ss/space/QuickCheck"&gt;QuickCheck&lt;/a&gt; for the &lt;a href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; programming language. The motivation is that traditional unit testing requires programmers to spell out each and every case to test, which seems like an awful lot of work, much of which probably isn&amp;#8217;t necessary. Even so, the payoff of unit testing is real, and we ought to do it. Thus the goal becomes to reduce the pain while keeping the gain.&lt;/p&gt;


	&lt;p&gt;Rather than working at the level of individual test cases, why not tell the computer about the shape of the &amp;#8220;test space&amp;#8221; and let the computer generate the cases automatically? That&amp;#8217;s what LectroTest does. You declare properties and assert that they hold over a certain test space. LectroTest then generates random cases from within the space and tests your assertion for each. If LectroTest is able to &amp;#8220;break&amp;#8221; whatever you&amp;#8217;re testing, it emits a counterexample that you can feed back into your code to debug the error. (Counterexamples also make for nice regression tests.)&lt;/p&gt;


	&lt;p&gt;If you write code in Perl and want another option for testing your code, give &lt;a href="http://community.moertel.com/ss/space/LectroTest"&gt;LectroTest&lt;/a&gt; a look.&lt;/p&gt;


&lt;div style="text-align: center"&gt;
&lt;img src="http://community.moertel.com/ss/space/LectroTest/LectroTestLogoSmall.png" title="LectroTest logo robot" alt="LectroTest logo robot" /&gt;
&lt;/div&gt;</description>
      <pubDate>Fri, 10 Sep 2004 12:00:00 -0400</pubDate>
      <guid isPermaLink="false">urn:uuid:13b7918fe8d5b63a37e6f7ccae9193f2</guid>
      <author>Tom Moertel</author>
      <link>http://blog.moertel.com/articles/2004/09/10/lectrotest-an-automatic-specification-based-testing-tool-for-perl</link>
      <category>programming</category>
      <category>perl</category>
      <category>testing</category>
      <category>perl</category>
      <category>testing</category>
      <category>lectrotest</category>
      <trackback:ping>http://blog.moertel.com/articles/trackback/29</trackback:ping>
    </item>
  </channel>
</rss>
