<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.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>tyPouypOblOg : Tag tdd, everything about tdd</title>
    <link>http://www.typouype.org/tag/tdd.rss</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Libre, Ruby, Objet, OpenBSD, Programmation</description>
    <item>
      <title>TDD C'est quoi ? (En ruby bien sur !) </title>
      <description>&lt;p&gt;&lt;em&gt;Voici un petit billet d&amp;#8217;initiation au D&#233;veloppement pilot&#233; par les Test (dit &lt;span class="caps"&gt;TDD&lt;/span&gt; pour Test Driven Development) avec Ruby. Initialiement publi&#233; sur le site de l&amp;#8217;association &lt;a href="http://rubyfrance.org"&gt;RubyFrance&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Imaginons que nous ayons besoin d&amp;#8217;un petit objet nous permettant d&amp;#8217;afficher un nom. En bon d&#233;veloppeur, nous allons d&amp;#8217;abord &#233;crire notre test.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;require &amp;quot;test/unit&amp;quot;

class TestMonObjet &amp;lt; Test::Unit::TestCase
  def test_attribut
    monObjet = MonObjet.new(&amp;quot;un titre&amp;quot;)
    assert_equal &amp;quot;un titre&amp;quot;, monObjet.nom
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Executons le test:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb
Loaded suite testMonObjet
Started
E
Finished in 0.001079 seconds.

  1) Error:
test_attribut(MonObjetTest):
NameError: uninitialized constant MonObjetTest::MonObjet
    testMonObjet.rb:6:in `test_attribut'

1 tests, 0 assertions, 0 failures, 1 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Mince une erreur. Vous allez me dire, c&amp;#8217;&#233;tait couru d&amp;#8217;avance, on a encore rien cod&#233;. Bien. Allons-y alors. D&amp;#8217;abord nous allons ajouter le fichier contenant l&amp;#8217;objet que nous allons cr&#233;er.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;require &amp;quot;monobjet.rb&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Ensuite cr&#233;ons ce fichier:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ cat monobjet.rb
class MonObjet
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Cela suffira largement pour empecher l&amp;#8217;erreur pr&#233;cedente. C&amp;#8217;est un point important dans l&amp;#8217;univers &lt;span class="caps"&gt;TDD&lt;/span&gt;. Il ne faut rien faire de plus que ce que les tests nous demande. Cela rejoint &#233;galement un autre concept: &lt;span class="caps"&gt;YAGNI&lt;/span&gt; (You Ain&amp;#8217;t Gonna Need It).&lt;/p&gt;


	&lt;p&gt;Executons encore ce test:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb
Loaded suite testMonObjet
Started
E
Finished in 0.00193 seconds.

  1) Error:
test_attribut(MonObjetTest):
ArgumentError: wrong number of arguments (1 for 0)
    testMonObjet.rb:7:in `initialize'
    testMonObjet.rb:7:in `new'
    testMonObjet.rb:7:in `test_attribut'

1 tests, 0 assertions, 0 failures, 1 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Hmm, encore une erreur, mais cette fois ce sont les param&#232;tres de notre objet qui pose probl&#232;me. Bien, corrigeons notre objet.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ cat monobjet.rb
class MonObjet
  def initialize un_nom
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Executons encore ce test:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb  
Loaded suite testMonObjet
Started
E
Finished in 0.001091 seconds.

  1) Error:
test_attribut(MonObjetTest):
NoMethodError: undefined method `nom' for #&amp;lt;MonObjet:0x80e4d100&amp;gt;
    testMonObjet.rb:8:in `test_attribut'

1 tests, 0 assertions, 0 failures, 1 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Encore une erreur. Mais cette fois c&amp;#8217;est la method nom qui est manquante pour MonObjet. Ajoutons la:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ cat monobjet.rb
class MonObjet
  def initialize un_nom
  end
  def nom
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Executons le test (oui, en tdd, on passe notre temps &#224; tester ! :-)):&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb  
Loaded suite testMonObjet
Started
F
Finished in 0.198677 seconds.

  1) Failure:
test_attribut(MonObjetTest) [testMonObjet.rb:8]:
&amp;lt;&amp;quot;un titre&amp;quot;&amp;gt; expected but was
&amp;lt;nil&amp;gt;.

1 tests, 1 assertions, 1 failures, 0 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Voil&#224; qui deviens interessant. Cette fois, ce n&amp;#8217;est pas une erreur, c&amp;#8217;est un echec du test. La m&#233;thode &amp;#8220;nom&amp;#8221; ne renvoi pas la bonne valeur. 
La situation d&amp;#8217;echec dans le test unitaire est aussi appel&#233; &amp;#8220;la barre rouge&amp;#8221;. Et quand il y a une barre rouge, le principe est de la faire redevenir verte le plus rapidement possible (en ajoutant tr&#232;s peu de code voir en enlevant du code).&lt;/p&gt;


	&lt;p&gt;Modifions donc rapidement notre code pour r&#233;pondre au besoin du test:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ cat monobjet.rb
class MonObjet
  def initialize un_nom
  end
  def nom
    &amp;quot;un titre&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Doucement, doucement, je vous vois venir, oui j&amp;#8217;ai mis une valeur en dur, executons le test (c&amp;#8217;est barre rouge), nous en parlons juste apr&#232;s.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb  
Loaded suite testMonObjet
Started
.
Finished in 0.000902 seconds.

1 tests, 1 assertions, 0 failures, 0 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Voil&#224;, le test passe. Nous pouvons maintenant parler. J&amp;#8217;ai mis une valeur en dur dans la m&#233;thode &amp;#8220;nom&amp;#8221;, cela vous d&#233;range ? Et bien pas moi. Je r&#233;pond ici au besoin exprim&#233; dans le test. Mais je n&amp;#8217;ai pas dit que nous allions nous arreter l&#224; ! Ajoutons un test pour bien pr&#233;ciser notre besoin.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;require &amp;quot;test/unit&amp;quot;

