<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged properties</title>
    <link href="https://passingcuriosity.com/tags/properties/properties.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/properties/properties.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2015-12-29T00:00:00Z</updated>
    <entry>
    <title>Some ScalaCheck generators fail too much</title>
    <link href="https://passingcuriosity.com/2015/scalacheck-discarded-tests/" />
    <id>https://passingcuriosity.com/2015/scalacheck-discarded-tests/</id>
    <published>2015-12-29T00:00:00Z</published>
    <updated>2015-12-29T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Most of the code I’ll be working with in my new job (BTW blog: I have
a new job) is written in <a href="http://www.scala-lang.org/">Scala</a> and uses property based testing
with <a href="https://scalacheck.org/">ScalaCheck</a>. Yesterday I ran into a problem with an existing
test suite that suddenly began failing with too many discarded tests:</p>
<pre><code>[info] FormattersSpec
[info]   Formatters are invertible for:
[info]     + Mapping
[info]     + Identifier
[info]
[error]     x Metadata
[error]  Gave up after only 39 passed tests. 197 tests were discarded. (FormattersSpec.scala:11)</code></pre>
<p>This test generates random <code>Metadata</code> values and makes sure that they
can be serialised and deserialised correctly (i.e. values can be
round-tripped). The property being test here is identical, only the
<code>Arbitrary</code>, <code>Serialise</code>, and <code>Deserialise</code> instances vary in each
case. The truly odd thing is that the pertinent code looks like this:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="kw">class</span> <span class="fu">Identifier</span><span class="op">(</span>name<span class="op">:</span> <span class="ex">String</span><span class="op">)</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="cf">case</span> <span class="kw">class</span> <span class="fu">Metadata</span> <span class="op">(</span>id<span class="op">:</span> Identifier<span class="op">,</span> maps<span class="op">:</span> <span class="ex">Set</span><span class="op">[</span>Identifier<span class="op">])</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">val</span> ArbIdentifier <span class="op">=</span> <span class="fu">Arbitrary</span><span class="op">(</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">{</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>    name  <span class="op">&lt;-</span> arbitrary<span class="op">[</span><span class="ex">String</span><span class="op">]</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">yield</span> <span class="fu">Identifier</span><span class="op">(</span>name<span class="op">)</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">val</span> ArbMetadata <span class="op">=</span> <span class="fu">Arbitrary</span><span class="op">(</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">{</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    identifier <span class="op">&lt;-</span> arbitrary<span class="op">[</span>Identifier<span class="op">]</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a>    mappings   <span class="op">&lt;-</span> arbitrary<span class="op">[</span><span class="ex">Set</span><span class="op">[</span>Identifier<span class="op">]]</span></span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">yield</span> <span class="fu">Metadata</span><span class="op">(</span>identifier<span class="op">,</span> mappings<span class="op">)</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div>
<p>My first step was redefining a few related <code>Arbitrary</code> instances to
avoid using <code>suchThat</code> (which discards invalid values) but this didn’t
fix the problem. Eventually I tried redefining <code>ArbMetadata</code> like
this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="kw">implicit</span> <span class="kw">val</span> ArbMetadata <span class="op">=</span> <span class="fu">Arbitrary</span><span class="op">(</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>  <span class="cf">for</span> <span class="op">{</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    identifier <span class="op">&lt;-</span> arbitrary<span class="op">[</span>Identifier<span class="op">]</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    mappings   <span class="op">&lt;-</span> Gen<span class="op">.</span><span class="fu">const</span><span class="op">(</span><span class="ex">Set</span><span class="op">.</span>empty<span class="op">[</span><span class="ex">Set</span><span class="op">[</span>Identifier<span class="op">]])</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>  <span class="op">}</span> <span class="cf">yield</span> <span class="fu">Metadata</span><span class="op">(</span>identifier<span class="op">,</span> mappings<span class="op">)</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a><span class="op">)</span></span></code></pre></div>
<p>and the problem went away. Trying to use <code class="sourceCode scala">arbitrary<span class="op">[</span><span class="ex">Set</span><span class="op">[</span>Identifier<span class="op">]]</span></code>
in various ways in the Scala REPL confirmed that it is the problem; we
can easily generate as large a <code>List[Identifier]</code> as we like, but a
<code>Set[Identifier]</code> fails fairly frequently:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode scala"><code class="sourceCode scala"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="co">// This always generates a Some[List[Identifier]] value.</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>Gen<span class="op">.</span><span class="fu">listOfN</span><span class="op">(</span><span class="dv">100</span><span class="op">,</span> arbitrary<span class="op">[</span>Identifier<span class="op">]).</span><span class="fu">map</span><span class="op">(</span>_<span class="op">.</span>length<span class="op">).</span>sample</span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a><span class="co">// Sometimes we get a Some[List[Set[Identifier]]] and others None.</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a>Gen<span class="op">.</span><span class="fu">listOfN</span><span class="op">(</span><span class="dv">100</span><span class="op">,</span> arbitrary<span class="op">[</span><span class="ex">Set</span><span class="op">[</span>Identifier<span class="op">]]).</span><span class="fu">map</span><span class="op">(</span>_<span class="op">.</span>length<span class="op">).</span>sample</span></code></pre></div>
<p>It appears as though whatever mechanism is used by <code>arbitrary[Set[_]]</code>
to construct the sets, it doesn’t fails when the generator for the
value type returns duplicate elements. You can confirm this easily by
trying <code>arbitrary[Set[Unit]]</code>; any <code>Gen[Unit]</code> has no choice but to
return a the single value of type <code>Unit</code> (or to fail) and, as
expected, this almost never succeeds. Replacing the problematic
<code>arbitrary[Set[Identifier]]</code> in the original code with
<code class="sourceCode scala">arbitrary<span class="op">[</span><span class="bu">Seq</span><span class="op">[</span>Identifier<span class="op">]].</span><span class="fu">map</span><span class="op">(</span>_<span class="op">.</span>toSet<span class="op">)</span></code> resolves the issue:
constructing a set from a list of possibly duplicate <code>Identifier</code>s
always works.</p>
<p>After a bit of reading in the ScalaCheck source code it <em>seems</em> as
though the root cause of this problem is some instance of
<code class="sourceCode scala">CanBuildFrom<span class="op">[</span><span class="ex">Set</span><span class="op">[</span>_<span class="op">],</span> A<span class="op">,</span> <span class="ex">Set</span><span class="op">[</span>A<span class="op">]]</span></code> but I’ve no idea how to go
about figure out which one or why it’s broken. In any case, I now know
a bit more about working with Scala.</p>
<p>For more information, see the <a href="https://github.com/rickynils/scalacheck/issues/89">ScalaCheck issue #89</a>.</p>]]></summary>
</entry>

</feed>