class TestMonObjet &amp;lt; Test::Unit::TestCase
  def test_attribut
    monObjet = MonObjet.new(&amp;quot;un titre&amp;quot;)
    assert_equal &amp;quot;un titre&amp;quot;, monObjet.nom
  end
  def test_attribut_autre
    monObjet = MonObjet.new(&amp;quot;un autre titre&amp;quot;)
    assert_equal &amp;quot;un autre titre&amp;quot;, monObjet.nom
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Executons le test unitaire maintenant enrichi d&amp;#8217;un test.&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb  
Loaded suite testMonObjet
Started
.F
Finished in 0.024359 seconds.

  1) Failure:
test_attribut_autre(MonObjetTest) [testMonObjet.rb:12]:
&amp;lt;&amp;quot;un autre titre&amp;quot;&amp;gt; expected but was
&amp;lt;&amp;quot;un titre&amp;quot;&amp;gt;.

2 tests, 2 assertions, 1 failures, 0 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Forcement, avec une valeur en dur, cela ne vas pas. Faisons passer la barre au vert avant de discuter:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ cat monobjet.rb
class MonObjet
  def initialize un_nom
    @nom = un_nom
  end
  def nom
    @nom
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Executons le test:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb  
Loaded suite testMonObjet
Started
..
Finished in 0.001734 seconds.

2 tests, 2 assertions, 0 failures, 0 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Parfait ! Barre verte !&lt;/p&gt;


	&lt;p&gt;Bien, maintenant, on peut laisser &#233;taler nos connaissance en ruby pour effectuer un petit refactoring:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ cat monobjet.rb
class MonObjet
  attr_reader :nom
  def initialize un_nom
    @nom = un_nom
  end
end&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Executons le test a nouveau pour &#234;tre sur que ce refactoring n&amp;#8217;a pas chang&#233; la donne:&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;rubyFrance:~ $ ruby testMonObjet.rb  
Loaded suite testMonObjet
Started
..
Finished in 0.001734 seconds.

2 tests, 2 assertions, 0 failures, 0 errors&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Un des inter&#234;t de faire un d&#233;veloppement pilot&#233; par les tests c&amp;#8217;est de tendre une sorte de filet de s&#233;curit&#233; permettant de donn&#233;e plus de courage, ou au moins de tranquillit&#233; pour effectuer le refactoring. Mais il existe bien d&amp;#8217;autre avantage &#224; ce mode de d&#233;veloppement. Notamment celui de ne pas faire plus que n&#233;cessaire.&lt;/p&gt;


	&lt;p&gt;Les tests ainsi &#233;crit, modifi&#233;, mis &#224; jour permette de disposer &#224; tout moment d&amp;#8217;une documentation sur l&amp;#8217;execution du programme.&lt;/p&gt;</description>
      <pubDate>Sun, 28 Sep 2008 19:14:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:38bbeb2c-b2ea-4207-b07d-cc7cc1821e94</guid>
      <comments>http://www.typouype.org/2008/09/28/tdd-c-est-quoi#comments</comments>
      <category>Ruby</category>
      <category>tdd</category>
      <category>test</category>
      <category>agiles</category>
      <category>Code</category>
      <link>http://www.typouype.org/2008/09/28/tdd-c-est-quoi</link>
    </item>
    <item>
      <title>Dojo</title>
      <description>&lt;p&gt;Lundi soir, comme apparemment presque tout les lundi soir, c&amp;#8217;est rendez-vous au &lt;strong&gt;dojo&lt;/strong&gt;. Non pas celui des arts martiaux, mais celui du d&#233;veloppement. Pour rester &lt;strong&gt;agiles&lt;/strong&gt;, l&amp;#8217;association &lt;a href="http://xp-france.org"&gt;XP-France&lt;/a&gt; organise des rencontres au dojo.&lt;/p&gt;


	&lt;p&gt;Dans une salle gentillement fourni par &lt;a href="http://www.epiconcept.com"&gt;EpiConcept&lt;/a&gt;, des praticiens agiles se retrouvent pour un Kata voir un Randori.&lt;/p&gt;


	&lt;p&gt;J&amp;#8217;ai pass&#233; une super soir&#233;e. J&amp;#8217;ai d&#233;couvert &lt;a href="http://www.haskell.org/"&gt;Haskell&lt;/a&gt; un langage fonctionnel pur (c&amp;#8217;est a pr&#233;ciser apparemment ;-)). J&amp;#8217;ai vu des tests, et encore des tests et c&amp;#8217;est beau. Vivement le prochain !&lt;/p&gt;


	&lt;p&gt;Si vous voulez en savoir plus: Voir &lt;a href="http://xp-france.net/cgi-bin/wiki.pl?LeProjetDuDojo"&gt;le projet Dojo&lt;/a&gt; sur le wiki de l&amp;#8217;asso.&lt;/p&gt;


	&lt;p&gt;Moi je vais tenter d&amp;#8217;y aller tout les lundi :-D&lt;/p&gt;</description>
      <pubDate>Tue, 22 Apr 2008 22:15:00 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:28808fd9-c52c-40e1-8be1-a645e3fd3792</guid>
      <comments>http://www.typouype.org/2008/04/22/dojo#comments</comments>
      <category>agiles</category>
      <category>dojo</category>
      <category>haskell</category>
      <category>tdd</category>
      <category>XP</category>
      <category>xpfrance</category>
      <category>test</category>
      <link>http://www.typouype.org/2008/04/22/dojo</link>
    </item>
  </channel>
</rss>
