<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://msmvps.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Angel "Java" Lopez : TDD, Desarrollo Agil</title><link>http://msmvps.com/blogs/lopez/archive/tags/TDD/Desarrollo+Agil/default.aspx</link><description>Tags: TDD, Desarrollo Agil</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>TDD Kata (4): La cortadora de césped</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/20/tdd-kata-4-la-cortadora-de-c-233-sped.aspx</link><pubDate>Sat, 20 Apr 2013 17:42:46 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827888</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827888</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/20/tdd-kata-4-la-cortadora-de-c-233-sped.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Como comentaba en el anterior post, hace una semana participé de la ronda preliminar del &lt;a href="https://code.google.com/codejam"&gt;Google Code Jam&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;El ejercicio B fue el Lawnmover:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://code.google.com/codejam/contest/2270488/dashboard#s=p1" href="https://code.google.com/codejam/contest/2270488/dashboard#s=p1"&gt;https://code.google.com/codejam/contest/2270488/dashboard#s=p1&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Problem &lt;/p&gt;    &lt;p&gt;Alice and Bob have a lawn in front of their house, shaped like an N metre by M metre rectangle. Each year, they try to cut the lawn in some interesting pattern. They used to do their cutting with shears, which was very time-consuming; but now they have a new automatic lawnmower with multiple settings, and they want to try it out. &lt;/p&gt;    &lt;p&gt;The new lawnmower has a height setting - you can set it to any height h between 1 and 100 millimetres, and it will cut all the grass higher than h it encounters to height h. You run it by entering the lawn at any part of the edge of the lawn; then the lawnmower goes in a straight line, perpendicular to the edge of the lawn it entered, cutting grass in a swath 1m wide, until it exits the lawn on the other side. The lawnmower&amp;#39;s height can be set only when it is not on the lawn. &lt;/p&gt;    &lt;p&gt;Alice and Bob have a number of various patterns of grass that they could have on their lawn. For each of those, they want to know whether it&amp;#39;s possible to cut the grass into this pattern with their new lawnmower. Each pattern is described by specifying the height of the grass on each 1m x 1m square of the lawn. &lt;/p&gt;    &lt;p&gt;The grass is initially 100mm high on the whole lawn.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Lo pude solucionar, ver:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/Lawnmover"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/Lawnmover&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Como siempre, la historia, prácticamente por test:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/Lawnmover"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/Lawnmover&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Pude resolver el primer “set” pequeño de problemas que me entregó Google. No pude resolver el “set” grande, porque me equivoqué de algoritmo a seguir, y no cumplí en resolverlo en 8 minutos. Mi algoritmo inicial (pueden ver los commits) resolvía el problema partiendo de los números mayores. Lo cambié para que comenzara a resolver los números menores primero, y ahí anduvo más rápido. Un tema que aprendí: algunos problemas de Google Code Jam son difíciles de probar a mano, como no tenemos los casos de uso (entrada y salida esperada), hay que trabajar con cuidado en esos temas.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827888" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Google/default.aspx">Google</category></item><item><title>TDD Kata (3): TaTeTíTomek</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx</link><pubDate>Mon, 15 Apr 2013 10:41:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827351</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827351</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx"&gt;Anterior Post&amp;nbsp;&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/20/tdd-kata-4-la-cortadora-de-c-233-sped.aspx"&gt;Siguiente Post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;El s&amp;aacute;bado pasado estuve participando del Google Code Jam. El ejercicio A fue TicTacToeTomek:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.google.com/codejam/contest/2270488/dashboard"&gt;https://code.google.com/codejam/contest/2270488/dashboard&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;h5&gt;Problem&lt;/h5&gt;
&lt;p&gt;Tic-Tac-Toe-Tomek is a game played on a 4 x 4 square board. The board starts empty, except that a single &amp;#39;T&amp;#39; symbol may appear in one of the 16 squares. There are two players: X and O. They take turns to make moves, with X starting. In each move a player puts her symbol in one of the empty squares. Player X&amp;#39;s symbol is &amp;#39;X&amp;#39;, and player O&amp;#39;s symbol is &amp;#39;O&amp;#39;.&lt;/p&gt;
&lt;p&gt;After a player&amp;#39;s move, if there is a row, column or a diagonal containing 4 of that player&amp;#39;s symbols, or containing 3 of her symbols and the &amp;#39;T&amp;#39; symbol, she wins and the game ends. Otherwise the game continues with the other player&amp;#39;s move. If all of the fields are filled with symbols and nobody won, the game ends in a draw. See the sample input for examples of various winning positions.&lt;/p&gt;
&lt;p&gt;Given a 4 x 4 board description containing &amp;#39;X&amp;#39;, &amp;#39;O&amp;#39;, &amp;#39;T&amp;#39; and &amp;#39;.&amp;#39; characters (where &amp;#39;.&amp;#39; represents an empty square), describing the current state of a game, determine the status of the Tic-Tac-Toe-Tomek game going on. The statuses to choose from are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;X won&amp;quot; (the game is over, and X won) &lt;/li&gt;
&lt;li&gt;&amp;quot;O won&amp;quot; (the game is over, and O won) &lt;/li&gt;
&lt;li&gt;&amp;quot;Draw&amp;quot; (the game is over, and it ended in a draw) &lt;/li&gt;
&lt;li&gt;&amp;quot;Game has not completed&amp;quot; (the game is not over yet)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If there are empty cells, and the game is not over, you should output &amp;quot;Game has not completed&amp;quot;, even if the outcome of the game is inevitable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Se nos da un archivo de entrada con distintas posiciones de tablero, y tenemos que producir una salida diciendo si X gan&amp;oacute;, O gan&amp;oacute;, empate, o todav&amp;iacute;a falta completar el juego.&lt;/p&gt;
&lt;p&gt;Lo resolv&amp;iacute; usando TDD, y pueden ver el resultado en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/TicTacToeTomek"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/TicTacToeTomek&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y la historia, pr&amp;aacute;cticamente con commits por tests, en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/TicTacToeTomek"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/TicTacToeTomek&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Fue un ejercicio sencillo, y bien adaptado para TDD. Google me acept&amp;oacute; tanto la soluci&amp;oacute;n de un archivo de entrada peque&amp;ntilde;o, y de otro grande. Tengo que escribir sobre los otros ejercicios (B, C, D), que se complican por:&lt;/p&gt;
&lt;p&gt;- Hay que resolver el problema en un tiempo adecuado&lt;/p&gt;
&lt;p&gt;- El algoritmo a implementar no es evidente, o no se puede implementar &amp;ldquo;de a poco&amp;rdquo;, con &amp;ldquo;baby steps&amp;rdquo;, con lo que a veces hay grandes refactor&lt;/p&gt;
&lt;p&gt;- A veces, dada la entrada, es dif&amp;iacute;cil calcular la salida correcta, a&amp;uacute;n manualmente. Entonces, muchos de mis intentos fueron rechazados al subir el archivo soluci&amp;oacute;n a Google.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827351" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Google/default.aspx">Google</category></item><item><title>TDD Kata (2): Lenguaje Alienígena</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx</link><pubDate>Fri, 12 Apr 2013 13:03:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1827165</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1827165</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/10/tdd-kata-1-piedra-papel-tijera-lagarto-spock.aspx"&gt;Anterior Post&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/15/tdd-kata-3-tatet-237-tomek.aspx"&gt;Siguiente Post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;En la lista &lt;a href="https://groups.google.com/group/tddev-sp?hl=es&amp;amp;pli=1"&gt;TDDev en espa&amp;ntilde;ol&lt;/a&gt; se mencion&amp;oacute; hace poco el &lt;a href="https://code.google.com/codejam/"&gt;Google Code Jam&lt;/a&gt;. Uno de los &lt;a href="https://code.google.com/codejam/contests.html"&gt;pasados desaf&amp;iacute;os&lt;/a&gt; de esa competencia, es el &lt;a href="https://code.google.com/codejam/contest/90101/dashboard#s=p0"&gt;Alien Language&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;After years of study, scientists at Google Labs have discovered an alien language transmitted from a faraway planet. The alien language is very unique in that every word consists of exactly L lowercase letters. Also, there are exactly D words in this language. &lt;/p&gt;
&lt;p&gt;Once the dictionary of all the words in the alien language was built, the next breakthrough was to discover that the aliens have been transmitting messages to Earth for the past decade. Unfortunately, these signals are weakened due to the distance between our two planets and some of the words may be misinterpreted. In order to help them decipher these messages, the scientists have asked you to devise an algorithm that will determine the number of possible interpretations for a given pattern. &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A pattern consists of exactly L tokens. Each token is either a single lowercase letter (the scientists are very sure that this is the letter) or a group of unique lowercase letters surrounded by parenthesis ( and ). For example: (ab)d(dc) means the first letter is either a or b, the second letter is definitely d and the last letter is either d or c. Therefore, the pattern (ab)d(dc) can stand for either one of these 4 possibilities: add, adc, bdd, bdc.&lt;/p&gt;
&lt;p&gt;Me gust&amp;oacute; como problema. Vean en la p&amp;aacute;gina que tambi&amp;eacute;n se pide leer un archivo de entrada con las palabras y los patrones a procesar. Se pueden bajar archivos de entrada desde la p&amp;aacute;gina del problema, y se debe entregar un archivo de salida para que Google nos diga si est&amp;aacute; bien. Hoy escrib&amp;iacute; una soluci&amp;oacute;n usando TDD:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/AlienLanguage"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/AlienLanguage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pueden ver la historia de los commits, pr&amp;aacute;cticamente por test:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/AlienLanguage"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/AlienLanguage&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Una de las &amp;uacute;ltimas cosas que hice fue refactorizar, para mejorar, si fuera necesario, la detecci&amp;oacute;n de palabras que cumplen con un patr&amp;oacute;n. Podr&amp;iacute;a mejorarlo m&amp;aacute;s, por ejemplo, haciendo que en vez de tener una lista de palabras, mantener un &amp;aacute;rbol de palabras con ramas por letra, como hice en &lt;a href="https://github.com/ajlopez/SimpleBoggle"&gt;SimpleBoggle&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Al final, escrib&amp;iacute; un programa de consola que acepta un archivo de entrada y produce un archivo de salida como pide Google. Me baj&amp;eacute; un archivo grande de Google, lo proces&amp;eacute;, y la salida obtenida lo sub&amp;iacute; a Google, para que lo revise autom&amp;aacute;tica. Y di&amp;oacute; bien:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0201.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Otro triunfo de TDD ;-)&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1827165" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>TDD Kata (1): Piedra Papel Tijera Lagarto Spock</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/10/tdd-kata-1-piedra-papel-tijera-lagarto-spock.aspx</link><pubDate>Wed, 10 Apr 2013 14:43:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1826997</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1826997</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/10/tdd-kata-1-piedra-papel-tijera-lagarto-spock.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/04/12/tdd-kata-2-lenguaje-alien-237-gena.aspx"&gt;Siguiente Post&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En estos d&amp;iacute;as, le&amp;iacute; en la lista de &lt;a href="https://groups.google.com/group/tddev-sp?hl=es&amp;amp;pli=1"&gt;TDDev&lt;/a&gt; en espa&amp;ntilde;ol una &lt;a href="https://groups.google.com/group/tddev-sp/browse_thread/thread/3b1877112d2c5de2?hl=es"&gt;nueva kata&lt;/a&gt; publicada en el blog de &lt;a href="https://aprendiendotdd.wordpress.com/"&gt;Aprendiendo TDD&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aprendiendotdd.wordpress.com/2013/04/08/kata-tdd-piedra-papel-tijera-lagarto-spock/"&gt;Piedra Papel Tijera Lagarto Spock&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;basado en el problema publicado en&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.solveet.com/exercises/Kata-Piedra-Papel-Tijera-Lagarto-Spock/20" title="http://www.solveet.com/exercises/Kata-Piedra-Papel-Tijera-Lagarto-Spock/20"&gt;http://www.solveet.com/exercises/Kata-Piedra-Papel-Tijera-Lagarto-Spock/20&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tom&amp;eacute; la descripci&amp;oacute;n del art&amp;iacute;culo de la Wikipedia:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock"&gt;http://en.wikipedia.org/wiki/Rock-paper-scissors-lizard-Spock&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The rules of Rock-paper-scissors-lizard-Spock are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://en.wikipedia.org/wiki/Scissors"&gt;Scissors&lt;/a&gt; cut &lt;a href="http://en.wikipedia.org/wiki/Paper"&gt;paper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Paper covers &lt;a href="http://en.wikipedia.org/wiki/Rock_(geology)"&gt;rock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rock crushes &lt;a href="http://en.wikipedia.org/wiki/Lizard"&gt;lizard&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Lizard poisons &lt;a href="http://en.wikipedia.org/wiki/Spock"&gt;Spock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Spock smashes (or melts) scissors &lt;/li&gt;
&lt;li&gt;Scissors decapitate lizard &lt;/li&gt;
&lt;li&gt;Lizard eats paper &lt;/li&gt;
&lt;li&gt;Paper disproves Spock &lt;/li&gt;
&lt;li&gt;Spock vaporizes rock &lt;/li&gt;
&lt;li&gt;Rock breaks scissors&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Y entonces me puse a codificarla usando TDD. Pueden ver el resultado en:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/SpockGame"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/SpockGame&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;La historia, casi por tests:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/commits/master/SpockGame"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master/SpockGame&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0103.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Vean el primer test/commit: todav&amp;iacute;a no compilaba. Luego, comenz&amp;oacute; a compilar pero con estado rojo. Luego, lo pas&amp;eacute; a verde y as&amp;iacute;.&lt;/p&gt;
&lt;p&gt;Tambi&amp;eacute;n decid&amp;iacute; ter dos tests por cada combinaci&amp;oacute;n de arriba: una que prueba que Scissors cut Paper, y otra que prueba Paper is cut by Scissors&lt;/p&gt;
&lt;p&gt;El dise&amp;ntilde;o inicial fue basado en:&lt;/p&gt;
&lt;p&gt;- Tener una instancia de Game (la alternativa era tener la clase, sin instancia)&lt;/p&gt;
&lt;p&gt;- Tener una enumeraci&amp;oacute;n para las opciones de juego (Play.Scissors, etc&amp;hellip;)&lt;/p&gt;
&lt;p&gt;- Tener una enumeraci&amp;oacute;n para el resultado (PlayResult.Tie, PlayResult.FirstPlayer&amp;hellip;)&lt;/p&gt;
&lt;p&gt;En vez de tener resultado de juego, podr&amp;iacute;a haber puesto un m&amp;eacute;todo que comparara dos opciones de juego, y devolviera cu&amp;aacute;l es la que gana. Incluso hoy podr&amp;iacute;a poner este m&amp;eacute;todo como refactorizaci&amp;oacute;n. &lt;/p&gt;
&lt;p&gt;Vean la &amp;uacute;ltima refactorizaci&amp;oacute;n: podr&amp;iacute;a haber dejado el c&amp;oacute;digo de implementaci&amp;oacute;n tal como estaba, con &lt;a href="https://github.com/ajlopez/TddOnTheRocks/blob/8bbf7cdf7978a067574c4aaed250a2cb29c852f7/SpockGame/SpockGame/Game.cs"&gt;if para decidir cu&amp;aacute;ndo gana el primer jugador&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0101.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;Por esta &lt;a href="https://github.com/ajlopez/TddOnTheRocks/blob/723f9dc6c8755ab7f56a4160cf9ca6f3dabe7ec0/SpockGame/SpockGame/Game.cs"&gt;otra forma&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddkata0102.png" alt="" /&gt; &lt;/p&gt;
&lt;p&gt;sugerida por el art&amp;iacute;culo de la Wikipedia:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;One way to remember the rules is to remember the standard &amp;quot;rock-paper-scissors&amp;quot; ordering, where each gesture defeats the one before it, and is defeated by the one after. But then add the two novel gestures near the word they approximately rhyme with:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Rock &lt;/li&gt;
&lt;li&gt;Spock &lt;/li&gt;
&lt;li&gt;Paper &lt;/li&gt;
&lt;li&gt;Lizard &lt;/li&gt;
&lt;li&gt;Scissors&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In this expanded list, each gesture is defeated by the following &lt;i&gt;two&lt;/i&gt; options, and defeats the preceding two.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1826997" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>Escribiendo una Aplicación usando TDD (Part 6) Modificando Vistas</title><link>http://msmvps.com/blogs/lopez/archive/2013/04/07/escribiendo-una-aplicaci-243-n-usando-tdd-part-6-modificando-vistas.aspx</link><pubDate>Sun, 07 Apr 2013 11:33:39 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1826752</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1826752</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/04/07/escribiendo-una-aplicaci-243-n-usando-tdd-part-6-modificando-vistas.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/06/27/writing_2D00_an_2D00_application_2D00_using_2D00_tdd_2D00_part_2D00_5_2D00_adding_2D00_views.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;El post de hoy va a mostrar que, al haber usado MVC (Model-View-Controller) podemos modificar nuestras vistas, sin necesidad de tocar el código. Ni siquiera tenemos que recompilar, en muchos casos.&lt;/p&gt;  &lt;p&gt;Primero, una novedad: he pasado el ejemplo, paso a paso, a ASP.NET MVC 4, usando Visual Studio 2010. Y también lo pasé a mi cuenta de GitHub&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddAppAspNetMvc"&gt;https://github.com/ajlopez/TddAppAspNetMvc&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0501.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Vean que cada versión (cada entrega por post) está señalada por tags. La de este post es la 0.0.5. Siempre pueden ver en&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddAppAspNetMvc/commits/master"&gt;https://github.com/ajlopez/TddAppAspNetMvc/commits/master&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0504.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Una de las cosas nuevas que me dió esta versión de ASP.NET MVC es el soporte de Razor, ahora las vistas están escritas con Razor. Como en el anterior post, use los “wizard” de creación de vistas del propio Visual Studio, y luego las modifiqué un poco (apenas algun texto).&lt;/p&gt;  &lt;p&gt;En el paso de este post, lo que hice fue agregar &lt;a href="http://twitter.github.io/bootstrap/"&gt;Twitter Bootstrap&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0503.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Agregué estilos y javascript que necesita Bootstrap, y armé un _viewstart.chtml que le indica a Razor que todas las vistas usan un _Layout.cshtml&lt;/p&gt;  &lt;p&gt;Vean cómo se ve ahora la página de Subjects:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/apptdd0502.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Notablemente, no toqué nada de código ni de tests. Esto muestra que hasta se puede trabajar en paralelo, o en distintos tiempos: primero se arma el código de los controladores y acciones con tests. Luego, al mismo tiempo o en algun momento, se agregan y mejoran las vistas.&lt;/p&gt;  &lt;p&gt;Próximos posts: agregar libros, aparición de primeros servicios, modelo de negocio, etc.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1826752" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>Introducción a TDD con Visual Studio</title><link>http://msmvps.com/blogs/lopez/archive/2013/03/27/introducci-243-n-a-tdd-con-visual-studio.aspx</link><pubDate>Wed, 27 Mar 2013 10:03:55 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1825919</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1825919</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/03/27/introducci-243-n-a-tdd-con-visual-studio.aspx#comments</comments><description>&lt;p&gt;Gracias a la gente del MUG Argentina (&lt;a href="http://www.mug.org.ar"&gt;http://www.mug.org.ar&lt;/a&gt;), dí una charla de dos horas sobre cómo es TDD, con un ejemplo en Visual Studio.&lt;/p&gt;  &lt;p&gt;Desarrollamos algunos tests, cumpliendo con el ciclo rojo, verde, refactor, sobre una Factura con Productos y Cantidades. Pueden ver el código en:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas" href="https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/Ventas&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Los commits, con la evolución paso a paso, están en&lt;/p&gt;  &lt;p&gt;&lt;a title="https://github.com/ajlopez/TddOnTheRocks/commits/master" href="https://github.com/ajlopez/TddOnTheRocks/commits/master"&gt;https://github.com/ajlopez/TddOnTheRocks/commits/master&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/tddgithub01.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Mencioné algunos posts en la charla. Son &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx"&gt;mis posts sobre TDD&lt;/a&gt;, pero destaqué:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/18/escribiendo-un-int-233-rprete-en-net-parte-10.aspx"&gt;Escribiendo un intérprete en .NET (Parte 10)&lt;/a&gt; donde van a ver un caso distinto y más extenso&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/03/08/tdd-y-dise-241-o-de-implementaci-243-n-1.aspx"&gt;TDD y Diseño de Implementación (1)&lt;/a&gt; donde voy a escribir sobre cómo queda simple el diseño de implementación usando TDD y la cabeza&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/02/20/tdd-como-compilador.aspx"&gt;TDD como Compilador&lt;/a&gt; para ver cómo TDD es el compilador de estos años: nos avisa cuando algo está mal, mucho mejor que los compiladores de lenguajes tipados&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/02/18/tdd-y-base-de-datos.aspx"&gt;TDD y Base de Datos&lt;/a&gt; sobre alternativas de qué hacer cuando tenemos bases de datos en nuestros tests&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/01/31/tdd-y-baby-steps.aspx"&gt;TDD y Baby Steps&lt;/a&gt; sobre ¿cómo comerse un elefante? Pedacito a pedacito&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2013/01/22/tdd-y-el-juego-del-go.aspx"&gt;TDD y el juego del Go&lt;/a&gt; sobre “el sistema está en buena forma” a cada momento, listo para abrazar el cambio y los próximos casos de uso.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/08/09/tdd_2D00_unit_2D00_tests_2D00_and_2D00_mocks.aspx"&gt;TDD, Test Unitarios y Mocks&lt;/a&gt; sobre usar mocks solamente cuando es necesario.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/07/04/tdd-y-casos-de-uso.aspx%20"&gt;TDD y Casos de Uso&lt;/a&gt; sobre cómo ir acompañando la implementación de casos de uso con TDD. Lean el post de “Uncle Bob” &lt;a href="http://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html"&gt;No DB&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/06/27/writing_2D00_an_2D00_application_2D00_using_2D00_tdd_2D00_part_2D00_5_2D00_adding_2D00_views.aspx"&gt;Escribiendo una Aplicación usando TDD (parte 5)&lt;/a&gt;&amp;#160; sobre algunos pasos que se pueden dar con ASP.NET MVC&lt;/p&gt;  &lt;p&gt;Para los que quieran ver cómo desarrollo partiendo de los controllers, en vez que desde el dominio de negocio, ver&lt;/p&gt;  &lt;p&gt;&lt;a href="http://altnethispano.org/wiki/van-2012-06-23-desarrollando-una-aplicacion-con-tdd-desde-0.ashx"&gt;Desarrollando una aplicación con TDD desde 0&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;donde por temas de tiempo, me salteé la evolución guiada por casos de uso. Pero ahí se ve cómo van surgiendo patrones, arquitectura, reparto de responsabilidades, pero PRIMERO LOS TESTS!&lt;/p&gt;  &lt;p&gt;Para practicar, coleccioné algunos enlaces en:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://delicious.com/ajlopez/tdd+codekata" href="http://delicious.com/ajlopez/tdd+codekata"&gt;http://delicious.com/ajlopez/tdd+codekata&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Para aprender más:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://delicious.com/ajlopez/tdd+tutorial" href="https://delicious.com/ajlopez/tdd+tutorial"&gt;https://delicious.com/ajlopez/tdd+tutorial&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Para ejemplos en video:&lt;/p&gt;  &lt;p&gt;&lt;a title="https://delicious.com/ajlopez/tdd+video" href="https://delicious.com/ajlopez/tdd+video"&gt;https://delicious.com/ajlopez/tdd+video&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1825919" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Argentina/default.aspx">Argentina</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Buenos+Aires/default.aspx">Buenos Aires</category></item><item><title>Entrevista y Podcast</title><link>http://msmvps.com/blogs/lopez/archive/2013/03/23/entrevista-y-podcast.aspx</link><pubDate>Sat, 23 Mar 2013 10:47:32 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1825715</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1825715</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/03/23/entrevista-y-podcast.aspx#comments</comments><description>&lt;p&gt;Hoy paso a comentar dos entregables que se publicaron: una entrevista, y una charla como podcast.&lt;/p&gt;  &lt;p&gt;El año pasado, el bueno de &lt;a href="https://twitter.com/santiagobasulto"&gt;@santiagobasulto&lt;/a&gt; (desarrollador de software, emprendedor, programador Python, colaborador en proyectos de código abierto) tuvo la paciencia de hacerme una entrevista en persona, acá en Buenos Aires, tomándose el trabajo de viajar desde su La Plata en un día atareado. Estuvimos charlando como dos horas (en un bar histórico de la ciudad, donde se filmó la escena del billete y el mozo, de la película “Nueve Reinas”, les dejo como trabajo para el hogar averiguar cuál es). Justamente, ese bar tiene también algo que ver con la entrevista, porque he pasado por él varias veces en las décadas que llevo de programar.&lt;/p&gt;  &lt;p&gt;Santiago la pasó en limpio, la pueden leer en:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html" href="http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html"&gt;http://charliedontcode.com/entrevistas/2012/08/12/entrevista-angel-java-lopez.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Algo más de contexto, lo escribí hace algo más de cuatro años:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx" href="http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx"&gt;http://msmvps.com/blogs/lopez/archive/2008/12/31/treinta-a-241-os-en-desarrollo-de-software.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Visiten el blog de Santiago:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://charliedontcode.com/" href="http://charliedontcode.com/"&gt;http://charliedontcode.com/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Muy buena la escena de cine de donde toma el nombre (ya me imagino a &lt;a href="https://twitter.com/santiagobasulto"&gt;@santiagobasulto&lt;/a&gt; cruzándose con Robert Duvall, acá en Buenos Aires, supongo que en otro bar histórico, La Biela ;-).&lt;/p&gt;  &lt;p&gt;Y también tuve una charla, esta vez a distancia, con los buenos &lt;a href="http://twitter.com/roundcrisis"&gt;@roundcrisis&lt;/a&gt; &lt;a href="http://twitter.com/dvilchez"&gt;@dvilchez&lt;/a&gt;, publicada hoy como podcast:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.32minutos.net/?p=106" href="http://www.32minutos.net/?p=106"&gt;http://www.32minutos.net/?p=106&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ah! Pusieron una foto mía, debe ser la “clásica” ;-) (no me saco muchas fotos). Tratamos temas de desarrollo de software, algo de desarrollo ágil, insistí bastante sobre el tema TDD, también sobre generación de código como sistema experto, y “ver la luz”. Y hasta apareció algo de Anglish ;-). &lt;/p&gt;  &lt;p&gt;Vean que han producido varios podcast en:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://www.32minutos.net/" href="http://www.32minutos.net/"&gt;http://www.32minutos.net/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;como el de &lt;a href="http://www.32minutos.net/?p=85"&gt;Programación Funcional&lt;/a&gt; con el bueno de &lt;a href="http://twitter.com/martinsalias"&gt;@martinsalias&lt;/a&gt;, o el de &lt;a href="http://www.32minutos.net/?p=32"&gt;Node.js&lt;/a&gt; con &lt;a href="http://twitter.com/woloski"&gt;@woloski&lt;/a&gt;, &lt;a href="http://twitter.com/jfroma"&gt;@jfroma&lt;/a&gt; y &lt;a href="http://twitter.com/theprogrammer"&gt;@theprogrammer&lt;/a&gt;. Hace unas semanas grabamos otro podcast, esta vez con Martin, para 32 minutos, y se conversó bastante sobre agilidad. Veremos si queda publicado en estos días. Estén atentos.&lt;/p&gt;  &lt;p&gt;Les agradezco a los tres haberme permitido conversar y expresar algunas ideas, que pueden servir o no. &lt;/p&gt;  &lt;p&gt;Pero lo bueno que están haciendo, es dejar entregables consumibles. Eso es importante. Internet (y la Web en particular) está permitiendo la generación de contenido y compartirlo con todos los interesados, de una forma accesible. Pienso que es una revolución tan grande como la de Gutenberg, y los primeros libros de Manuccio.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1825715" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Historia+de+la+Computaci_26002300_243_3B00_n/default.aspx">Historia de la Computaci&amp;#243;n</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category></item><item><title>Charla de TDD con Visual Studio en Buenos Aires</title><link>http://msmvps.com/blogs/lopez/archive/2013/03/16/charla-de-tdd-con-visual-studio-en-buenos-aires.aspx</link><pubDate>Sat, 16 Mar 2013 15:35:08 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1825319</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1825319</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/03/16/charla-de-tdd-con-visual-studio-en-buenos-aires.aspx#comments</comments><description>&lt;p&gt;Gracias &lt;a href="http://www.mug.org.ar"&gt;al MUG Argentina&lt;/a&gt; podré dar en unos días una gratuita charla sobre TDD con Visual Studio:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.mug.org.ar/Eventos/3874.aspx"&gt;Introducción a TDD con Visual Studio&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Martes 26 de Marzo&lt;/p&gt;    &lt;p&gt;Lugar: Auditorio del MUG, Rivadavia 1479 1er Piso, Buenos Aires. &lt;/p&gt;    &lt;p&gt;Horario: 18:30 a 20:30 hs. &lt;/p&gt;    &lt;p&gt;Describiremos brevemente lo que es y no es Test-Driven Development, pasando luego a escribir código.      &lt;br /&gt;Armaremos un dominio simple, usando TDD, y el ciclo de: test, rojo,&amp;#160; verde, refactor. Veremos como entonces va “creciendo” nuestro código de manera orgánica, consiguiendo un diseño adecuado a lo que se necesita. &lt;/p&gt;    &lt;p&gt;Los tests nos guían en la construcción del software, siendo más que tests, especificaciones, ejemplos de uso esperado del software en construcción y hasta conseguimos ser más productivos y con código mantenible, evitando la sobre-ingeniería, y arquitecturas complicadas.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Es gratuito, pero &lt;a href="http://www.mug.org.ar/registracion.aspx?idevento=3874"&gt;hay que registrase aquí&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Ya saben que TDD es uno de mis temas favoritos. Pero ¿por qué? Porque es la disciplina de programación que pone en marco y contexto todas las demás. Si saben SOLID, patrones y “tutti li fiocci” pero no hacen TDD, será hacer lo bueno, pero no lo correcto. Será como alinear las sillas en la cubierta del Titanic ;-)&lt;/p&gt;  &lt;p&gt;No quiero aburrirlos más, ya escribí bastante en &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx"&gt;mis posts sobre TDD&lt;/a&gt;. Y cada día publico &lt;a href="https://github.com/ajlopez"&gt;código que sigue TDD en mi cuenta de GitHub&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1825319" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Argentina/default.aspx">Argentina</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Buenos+Aires/default.aspx">Buenos Aires</category></item><item><title>TDD y Diseño de Implementación (1)</title><link>http://msmvps.com/blogs/lopez/archive/2013/03/08/tdd-y-dise-241-o-de-implementaci-243-n-1.aspx</link><pubDate>Fri, 08 Mar 2013 14:19:53 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1824849</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1824849</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/03/08/tdd-y-dise-241-o-de-implementaci-243-n-1.aspx#comments</comments><description>&lt;p&gt;Sirva el post de hoy como introducción a un gran tema, que seguramente no podré comentar completamente. Es el tema de la relación entre TDD (Test-Driven Development) y diseño de implementación (no de interfaz o experiencia de usuario, digamos, diseño del código y su arquitectura).&lt;/p&gt;  &lt;p&gt;Comienzo con una pregunta:&lt;/p&gt;  &lt;p&gt;¿Qué esperamos de un sistema o aplicación?&lt;/p&gt;  &lt;p&gt;Lo primero que se me ocurre, es que funcione bien. Imaginemos que estamos usando un procesador de texto, y cuando guardamos el documento se graba nada más que la mitad y lo demás se pierde. No será lo que esperamos. A esta altura de la historia del software, esperamos que una aplicación funcione bien, sin ese tipo de problemas. Yendo más específico, debería:&lt;/p&gt;  &lt;p&gt;- Brindar la salida esperada, ante una entrada esperada&lt;/p&gt;  &lt;p&gt;- Reaccionar de forma adecuada, ante una entrada no esperada&lt;/p&gt;  &lt;p&gt;- Reaccionar de forma adecuada ante una falla en el entorno (por ejemplo, pérdida de conexión con la base de datos)&lt;/p&gt;  &lt;p&gt;Seguramente se les ocurriran más puntos de este estilo.&lt;/p&gt;  &lt;p&gt;Ahora bien, me puedo imaginar una aplicación así, y que no esté bien diseñada. Muchos de nosotros recordamos (y aún puede ser que tengamos) aplicaciones Visual Fox, o Visual Basic clásico, donde todo está escrito en el botón de aceptar. Conozco aplicaciones así, que funcionan según lo esperado. Y los clientes y usuarios están contentos.&lt;/p&gt;  &lt;p&gt;Pero muéstrenme un ejemplo de una aplicación exitosa así, y casi seguro que los creadores de ese sistema tuvieron que lidiar bastante en sacar nuevas versiones, y todavía están viendo cómo migrarlas a la web y dispositivos móviles, impulsados por lo que la gente y el mercado espera hoy.&lt;/p&gt;  &lt;p&gt;Entonces ¿qué esperamos de un buen diseño de implementación? No sé ustedes, pero yo espero que el diseño de implementación (el código, su funcionalidad interna, su distribución, su arquitectura) sea simple. ¿Por qué? Porque es la cualidad más importante para conseguir que sea mantenible.&lt;/p&gt;  &lt;p&gt;Si un sistema exitoso no necesitara cambios, no buscaríamos mantenibilidad. Pero si un sistema es exitoso, casi seguro que sobrevivirá en el tiempo, y como la realidad cambia, habrá que actualizarlo. Un contraejemplo: si conseguimos escribir un sistema que nos dé el número ganador de la próxima gran lotería en EE.UU. y de sólo esa lotería, con un grandísimo premio, el cliente final no se va a preocupar por la mantenibilidad o nos va a pedir actualizaciones. Pero en general, los sistemas y aplicaciones exitosos necesitan evolucionar.&lt;/p&gt;  &lt;p&gt;Por supuesto, podemos conseguir sistemas y aplicaciones exitosos programando sin buen diseño, por ejemplo, para llegar primeros a un mercado. Algunas de las aplicaciones Visual Fox que mencionaba antes, al salir rápidamente, consiguieron que la empresa creadora pudiera llegar primero a un nicho de mercado, y eso fue más importante que el tener un buen diseño desde el comienzo. Luego, se pudo pagar la deuda técnica en la versión 2.x con todo el ingreso y el posicionamiento que se consiguión en la versión 1.x.&lt;/p&gt;  &lt;p&gt;Entonces, volviendo a la mantenibilidad, ¿por qué pido que la implementación sea simple? Porque será entonces&lt;/p&gt;  &lt;p&gt;- más entendible para quien quiera que venga (individuo o equipo) a escribir la versión 2.0&lt;/p&gt;  &lt;p&gt;- tendrá menos piezas, y cada modificación se podrá encarar tocando pocas de esas piezas a la vez&lt;/p&gt;  &lt;p&gt;Por añadidura, una aplicación internamente simple, se verá expuesta a menos fallas de las piezas (en general) por tener menos puntos de posibles problemas en ejecución. No es lo mismo tener una aplicación que actualice una sola base de datos, que otra que tenga que actualizar 10 bases de datos distribuidas y heterogéneas.&lt;/p&gt;  &lt;p&gt;Hay quien pedirá: no, yo no quiero que el diseño sea simple, sino flexible. Acá llegamos a un punto crucial, para lo que quiero tratar y todavía no apareció: desarrollar con TDD.&lt;/p&gt;  &lt;p&gt;Bien, bastante por hoy, veré de escribir en próximos posts:&lt;/p&gt;  &lt;p&gt;- Lo simple vs lo flexible&lt;/p&gt;  &lt;p&gt;- Cómo TDD promueve lo simple&lt;/p&gt;  &lt;p&gt;- Cómo TDD nos ayuda a conseguir lo “flexible” por añadidura y sin gran esfuerzo&lt;/p&gt;  &lt;p&gt;- Cómo TDD nos da una mano para conseguir lo primero que mencioné: que la aplicación funcione como esperamos &lt;/p&gt;  &lt;p&gt;- Cómo un buen diseñador puede diseñar “mejor” con TDD, y además cómo eso beneficia a quien quiera que venga a mantener el sistema&lt;/p&gt;  &lt;p&gt;Vean que pongo “TDD promueve”, “TDD nos ayuda”, porque TDD solo no hace nada. Hay que poner cabeza. Pero desde hace unos años veo que TDD + Cabeza, nos da un sistema mejor que sólo aplicar Cabeza, es decir, sólo con nuestros conocimientos y destrezas.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1824849" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category></item><item><title>TDD como Compilador</title><link>http://msmvps.com/blogs/lopez/archive/2013/02/20/tdd-como-compilador.aspx</link><pubDate>Wed, 20 Feb 2013 17:56:01 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1824052</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1824052</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/02/20/tdd-como-compilador.aspx#comments</comments><description>&lt;p&gt;Veamos hoy un tema que pone en perspectiva ¿para qué sirve TDD? O por lo menos, trata de responder en gran parte esa pregunta.&lt;/p&gt;  &lt;p&gt;Todos conocemos lo que es programar en Java o en .NET. Escribimos el programa, posiblemente usando una IDE (Eclipse, Visual Studio.NET), y llegado el momento, compilamos. Los lenguajes .NET (VB.NET, C#, otros) y Java, son lenguajes tipados. El compilador nos dice cuándo nos equivocamos, ANTES de ejecutar nuestro programa. Por ejemplo, nos dice que nos equivocamos en el nombre de un método, o que escribimos mal el nombre de una clase, o que está mal el tipo del parámetro que tenemos que pasar a una función.&lt;/p&gt;  &lt;p&gt;Eso ha sido útil por décadas. Y entonces, es fácil confundir esa solución (detectar en compilación errores), con el problema inicial (que nuestra aplicación funcione como esperamos).&lt;/p&gt;  &lt;p&gt;Cuando pasamos a lenguajes dinámicos, como Ruby o Python o JavaScript, algunos se resienten: hey! No tenemos compilador! No podemos asegurarnos que lo que escribimos esté bien. Sólo nos damos cuenta si lo ejecutamos. Esto parece inclinar la balanza de nuestras preferencias a los lenguajes tipados con compilación.&lt;/p&gt;  &lt;p&gt;Pero no es así. Todos los compiladores del mundo NO PUEDEN ASEGURARNOS que lo que escribimos esté bien. No pueden asegurarnos, al compilar, QUE NUESTRO SOFTWARE HAGA LO QUE ESPERAMOS QUE HAGA.&lt;/p&gt;  &lt;p&gt;Veamos un ejemplo en concreto. Si tenemos un método llamado “incrementar” que recibe un entero, un compilador de Java o de .NET nos va a avisar sin lo llamamos con un nombre incorrecto, o si le estamos pasando un valor real o texto en lugar de un entero. Y eso es útil. PERO NO NOS AVISA NADA sobre si el método “incrementar” cumple con lo que esperamos de él. Bien podríamos tener en ese método código que en vez de incrementar una variable interna se dedica a formatear el disco C: o a borrar todo lo que tengamos en /usr/bin. EL COMPILADOR NO NOS SIRVE para afirmar que el método hace lo que esperamos que haga.&lt;/p&gt;  &lt;p&gt;En cambio, TDD, al escribir los tests de lo que esperamos de nuestro método “incrementar” NOS AVISA cuándo las expectativas que tenemos no se cumplen. Entonces, no hay mucha diferencia entre escribir Ruby sin compilar y sin TDD y escribir C# sin compilar y sin TDD: de las dos formas, no sabemos si lo que escribimos HACE LO QUE ESPERAMOS QUE HAGA.&lt;/p&gt;  &lt;p&gt;Es por todo eso que veo a TDD como la próxima generación de compiladores: es lo que nos asegura que lo que escribimos esté bien, NO EN SINTAXIS, sino en lo que podemos nombrar como SEMANTICA: lo que escribimos cumple con la conducta esperada.&lt;/p&gt;  &lt;p&gt;Accesorio: por eso no tomo tanto en cuenta a los que critican a Ruby, Python o JavaScript por no ser tipados y no poder detectar errores en “compilación”. Si escribimos siguiendo TDD, no importa tanto el lenguaje que usemos: cada línea de código que agregamos está respaldada por un test, y cada test es una condición que cumplir. Cuando TDD nos avise que un test está en rojo, es como cuando el compilador nos avisa “el método inkrementar no existe”. Es más: yo diría que nos das avisos más importantes que lo que nos da cualquier compilador.&lt;/p&gt;  &lt;p&gt;Escribir código de producción sin TDD, es como escribir un programa ejecutable, usando un editor hexadecimal sobre el archivo compilado: nada nos asegura que lo que estamos haciendo esté bien. Si quieren escribir código de producción sin TDD, bien, tengo unos folletos para jugar ruleta rusa, si les interesa ;-)&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1824052" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category></item><item><title>TDD y Base de Datos</title><link>http://msmvps.com/blogs/lopez/archive/2013/02/18/tdd-y-base-de-datos.aspx</link><pubDate>Mon, 18 Feb 2013 16:54:30 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1823940</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1823940</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/02/18/tdd-y-base-de-datos.aspx#comments</comments><description>&lt;p&gt;Ya he escrito bastante en mis anteriores posts, sobre cuánto uso modelos en memoria al desarrollar un sistema. Pero ¿qué pasa cuando tenemos una base de datos? Ya sea porque llegamos al punto de necesitar usarla, o porque la base de datos ya está desde el principio del desarrollo.&lt;/p&gt;  &lt;p&gt;Lo que he encontrado que me ha servido en esos casos es tener los tests de TDD como siempre, pero el modelo con persistencia en una base de datos local, del desarrollador. En el repositorio común al equipo debería estar claros los pasos para instalar esa base de datos (por ejemplo, un script de creación e inserción de datos iniciales). Puede que esa misma base de datos la usemos localmente para hacer pruebas manuales y demostraciones. Pero la cuestión es que los tests de TDD debería poder ejecutarse en cualquier momento, una vez o varias veces, sin verse afectado por la base de datos. Entonces, hay varias soluciones (que se pueden combinar):&lt;/p&gt;  &lt;p&gt;- Un comando de línea que ponga a la base de datos de TDD en un estado conocido, la “well-known database”&lt;/p&gt;  &lt;p&gt;- Tener una base de datos para TDD y otra, también local, para las demostraciones&lt;/p&gt;  &lt;p&gt;- En los tests, una vez, al principio, tener una tarea que ponga a la base de datos de TDD en un estado conocido&lt;/p&gt;  &lt;p&gt;- Cada test, envolverlo en una transacción y nunca hacer el commit&lt;/p&gt;  &lt;p&gt;Con esto, se reduce la fricción de correr los tests locales.&lt;/p&gt;  &lt;p&gt;En un servidor de integración continua, seguramente se creará la base y se cargará con los datos iniciales antes de correr los tests (de TDD u otros)&lt;/p&gt;  &lt;p&gt;Yendo un poco más en detalle. Supongamos que nuestro sistema debe calcular la retención del impuesto a las ganancias cuando hay que pagar a un proveedor. En Argentina, puede que las reglas sean algo complejas para calcular. No sé el estado actual del tema, pero en su tiempo podía depender del servicio dado por el proveedor, de si el servicio abarcaba varias provincias (por ejemplo, un flete que comenzaba en una provincia y terminaba en otra), de lo que nos había facturado en el último mes, de si el proveedor tenía domicilio en una zona de promoción industrial o no, etc. Sea así o no ahora, me sirve como idea de base.&lt;/p&gt;  &lt;p&gt;¿Cómo se encararía programar eso con TDD, y base de datos?&lt;/p&gt;  &lt;p&gt;Como siempre, paso a paso, “baby steps”. Seguramente atacaríamos primero algunos casos sencillos y luego otros casos más complicados. Cuando se llegue a estos casos (por ejemplo el proveedor con promoción industrial) ponemos en la base de datos bien conocida, un proveedor X que cumpla con lo que necesitamos para el test que estamos desarrollando. Es decir, a medida que resolvemos los test, va quedando en la base (en scripts de creación con datos iniciales) los escenarios que vamos necesitando. Probablemente, un test solamente necesite crear al proveedor (en la etapa de Arrange). Si lo necesitamos a ese proveedor para varios tests, habrá refactor del test para que haya una rutina que lo cree. Pero cuando ya lo necesitamos para varias situaciones, migrará su existencia directamente a la base de datos bien conocida.&lt;/p&gt;  &lt;p&gt;Cada desarrollador del equipo, cuando traer el último código del repositorio, podrá ver si alguien modificó los scripts de creación de la base. Y aún si no se da cuenta, al ejecutar los tests de TDD, seguramente alguno quedará en rojo, adviertiendo que algo de base ha cambiado. Toda esta forma de trabajo también sirve cuando en el desarrollo se va cambiando la estructura de la base. Y les sirve para no tener que adoptar mi consejo de modelo en memoria, si aún no se animan a esa forma de trabajo.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1823940" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Programaci_F300_n/default.aspx">Programación</category></item><item><title>TDD y el juego del Go</title><link>http://msmvps.com/blogs/lopez/archive/2013/01/22/tdd-y-el-juego-del-go.aspx</link><pubDate>Tue, 22 Jan 2013 16:59:29 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1822988</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1822988</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2013/01/22/tdd-y-el-juego-del-go.aspx#comments</comments><description>&lt;p&gt;Hace unos años tuve la suerte y el agrado de conocer personalmente a Fernando Aguilar, uno de los mejores jugadores de Go, de Argentina y de Occidente. Pueden leer:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ajlopez.zoomblog.com/archivo/2007/06/20/fernando-Aguilar-y-el-Go.html"&gt;Fernando Aguilar y el Go&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sobre el juego del Go, ver mis posts y links:&lt;/p&gt;  &lt;p&gt;&lt;a title="http://ajlopez.zoomblog.com/cat/15644" href="http://ajlopez.zoomblog.com/cat/15644"&gt;http://ajlopez.zoomblog.com/cat/15644&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://delicious.com/ajlopez/go+baduk"&gt;http://delicious.com/ajlopez/go+baduk&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;Si leen mis posts, ya saben que me interesa la aplicación de la Inteligencia Artificial al juego del Go, ver:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ajlopez.zoomblog.com/archivo/2008/03/31/computer-Go-y-el-programa-Ajgo.html"&gt;Computer Go y el programa AjGo&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2008/03/31/ajgo-hacia-un-programa-que-juegue-al-go.aspx"&gt;AjGo: Hacia un programa que juege al Go&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;(Nota curiosa: AjGo fue reescrito en 2008 aplicando TDD en cada paso, pueden ver el repo. También pueden vigilar &lt;a href="https://github.com/ajlopez/SimpleGo"&gt;SimpleGo&lt;/a&gt; para ir viendo como voy a ir aplicando TDD completo, esta vez en JavaScript).&lt;/p&gt;  &lt;p&gt;Pero volvamos al tema. Cuando estuve en la charla de Fernando, le pregunté: cómo piensa la próxima jugada. Quería aprender para poder aplicarlo a mis programas. El go tiene muchas más variantes en cada ply que el ajedrez, y tiene características sutiles, como que una jugada hecha un lugar puede tener grandes efectos en otro lado del tablero. Esto ha impedido que haya programas de go que sean tan avanzados como los que encontramos en ajedrez. Lo que recuerdo de la respuesta:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;En determinado momento [cerca de la apertura] no pensé hacia adelante, no me interesó calcular jugadas. Miré el tablero y me dije: Estoy bien. Cualquier cosa que haga el adversario, yo voy a poder contestarle. No tengo debilidades. El futuro no me asusta.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Siempre me quedó esa respuesta (atención, puesta con mis palabras, no tengo las notas que tomé en su momento). También se puede aplicar al ajedrez. No es que no hay situaciones tácticas en go, donde el cálculo de un árbol de jugadas es importante. Pero no se da tanto en la mayoría de los juegos y situaciones, solo por momentos. De ahí que el “approach” Big Blue (atacar con fuerza bruta un gran árbol de búsqueda, con alguna heurística de dónde para en la exploración y evaluaciones parciales) no sea tan aplicable en el caso del go. Hay que trabajar más en buenos algoritmos evaluadores de posiciones estáticas, que me digan “estoy bien”.&lt;/p&gt;  &lt;p&gt;Lo mismo nos da TDD, armado con casos de usos, y evitando romper YAGNI. Cualquier cambio que venga (recuerden que en lo ágil abrazamos el cambio, no “luchamos” contra él), cualquier cambio en los requerimientos, cualquier caso de uso nuevo, cuando hago TDD veo que puedo enfrentarlo cuando llegue el caso. No hace falta “pensar jugadas hacia adelante”. Cuando tengo un proyecto armado usando TDD, lo que se va creando crece orgánicamente, sin debilidades grandes. Si alguna vez tenemos que refactorizar en grande, TDD nos da la red de seguridad para enfrentar el cambio con coraje. El aplicar “baby steps” permite que nuestro sistema crezca como un organismo: de a poco. No será un “monstruo” que tenga dos cabezas, o un brazo más grande que otro. Y hasta agregaría que no tendrá cosas insertadas “porque las vamos a necesitar”. No, sólo tendrá lo que habremos necesitado hasta ese punto. Y nuestro código estará preparado para soportar cambios que vengan (que siempre vienen).&lt;/p&gt;  &lt;p&gt;Eso nos va a ir dando un sistema que, a cada paso, no tiene mochilas al hombro. Vamos a “estar bien”, y ningún artefacto nos “va a pesar” o nos va a generar fricción. Estaremos en una posición tal como la de Fernando. El sistema y nuestro equipo podrá decir “Estoy bien. No tengo debilidades. El futuro no me asusta” :-)&lt;/p&gt;  &lt;p&gt;Bueno, apenas relacionado, pero los otros días veía &lt;a href="http://www.imdb.com/title/tt0070034/"&gt;Enter the Dragon&lt;/a&gt;, (1973), la última película de Bruce Lee. Antes de olvidarlo, lo comparto con Uds:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A good fight should be like a small play, but played seriously. A good martial artist does not become tense, but ready. Not thinking, yet not dreaming. Ready for whatever may come. When the opponent expands, I contract. When he contracts, I expand. And when there is an opportunity, I do not hit. It hits all by itself. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Ready for whatever may come.&lt;/p&gt;  &lt;p&gt;Dicho esto, que el creador del universo se apiade de los equipos que desarrollan software de producción sin TDD :-)&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1822988" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>Presentando TDD</title><link>http://msmvps.com/blogs/lopez/archive/2012/09/26/presentando-tdd.aspx</link><pubDate>Wed, 26 Sep 2012 14:52:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1817375</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1817375</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/09/26/presentando-tdd.aspx#comments</comments><description>&lt;p&gt;Hoy voy a estar dando una charla gratuita sobre TDD, usando Visual Studio, en Buenos Aires, gracias al &lt;a href="http://www.mug.org.ar"&gt;Microsoft User Group de Argentina&lt;/a&gt;. Ya escribí anunciando esta actividad en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/08/16/seminario-gratuito-en-buenos-aires-introducci-243-n-a-tdd-con-visual-studio.aspx"&gt;Introducción a TDD con Visual Studio&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Así que quiero poner en este post lo que voy a presentar, todo práctico, que será código desarrollado en las dos horas de la charla. Elegiré un dominio y algunos tests, y lo desarrollaremos en el momento. Iré agregando código a mi proyecto de GitHub:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks"&gt;https://github.com/ajlopez/TddOnTheRocks&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Seguramente aparecerá hoy un nuevo directorio, con lo que iremos haciendo.&lt;/p&gt;  &lt;p&gt;Para los que quieran TDD para una aplicación MVC, hay un video de &lt;a href="http://altnethispano.org/Inicio.aspx"&gt;ALT.NET Hispano&lt;/a&gt;:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://altnethispano.org/wiki/van-2012-06-23-desarrollando-una-aplicacion-con-tdd-desde-0.ashx"&gt;Desarrollo de una Aplicación con TDD desde 0&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;explicando el desarrollo de:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Un ejemplo más simple:&lt;/p&gt;  &lt;p&gt;&lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/MySrc"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/MySrc&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;basado en un ejemplo de &lt;a href="http://twitter.com/hernanwilkinson"&gt;@hernanwilkinson&lt;/a&gt;, explicado en según mi serie de posts:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/03/18/tdd-paso-a-paso-1-primer-test.aspx"&gt;TDD paso a paso&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Dos ejemplos más:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/03/01/writing_2D00_an_2D00_application_2D00_using_2D00_tdd_2D00_part_2D00_1_2D00_introduction.aspx"&gt;Escribiendo una Aplicación usando TDD&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2010/09/15/escribiendo-un-int-233-rprete-en-net-parte-1.aspx"&gt;Escribiendo un intérprete en .NET&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Recursos adicionales:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx"&gt;Mis posts sobre TDD en español&lt;/a&gt; (acá está la lista completa de las series de arriba y algunos post más en otros lenguajes y tecnologías, usando TDD; además, hay algún video demostrativo)    &lt;br /&gt;&lt;a href="http://ajlopez.wordpress.com/category/test-driven-development/"&gt;Mis post en Anglish ;-)&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Mis enlaces&lt;/p&gt;  &lt;p&gt;&lt;a href="http://delicious.com/ajlopez/tdd"&gt;http://delicious.com/ajlopez/tdd&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://delicious.com/ajlopez/tdd+tutorial"&gt;http://delicious.com/ajlopez/tdd+tutorial&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://delicious.com/ajlopez/tdd+video"&gt;http://delicious.com/ajlopez/tdd+video&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://delicious.com/ajlopez/tdd+codekata"&gt;http://delicious.com/ajlopez/tdd+codekata&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Espero les sirva&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1817375" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Reuniones/default.aspx">Reuniones</category></item><item><title>Seminario Gratuito en Buenos Aires: Introducción a TDD con Visual Studio</title><link>http://msmvps.com/blogs/lopez/archive/2012/08/16/seminario-gratuito-en-buenos-aires-introducci-243-n-a-tdd-con-visual-studio.aspx</link><pubDate>Thu, 16 Aug 2012 14:55:20 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1815168</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1815168</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/08/16/seminario-gratuito-en-buenos-aires-introducci-243-n-a-tdd-con-visual-studio.aspx#comments</comments><description>&lt;p&gt;Gracias a &lt;a href="http://www.mug.org.ar/"&gt;la gente del MUG de Argentina&lt;/a&gt; el día miércoles 26 de septiembre voy a estar dando una charla gratuita sobre uno de mis temas preferidos: Test-Driven Development, usando ejemplo en concreto con C# y Visual Studio. Pueden ver el detalle y registración en:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;a href="http://www.mug.org.ar/Eventos/3804.aspx"&gt;http://www.mug.org.ar/Eventos/3804.aspx&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;Fecha y Horario: Miércoles 26 de Septiembre de 2012, en el horario de 18.30 a 20.30 hs. &lt;/p&gt;    &lt;p&gt;Vamos a armar desde el comienzo un dominio simple, usando TDD, y el ciclo de: test, rojo,&amp;#160; verde, refactor. &lt;/p&gt;    &lt;p&gt;Veremos como entonces va “creciendo” nuestro código de manera orgánica, consiguiendo un diseño adecuado a lo que se necesita.     &lt;br /&gt;Los tests nos guían en la construcción del software, siendo más que tests, especificaciones, ejemplos de uso esperado del software en construcción. &lt;/p&gt;    &lt;p&gt;Y hasta conseguimos ser más productivos y con código mantenible, evitando la sobre-ingeniería, arquitecturas de astronauta, y YAG &lt;/p&gt;    &lt;p&gt;Lugar: Auditorio del MUG - Rivadavia 1479, 1er Piso &amp;quot;A&amp;quot; - Ciudad de Buenos Aires &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;No digan que no les avisé con tiempo :-)&lt;/p&gt;  &lt;p&gt;La idea es armar un dominio no básico pero que pueda abarcarse en las dos horas que tenemos dispoibles. Iremos armándolo siguiendo TDD: escribir un test, hacer que funcione en rojo, luego agregar el mínimo código para que pase a verde, y refactor. Esto nos permitirá experimentar algo que no veo muy aplicado por estos lares: la construcción de software paso a paso, con “baby steps”, sin poner todos los patrones “en la parrilla” desde el principio, sino viendo cómo el software en construcción puede verse como un organismo, que se va desarrollando armónicamente, sin grandes saltos ni imponiendo grandes decisiones de antemano. Yo vengo practicando esta forma de programar desde hace años, y me ha dado muchas satisfacciones. Hasta permite dominar la complejidad, justamente, paso a paso. ¿Cómo comerse un elefante? La respuesta ágil es: pedacito a pedacito.&lt;/p&gt;  &lt;p&gt;Como comenté en &lt;a href="http://msmvps.com/blogs/lopez/archive/2012/08/09/tdd_2D00_unit_2D00_tests_2D00_and_2D00_mocks.aspx"&gt;TDD, Tests Unitarios y Mocks&lt;/a&gt;, yo soy partidario de la escuela “clásica” de TDD, usando mocks solamente cuando es necesario. Eso es apenas una rama de lo que uno puede adoptar con TDD (y ágil y XP en general): diferir las decisiones (algo escribí sobre el tema en &lt;a href="http://msmvps.com/blogs/lopez/archive/2012/07/04/tdd-y-casos-de-uso.aspx"&gt;TDD y Casos de Uso&lt;/a&gt;). Sobre cómo armar algo que vaya más allá del dominio, por ejemplo, con ASP.NET MVC, lean ese post sobre TDD y casos de uso, y además la &lt;a href="http://altnethispano.org/wiki/van-2012-06-23-desarrollando-una-aplicacion-con-tdd-desde-0.ashx"&gt;charla que quedó en video&lt;/a&gt; gracias a la gente de ALT.NET Hispano.&lt;/p&gt;  &lt;p&gt;Si no pueden venir a la charla de Buenos Aires, pueden seguir mi serie &lt;a href="http://msmvps.com/blogs/lopez/archive/2012/07/28/tdd_2D00_and_2D00_business_2D00_rules_2D00_1.aspx"&gt;TDD y Reglas de Negocio&lt;/a&gt;, donde encararé un dominio distinto. También tienen varios ejemplos y hasta videos, en mis posts sobre TDD.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1815168" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>TDD, Test Unitarios y Mocks</title><link>http://msmvps.com/blogs/lopez/archive/2012/08/09/tdd_2D00_unit_2D00_tests_2D00_and_2D00_mocks.aspx</link><pubDate>Thu, 09 Aug 2012 15:03:07 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1814938</guid><dc:creator>lopez</dc:creator><slash:comments>4</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1814938</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/08/09/tdd_2D00_unit_2D00_tests_2D00_and_2D00_mocks.aspx#comments</comments><description>&lt;p&gt;En el mes de Junio pasado dí una charla en lína sobre TDD usando ASP.NET MVC, gracias a la gente de ALT.NET Hispano. Pueden &lt;a href="http://altnethispano.org/wiki/van-2012-06-23-desarrollando-una-aplicacion-con-tdd-desde-0.ashx"&gt;verla aquí&lt;/a&gt;. Usé &amp;quot;baby steps”, pasos de bebé, para ir escribiendo el código, usando el ciclo TDD “escribir el test, rojo, verde, refactor”. Tengo otros ejemplos similares, en mis posts sobre TDD de este blog, y en mi cuenta de GitHub. Usualmente, no escribo ni mocks ni stubs. Puedo ser clasificado como un miembro de la escuela “clásica” de TDD, en contraste con la escuela “mockista”. Mi referencia a esta dicotomía (que no tiene que ser tajante) es el artículo de Martin Fowler:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://martinfowler.com/articles/mocksArentStubs.html"&gt;Mocks Aren’t Stubs&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esto es: sólo agrego un mock si REALMENTE lo necesito. Pero alguien podría decir: “Ah! Yo también, sólo los agrego cuando los necesito, pero LOS NECESITO TODO EL TIEMPO”. Yo no pienso de esa manera: los mocks nos son algo imperativo en la programación TDD. El propósito de este post es mostrar que semejante aserción “necesito mocks siempre” es una falacia, que deriva de un entendimiento parcial de lo que es un test, y en especial, un test unitario. Uds. pueden luego decidir usar o no usar mocks y stubs. Pero los mocks sólo son REALMENTE necesarios en TDD en algunas circunstancias (otra historia es la necesidad de mocks en test en general, fuera de TDD, por ejemplo, en “escribo test después del código sólo para tener buen code coverage”).&lt;/p&gt;  &lt;p&gt;Leo en ese artículo de Fowler:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;xUnit tests follow a typical four phase sequence: setup, exercise, verify, teardown. In this case the setup phase is done partly in the setUp method (setting up the warehouse) and partly in the test method (setting up the order). The call to &lt;code&gt;order.fill&lt;/code&gt; is the exercise phase. This is where the object is prodded to do the thing that we want to test. The assert statements are then the verification stage, checking to see if the exercised method carried out its task correctly. In this case there&amp;#39;s no explicit teardown phase, the garbage collector does this for us implicitly.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Sí, usualmente escribo el test con una parte de “setup” o “arrange”, que arma el escenario del test. La escual mockista escribiría los mocks (vean el mismo ejemplo en el artículo de Fowler, usando mocks). De ese artículo, se ve que el mismo test, SE PUEDE escribir CON y SIN mocks. Fowler escribe:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The &lt;b&gt;classical TDD&lt;/b&gt; style is to use real objects if possible and a double if it&amp;#39;s awkward to use the real thing. So a classical TDDer would use a real warehouse and a double for the mail service. The kind of double doesn&amp;#39;t really matter that much.&lt;/p&gt;    &lt;p&gt;A &lt;b&gt;mockist TDD&lt;/b&gt; practitioner, however, will always use a mock for any object with interesting behavior. In this case for both the warehouse and the mail service.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Veo que todo este tema termina relacionado con lo que llamamos y entendemos por Test Unitario. No hay una clara definición del término: muchos libros de TDD sólo mencionan test, o ponen la expresión “test unitario” de vez en cuando, sin definirla. Voy entonces a la wikipedia:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Unit_testing"&gt;http://en.wikipedia.org/wiki/Unit_testing&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;In &lt;a href="http://en.wikipedia.org/wiki/Computer_programming"&gt;computer programming&lt;/a&gt;, &lt;b&gt;unit testing&lt;/b&gt; is a method by which individual units of &lt;a href="http://en.wikipedia.org/wiki/Source_code"&gt;source code&lt;/a&gt;, sets of one or more computer program modules together with associated control data, usage procedures, and operating procedures, are tested to determine if they are fit for use.&lt;sup&gt;&lt;a href="http://en.wikipedia.org/wiki/Unit_testing#cite_note-kolawa-0"&gt;[1]&lt;/a&gt;&lt;/sup&gt; Intuitively, one can view a unit as the smallest testable part of an application. In &lt;a href="http://en.wikipedia.org/wiki/Procedural_programming"&gt;procedural programming&lt;/a&gt; a unit could be an entire module but is more commonly an individual function or procedure. In &lt;a href="http://en.wikipedia.org/wiki/Object-oriented_programming"&gt;object-oriented programming&lt;/a&gt; a unit is often an entire interface, such as a class, but could be an individual method. &lt;sup&gt;&lt;a href="http://en.wikipedia.org/wiki/Unit_testing#cite_note-1"&gt;[2]&lt;/a&gt;&lt;/sup&gt; Unit tests are created by programmers or occasionally by &lt;a href="http://en.wikipedia.org/wiki/White-box_testing"&gt;white box testers&lt;/a&gt;during the development process.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;La parte clave es:&amp;#160; un Test Unitario ejercita, prueba, “pone en la fragua” una PARTE del software, usualmente un método individual. En la parte de “act” (dentro de “arrange/act/assert”) pongo un solo comando: la llamada al método que estoy probando, nada más, nada menos.&lt;/p&gt;  &lt;p&gt;PERO MUCHA GENTE piensa: esa llamada al método, DEBE INVOLUCRAR SOLO al código de ese método, y no meterse en el código de las otras partes que ese método usa y llama. Bien, eso no es imperativo en TDD. El primer ejemplo de Martin Fowler muestra claramente que se pueden usar otras instancias y métodos. Y esas instancias pueden ser código real de producción, no necesariamente mocks ni stubs. Esa es la escuela clásica de TDD en acción.&lt;/p&gt;  &lt;p&gt;Sigo leyendo en la Wikipedia:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Ideally, each &lt;a href="http://en.wikipedia.org/wiki/Test_case"&gt;test case&lt;/a&gt; is independent from the others: substitutes like &lt;a href="http://en.wikipedia.org/wiki/Method_stub"&gt;method stubs&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Mock_object"&gt;mock objects&lt;/a&gt;,&lt;sup&gt;&lt;a href="http://en.wikipedia.org/wiki/Unit_testing#cite_note-mocksarentstubs-2"&gt;[3]&lt;/a&gt;&lt;/sup&gt; &lt;a href="http://en.wikipedia.org/wiki/Mock_object#Mocks_and_fakes"&gt;fakes&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Test_harness"&gt;test harnesses&lt;/a&gt; can be used to assist testing a module in isolation.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Acá la clave está en lo de “ideally”. Idealmente para qué? Para poder probar algo de forma aislada, para lograr “isolation”. Pero como toda solución, tiene sus pros y sus contras IMNSHO (In My No So Humbler Opinion :-) perseguir el aislamiento DEBE SER EVALUADO, en términos de costo versus beneficios, NO DEBE SER tomado como un fin en sí. Mi experiencia me muestra, entonces: no vale la pena llegar a eso usando mocks. Usándolos, hay que agregar parvas de código, solamente para conseguir el aislamiento de una prueba unitaria. En cambio, uso otros caminos, como usar código real en el contexto de un escenario que trato de armar de forma ágil. Fowler menciona Object Mother:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;In practice, classic testers tend to reuse complex fixtures as much as possible. In the simplest way you do this by putting fixture setup code into the xUnit setup method. More complicated fixtures need to be used by several test classes, so in this case you create special fixture generation classes. I usually call these &lt;a href="http://martinfowler.com/bliki/ObjectMother.html"&gt;Object Mothers&lt;/a&gt;, based on a naming convention used on an early ThoughtWorks XP project. Using mothers is essential in larger classic testing, but the mothers are additional code that need to be maintained and any changes to the mothers can have significant ripple effects through the tests. There also may be a performance cost in setting up the fixture - although I haven&amp;#39;t heard this to be a serious problem when done properly. Most fixture objects are cheap to create, those that aren&amp;#39;t are usually doubled.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;En mi ejemplo del video que mencioné alprincio, uso algo similar al “object mother” de Fowler, un objeto que prepara el escenario bajo el cual voy a ejecutar mi prueba unitaria. En general, preparo los objetos del dominio, leyéndolos de objetos JSON. Ese “object mother” SOLO APARECE cuando lo comienzo a necesitar en TDD. Recuerden: TDD favorece el uso de YAGNI: no agregar algo que no necesitamos todavía. En muchos proyectos, siguiendo “baby steps”, termino usando un dominio en memoria, con una base de datos/repositorios en memoria. Lean &lt;a href="http://www.martinfowler.com/bliki/InMemoryTestDatabase.html"&gt;In memory database&lt;/a&gt; del mismo Fowler. Un ejemplo de la evolución de mi código siguiendo ese camino (con commits atómicos, casi por tests) en: &lt;a href="https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp&lt;/a&gt;. Y en ese ejemplo, comencé programando el controlador, siguiendo un camino “top-down”. Se puede escribir TDD de forma “top-down” o “bottom-up” CON y SIN mocks. El uso de mocks no está relacionado ni con TDD ni con la dirección del armado del código.&amp;#160; Algo relacionado y muy interesante referencia es el artículo de &lt;a href="https://twitter.com/unclebobmartin"&gt;@unclebobmartin&lt;/a&gt;e: &lt;a href="http://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html"&gt;No DB&lt;/a&gt;:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The center of your application is not the database. Nor is it one or more of the frameworks you may be using. &lt;em&gt;The center of your application are the use cases of your application.&lt;/em&gt;&lt;/p&gt;    &lt;p&gt;…&lt;/p&gt;    &lt;p&gt;What is the best time to determine your data model? When you know what the data entities are, how they are related, and how they are used. When do you know that? When you’ve gotten all the use cases and business rules written &lt;em&gt;and tested&lt;/em&gt;. By that time you will have identified all the queries, all the relationships, all the data elements, and you’ll be able to construct a data model that fits nicely into a database.&lt;/p&gt;    &lt;p&gt;Does this change if you are using a NoSql database? Of course not! You still focus on getting the use cases working and tested before you even think about the database; no matter what kind of database it ends up being.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Yo pude, varias veces, seguir ese camino, y SIN escribir un SOLO MOCK.&lt;/p&gt;  &lt;p&gt;Qué pasa con la pérdida del aislamiento? Por lo menos, en mis proyectos, no ha sido un probelma. Si rompo algo “grande”, puedo tener 40 tests en rojo, pero una rápida inspección me dice que 15 son tests de controladores, 20 en una capa de servicios lógicos y 5 en un repositorio. Entonces, el problema está altamente relacionado con el repositorio. El aislamiento a priori no me fue necesario.&lt;/p&gt;  &lt;p&gt;Recientemente, estuve trabajando en un equipo, con gente de diferentes estilos. Algunos no usaban TDD, o sólo escribían &amp;quot;test para aumentar el code ccoverage”. Otros usanban TDD pero había representantes de ambas escuelas, la “clasista combativa” :-) y la mockista. Entonces, cuando había que refactorear una implementación, los test clásicos relacionados con el cambio QUEDABAN en VERDE automáticamente. En cambio, los tests mockistas se rompían, porque estaban muy ligados a lo que se esperaba en la implementación actual o interna. Yo veo ahí que los mocks son una mochila, algo que nos pesa y va en contra del refactor ágil.&lt;/p&gt;  &lt;p&gt;¿Cuándo usar, entonces, un mock o un stub? Bueno, esa decisión se las dejo a Uds. Pero quiero mosntrar que es una decisión a tomar en un contexto, no es cuestión de decir “hay que usar mocks siempre, porque eso es TDD”. Realmente, es rara la ocasión en la que tenga que usar un mock en mis proyectos personales. Un ejemplo: puedo tener código que no escribí, un caso: un servicio web externo que tengo que consumir. Entonces, en mis tests, no llamo al servicio web externo (que puede no estar siempre accesible, o tener problemas de latencia). Tampoco un stub. Escribo una implementación que simule el servicio web y LO ENTREGO en la aplicación final de la iteración. No es código sólo para test. Luego, con el tiempo, voy preparando la aplicación para que se pueda configurar, a gusto del consumidor, si quiere usar esa implementación “liviana” o el servicio web real. De esta manera, puedo ir manteniendo el proyecto ágil, y acercarme en cualquier momento a la implementación real.&lt;/p&gt;  &lt;p&gt;¿Alguna situación donde usar mocks sea necesario? Hmm.. puede ser en un equipo distribuido, o que tiene repartidas las tareas. El equipo A tiene a su cargo escribir los controladores de una aplicación ASP.NET, y el equipo B tiene que escribir los servicios lógicos, el dominio a consumir. Mientras el equipo B los escribe, el equipo A puede usar mocks de ellos, para tener listos sus controladores. Esa es una situación, en mi opinión, más “legitimada” para usar mocks.&lt;/p&gt;  &lt;p&gt;¿Comentarios? ¿Otros pros y contras de las escuelas clásica y mockista?&lt;/p&gt;  &lt;p&gt;Podría parafrasear a un político norteamericano del siglo XIX y decir: “El único mock bueno es el mock muerto, el que no se escribe” :-)&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1814938" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>TDD y Reglas de Negocio (1)</title><link>http://msmvps.com/blogs/lopez/archive/2012/07/28/tdd_2D00_and_2D00_business_2D00_rules_2D00_1.aspx</link><pubDate>Sat, 28 Jul 2012 09:47:07 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1813748</guid><dc:creator>lopez</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1813748</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/07/28/tdd_2D00_and_2D00_business_2D00_rules_2D00_1.aspx#comments</comments><description>&lt;p&gt;Este mes estuve trabajando como miembro de un equipo ágil, desarrollando una aplicación privada. Una de las características interesates es que el sistema permite la creación y existencia de entidades del dominio del&amp;#160; negecio, aún cuando estén en algún estado “inválido”. El product owner quiere armar un sistema flexible que refleje la realidad del negocio, en vez de uno más estrcito que no permita ese reflejo porque no se cumple alguna regla de negocio. Pero quiere ver también cuáles son las entidades que están en estado “inválido” y por qué. Así que se le muestra (la parte de interfaz de usuario está en ASP.NET MVC) una página con lo que hemos llamado Findings: una lista de mensajes alertando sobre los estados a revisar. Por ejemplo: que tal factura tiene un importe demasiado bajo o que no tiene renglones asociados.&lt;/p&gt;  &lt;p&gt;Me gustaría explorar el mode TDD de armar esa característica. Para conseguirlo, necesito un dominio de prueba, y en este post voy a describirlo, simplificado, para tener algo en firme sobre el que implementar los Findings.&lt;/p&gt;  &lt;p&gt;Sea una Order. Cada Order tiene uno o más Order Item. Cada Order Item tiene un Product, Quantity, Price (Producto, Cantidad y Precio). Cada Order tiene un Customer (Cliente). Hay reglas de negocio que describen cuáles son los estados “inválidos”. Algunos ejemplos:&lt;/p&gt;  &lt;p&gt;- Una Order para un Customer de categoría Y no puede tener un monto total que supere X.    &lt;br /&gt;- Una Order debe tener uno o más Order Items.     &lt;br /&gt;- Los Order Items deben tener una Cantidad/Quantity &amp;gt; 0.     &lt;br /&gt;- Los Order Items deben tener Precio/Price &amp;gt; 0.     &lt;br /&gt;- El Producto P debe tener Cantidad &amp;gt; Cantidad Mínima en cada Order Item.    &lt;br /&gt;- Producto P tiene un Precio, y cada Order Item que lo incluya no puede tener su Precio &amp;lt; Precio de Producto &amp;lt; 0.80.     &lt;br /&gt;- y así…&lt;/p&gt;  &lt;p&gt;De esta forma, las Ordenes pueden ser creadas y persistidas sin tener que cumplir con todas las reglas. La Order no es RECHAZADA por el sistema. Solamente que hay páginas para pedir (en cualquier momento) cuáles son los Findings, la lista de las reglas que no se cumplen.&lt;/p&gt;  &lt;p&gt;Las reglas de negocio pueden cambiar, y se pueden definir nuevas. No está definido en esta esta etapa del proyecto cómo conseguir esto: puede ser que simplemente agregando código, o escribiendo un DSL (Domain-Specific Languages) de reglas. Por ahora es un tema que no importa. En la aplicación real, el cliente final tiene programadores a disposición, así que la modificación del código sigue siendo una opción aceptable. Bien puede descubrir que 30 reglas bastan, y que no hace falta cambiarlas o se cambian cada 6 meses. Este es un tema a investigar: no siempre crear un DSL de reglas se justifica. En esta versión inicial, las reglas de negocio están en el código, compiladas. En una segunda versión, algunas reglas se aplicarán a algunas órdenes (por ejemplo, a las Orders que tienen clientes de Canadá). El Product Owner quiere tener: Findings por Order, Findings por Producto, Findings por Customer.&lt;/p&gt;  &lt;p&gt;En esta serie de post, quiero entonces explorar y mostrar una forma de armar lo pedido, USANDO TDD. Para simplificar el ejemplo, no habrá UI ni persistencia, solamente objetos del dominio, y su grafo de relaciones. Veremos cómo, usando TDD, las reglas y su forma de ejecución van emergiendo desde los casos de uso planteados. Usaré mi cuenta en GitHub para ir compartiendo el código. Será escrito, como la aplicación original, en C#.&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez    &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;     &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1813748" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>TDD y Casos de Uso</title><link>http://msmvps.com/blogs/lopez/archive/2012/07/04/tdd-y-casos-de-uso.aspx</link><pubDate>Wed, 04 Jul 2012 09:44:24 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1812272</guid><dc:creator>lopez</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1812272</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/07/04/tdd-y-casos-de-uso.aspx#comments</comments><description>&lt;p&gt;Ya saben que me importa mucho usar Test-Driven Delopment. Yo diría que es lo primero a adoptar en un desarrollo, como “tecnología nueva”. Pero reconozco que no es fácil a veces transmitir la idea y convencer a la gente de adoptar TDD.&lt;/p&gt;  &lt;p&gt;Por ejemplo, hay una idea flotando, que leí hace poco en una lista: “no uso TDD porque el sistema lo tengo que entregar en tres semanas”. Como si TDD fuera algo que alentece. Yo quisiera que se tomara el tiempo, entonces, en cuánto se gasta en la prueba manual o el tiempo que se ocupa usando el “debugger”.&lt;/p&gt;  &lt;p&gt;Hace dos semanas, tuve el gusto de dar una charla aplicando TDD desde un “File, New Project”, gracias a la gente de &lt;a href="http://twitter.com/altnethispano"&gt;@AltNetHispano&lt;/a&gt; (&lt;a href="http://altnethispano.org/Inicio.aspx"&gt;http://altnethispano.org/Inicio.aspx&lt;/a&gt;). Lo anuncié en &lt;a href="http://msmvps.com/blogs/lopez/archive/2012/06/18/van-en-alt-net-hispano-desarrollando-una-aplicaci-243-n-con-tdd.aspx"&gt;VAN en Alt.NET Hispano: Desarrollando una Aplicación con TDD&lt;/a&gt;&amp;#160; y pueden ver el resultado en &lt;a title="https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp" href="https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp"&gt;https://github.com/ajlopez/TddOnTheRocks/tree/master/TddApp&lt;/a&gt; con commits casi por test. Ese desarrollo fue orientado a terminar en 2 horas, y entonces se mostró cómo por refactor aparecen patrones, para mejorar el código en desarrollo, pero NO APARECEN desde el principio. Al comienzo, TDD brega por el “menor código” que pase el test. Todo mejoramiento de código pasa por refactor. Ese énfasis me hizo dejar algo de lado un tema importante, aunque lo aclaré en la charla: prefiero aplicar TDD escribiendo tests SOBRE CASOS DE USO.&lt;/p&gt;  &lt;p&gt;Algo de ese “approach” aparece en la serie de post &lt;a href="http://msmvps.com/blogs/lopez/archive/2012/05/25/tdd-paso-a-paso-6-la-semana-del-panadero.aspx"&gt;TDD paso a paso&lt;/a&gt; donde se ve cómo se va construyendo el software a partir de un problema planteado por el bueno de &lt;a href="http://twitter.com/hernanwilkinson"&gt;@hernanwilkinson&lt;/a&gt;. Vean cómo se hace poco diseño de implementación por adelantado: se puede hacer, pero en general con TDD se hace poco o de forma liviana. Los tests nos van guiando qué clases, métodos, estado interno NECESITAMOS debido a que vamos planteando los casos de uso.&lt;/p&gt;  &lt;p&gt;En la charla de @AltNetHispano&amp;#160; se preguntó: ¿pero qué hacemos si en la primera iteración el cliente/”product owner” nos pide un diagrama de entidad-relación como entregable? Pues bien, respuesta corta: va a ser muy difícil aplicar TDD. Cualquier DER que entreguemos no se basará en casos de uso en concreto, sino que trataremos de “compilar” en nuestra cabeza un modelo POR ADELANTADO de lo que necesitamos. ¿Y eso es problema? No, si NO trabajan ágil y NO usan TDD. ¿Por qué es problema si quieren trabajar ágil y también quieren aplicar TDD? Porque cualquier DER que entreguen será un “dibujo”, algo medio inventado, basado en nuestra capacidad de visualizar qué se necesita SIN HABER planteado un solo caso de uso en concreto. Y hay un problema adicional: ese DER es una “bajada de línea”. En dos semanas más, alguien del equipo comenzará a decir: “no podemos hacer X porque rompemos el DER” y temas parecidos.&lt;/p&gt;  &lt;p&gt;Otra bajada de línea aparece con: el “product owner” aparece ya desde el principio con un modelo de datos, de un sistema aún no construido (acepto mejor que venga con una base de datos de un sistema que YA se está usando).&lt;/p&gt;  &lt;p&gt;De ahí mi énfasis en usar TDD guiado a su vez por CASOS DE USO. Hace que cada cosa que agregamos (clase, método, estado, entidades, etc…. ) HAGA SU APARICION por haber escrito los tests para un caso de uso. Hace un tiempo me encontré con ideas parecidas de parte de “Uncle Bob” Martin. Les recomiendo lectura de:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html"&gt;No DB&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Un párrafo importante:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The center of your application is not the database. Nor is it one or more of the frameworks you may be using. The center of your application are the use cases of your application. &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Sigo:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;It makes me crazy when I hear a software developer describe his system as a “Tomcat system using Spring and Hibernate using Oracle”. The very wording puts the frameworks and the database at the center. &lt;/p&gt;    &lt;p&gt;What do you think the architecture of that system would look like? Do you think you’d find the use cases at the center of the design? Or would you find the source code arranged to fit nicely into the pattern of the frameworks? Would you find business objects that looked suspiciously like database rows? Would the schema and the frameworks pollute everything? &lt;/p&gt;    &lt;p&gt;Here’s what an application should look like. The use cases should be the highest level and most visible architectural entities. The use cases are at the center. Always! Databases and frameworks are details! You don’t have to decide upon them up front. You can push them off until later, once you’ve got all the use cases and business rules figured out, written, and tested.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Eso: “una vez que los casos de usos y las reglas de negocio se determinaron/descubrieron, escribieron, y PROBARON”. &lt;/p&gt;  &lt;p&gt;A ver, repitan conmigo:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The center of your application are the use cases of your application.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;De nuevo, por favor, en serio:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;The center of your application are the use cases of your application.&lt;/p&gt;    &lt;p&gt;The center of your application are the use cases of your application.&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Bien, y ahora, a repetir cada día, frente al espejo:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Databases and frameworks are details!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Si, antes de lavarse los dientes a la mañana repetir:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Databases and frameworks are details!&lt;/p&gt;    &lt;p&gt;Databases and frameworks are details!&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;;-)&lt;/p&gt;  &lt;p&gt;Les aseguro que si repiten eso cada día, van a mejorar en sus “skills” de programación, van a mejorar en la calidad del software que engreguen, y van a desarrollar sin tener que pelearse con tecnologías adoptadas por que sí, o porque “era más fácil”.&lt;/p&gt;  &lt;p&gt;Recuerden también: “fácil” no es “simple”, y bien puede que lo “fácil” conspire con lo “simple”. Para traer un ejemplo concreto: Rails es “fácil”, permite generar una aplicación web con dos o tres comandos. Ahora, vayan y vean si es “simple” el código.&lt;/p&gt;  &lt;p&gt;Les recomiendo leer un “review” de alguna charla de “Uncle Bob” Martin, donde se evalúa lo de más arriba:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.codingthearchitecture.com/2011/11/06/the_delivery_mechanism_is_an_annoying_detail.html"&gt;The delivery mechanism is an annoying detail&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Ahí hay un Tweet de &lt;a href="http://twitter.com/unclebobmartin"&gt;@unclebobmartin&lt;/a&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;A good architecture allows you to defer framework decisions. A good architecture allows frameworks to act as plugins to the app&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;Bien, yo diría que las disciplinas ágiles y TDD en particular, permiten también diferir las decisiones. Ese un punto importante. Por ejemplo, en el ejemplo de la charla que mencioné al principio, DIFERI el diseño de la base de datos. Eso permite hacer cambios en las primeras iteraciones, SIN TENER la carga, el peso de la inercia de tener un esquema de tablas, datos cargados, etc.. Pueden ver ese approach en los post:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/06/27/writing_2D00_an_2D00_application_2D00_using_2D00_tdd_2D00_part_2D00_5_2D00_adding_2D00_views.aspx"&gt;Escribiendo una aplicación con TDD&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Y lean un ejemplo de Ron Jeffries:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://xprogramming.com/articles/but-we-need-a-database-dont-we/"&gt;http://xprogramming.com/articles/but-we-need-a-database-dont-we/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://xprogramming.com/articles/see-we-dont-need-a-database-yet/"&gt;http://xprogramming.com/articles/see-we-dont-need-a-database-yet/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Si en su equipo todavía hay resistencia a TDD, leer el post de Bob Martin:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.8thlight.com/uncle-bob/2012/01/11/Flipping-the-Bit.html"&gt;http://blog.8thlight.com/uncle-bob/2012/01/11/Flipping-the-Bit.html&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En mi charla se mencionó bibliografía. Uno de los libros mencionados fue el&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.dirigidoportests.com/el-libro"&gt;http://www.dirigidoportests.com/el-libro&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Les recomiendo leer el ejemplo que los autores describen al principio. Dos programadores, uno usando TDD, y otro trabajando rápido, adoptando frameworks, librerías, todo ya hecho, porque PARECE MAS FACIL, y hasta mejor. Lean el desenlace.&lt;/p&gt;  &lt;p&gt;Les puedo comentar un caso, sin dar mucho detalle: en un sistema, había que realizar las tareas A, B, C. Con TDD hubiéramos ido avanzando, tal vez escribiendo un método que invoque a A, B, C, y viendo de revisar, en los tests, los resultados de esas tareas. En vez de eso, se adoptó un “Job Engine”, porque “ya estaba hecho”. Como ese “job engine” funciona dentro de un entorno de tecnología que necesita (usando colas en la nube, monitoreo, etc…), probar que las tareas A, B, C se realicen, es todo un problema. Un año y medio despues, todavía se está analizando por qué algunas tareas se traban en el sitio de producción, o por qué un “job” tarda 15 o más minutos en lanzarse, desde que el pedido se puso en la cola.&lt;/p&gt;  &lt;p&gt;Bien, fue un post largo, y espero que haya sido de provecho para alguien. Un resumen:&lt;/p&gt;  &lt;p&gt;- Usen TDD guiado por los casos de uso, aceptando lo menos posible “bajadas de línea” sin justificación&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1812272" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>VAN en Alt.NET Hispano: Desarrollando una Aplicación con TDD</title><link>http://msmvps.com/blogs/lopez/archive/2012/06/18/van-en-alt-net-hispano-desarrollando-una-aplicaci-243-n-con-tdd.aspx</link><pubDate>Mon, 18 Jun 2012 16:29:07 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1811274</guid><dc:creator>lopez</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1811274</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/06/18/van-en-alt-net-hispano-desarrollando-una-aplicaci-243-n-con-tdd.aspx#comments</comments><description>&lt;p&gt;El sábado que viene, 23 de Junio, estaré en una VAN (reunión virtual) organizada por &lt;a href="http://altnethispano.org"&gt;el grupo Alt.NET Hispano&lt;/a&gt;, tratando el tema de cómo desarrollar una aplicación con TDD. El horario es el habitual 18pm GMT, en Buenos Aires tenemos GMT-3, y es 3 de la tarde hora local.&lt;/p&gt;  &lt;p&gt;Quiero mostrar cómo uso habitualmente TDD para ir desarrollando una aplicación. Usaré C#, una interfaz con ASP.NET MVC, y seguramente algún proyecto de clases donde ir poniendo el dominio. Estoy pensando más en detalle el dominio, quisiera uno que pudiera abarcar en las dos horas que tenemos disponibles, y que tuviera algunas reglas.&lt;/p&gt;  &lt;p&gt;Para mí, es muy importante usar TDD en código en producción. Me ha resultado muy útil, no sólo por la cobertura de tests que me permite refactorizar con confianza, sino por el proceso de diseño del código y de la aplicación en sí. En los últimos años le he agregado también la idea de que lo importante son los casos de uso, y darle menos peso a temas como el diseño de la base de datos que puede aparecer más adelante en un desarrollo ágil, no tiene por qué estar desde el principio.&lt;/p&gt;  &lt;p&gt;Ya escribí &lt;a href="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx"&gt;varios posts sobre desarrollo con TDD&lt;/a&gt; y mis proyectos personales públicos prácticamente están todos desarrollados con TDD (pueder ver mi &lt;a href="http://github.com/ajlopez"&gt;cuenta de GitHub&lt;/a&gt; cómo van avanzando test a test). Pero no había tenido la oportunidad de mostrar esta técnica en una VAN sobre una aplicación y un dominio. Espero que pueda mostrar qué bueno es aplicar TDD desde el comienzo, y cómo nos ayuda en un desarrollo ágil.&lt;/p&gt;  &lt;p&gt;Más información sobre Alt.NET Hispano en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://altnethispano.org/Inicio.aspx"&gt;http://altnethispano.org/Inicio.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sobre las reuniones VAN y cómo participar en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://altnethispano.org/reuniones/descripcion.aspx"&gt;http://altnethispano.org/reuniones/descripcion.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Las anteriores VAN han sido publicadas (en video) en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://altnethispano.org/reuniones/historico.aspx"&gt;http://altnethispano.org/reuniones/historico.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;El calendario de próximo eventos en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://altnethispano.org/reuniones/calendario.aspx"&gt;http://altnethispano.org/reuniones/calendario.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Nos leemos!&lt;/p&gt;  &lt;p&gt;Angel “Java” Lopez   &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1811274" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/.NET/default.aspx">.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ALT.NET/default.aspx">ALT.NET</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/ASP.NET+MVC/default.aspx">ASP.NET MVC</category></item><item><title>TDD Paso a Paso (6) La semana del panadero</title><link>http://msmvps.com/blogs/lopez/archive/2012/05/25/tdd-paso-a-paso-6-la-semana-del-panadero.aspx</link><pubDate>Fri, 25 May 2012 22:36:09 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1810311</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1810311</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/05/25/tdd-paso-a-paso-6-la-semana-del-panadero.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/05/09/tdd-paso-a-paso-5-lunes-como-d-237-a-no-laborable.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Sigamos mejorando la clase de calendario de días laborables. Quiero ahora plantear el caso:&lt;/p&gt;  &lt;p&gt;- El sábado y domingo se trabaja    &lt;br /&gt;- El lunes no se trabaja&lt;/p&gt;  &lt;p&gt;Acá en Argentina, es común que así sea la semana del panadero (aunque dado los tiempos que corren, muchos abren todos los días). Este es el test que me armé: configuro al calendario con sábado y domingo como días laborales, y lunes como no laborable. Luego se prueban esos tres días:&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;pre style="background-color:black;color:white;"&gt;&lt;span style="color:cyan;"&gt;[&lt;/span&gt;TestMethod&lt;span style="color:cyan;"&gt;]&lt;/span&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;void&lt;/span&gt; SetWeekendAsWorkingDaysAndMondayAsANonWorkingDay&lt;span style="color:cyan;"&gt;()&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	WorkingDaysCalendar calendar = &lt;span style="color:orange;"&gt;new&lt;/span&gt; WorkingDaysCalendar&lt;span style="color:cyan;"&gt;();&lt;/span&gt;

	calendar.AddDayOfWeekAsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek.Saturday&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
	calendar.AddDayOfWeekAsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek.Sunday&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
	calendar.AddDayOfWeekAsNonWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek.Monday&lt;span style="color:cyan;"&gt;);&lt;/span&gt;

	DateTime saturday = &lt;span style="color:orange;"&gt;new&lt;/span&gt; DateTime&lt;span style="color:cyan;"&gt;(&lt;/span&gt;2012&lt;span style="color:cyan;"&gt;,&lt;/span&gt; 3&lt;span style="color:cyan;"&gt;,&lt;/span&gt; 10&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
	Assert.AreEqual&lt;span style="color:cyan;"&gt;(&lt;/span&gt;saturday.DayOfWeek&lt;span style="color:cyan;"&gt;,&lt;/span&gt; DayOfWeek.Saturday&lt;span style="color:cyan;"&gt;);&lt;/span&gt;

	Assert.IsTrue&lt;span style="color:cyan;"&gt;(&lt;/span&gt;calendar.IsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;saturday&lt;span style="color:cyan;"&gt;));&lt;/span&gt;
	Assert.IsTrue&lt;span style="color:cyan;"&gt;(&lt;/span&gt;calendar.IsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;saturday.AddDays&lt;span style="color:cyan;"&gt;(&lt;/span&gt;1&lt;span style="color:cyan;"&gt;)));&lt;/span&gt;
	Assert.IsFalse&lt;span style="color:cyan;"&gt;(&lt;/span&gt;calendar.IsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;saturday.AddDays&lt;span style="color:cyan;"&gt;(&lt;/span&gt;2&lt;span style="color:cyan;"&gt;)));&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Al ejecutar este código, si tenemos la clase calendario del post anterior, da en rojo, porque no tengo contemplado más que un día especial por tipo: sólo un día laborable especial, o sólo un día no laborable especial. Pero al llegar a este test, puedo implementar mejor el algoritmo interno. Llegó la hora de tener una lista de días:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;pre style="background-color:black;color:white;"&gt;&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;class&lt;/span&gt; WorkingDaysCalendar
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;private&lt;/span&gt; IList&lt;span style="color:cyan;"&gt;&amp;lt;&lt;/span&gt;DayOfWeek&lt;span style="color:cyan;"&gt;&amp;gt;&lt;/span&gt; nonWorkingDaysOfWeek = &lt;span style="color:orange;"&gt;new&lt;/span&gt; List&lt;span style="color:cyan;"&gt;&amp;lt;&lt;/span&gt;DayOfWeek&lt;span style="color:cyan;"&gt;&amp;gt;()&lt;/span&gt; &lt;span style="color:cyan;"&gt;{&lt;/span&gt; DayOfWeek.Saturday&lt;span style="color:cyan;"&gt;,&lt;/span&gt; DayOfWeek.Sunday &lt;span style="color:cyan;"&gt;};&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;bool&lt;/span&gt; IsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DateTime day&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
		&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDaysOfWeek.Contains&lt;span style="color:cyan;"&gt;(&lt;/span&gt;day.DayOfWeek&lt;span style="color:cyan;"&gt;))&lt;/span&gt;
			&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;false&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

		&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;true&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;void&lt;/span&gt; AddDayOfWeekAsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek dayOfWeek&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
		&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDaysOfWeek.Contains&lt;span style="color:cyan;"&gt;(&lt;/span&gt;dayOfWeek&lt;span style="color:cyan;"&gt;))&lt;/span&gt;
			&lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDaysOfWeek.Remove&lt;span style="color:cyan;"&gt;(&lt;/span&gt;dayOfWeek&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

	&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;void&lt;/span&gt; AddDayOfWeekAsNonWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek dayOfWeek&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
		&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(!&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDaysOfWeek.Contains&lt;span style="color:cyan;"&gt;(&lt;/span&gt;dayOfWeek&lt;span style="color:cyan;"&gt;))&lt;/span&gt;
			&lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDaysOfWeek.Add&lt;span style="color:cyan;"&gt;(&lt;/span&gt;dayOfWeek&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
	&lt;span style="color:cyan;"&gt;}&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;Agregué una lista interna de días no laborables, sin cambiar la interfaz pública de la clase. ¿Pero habré cumplido con lo pedido con el test? Ejecuto, y da verde. ¿Pero no habré roto algo? Ejecuto el resto de los tests, también estan en verde. En cualquier caso, seguiría trabajando hasta que todo quede en verde. Luego, vendría refactorización. Por ejemplo, no estoy conforme conque los métodos comienzen con Add. No se agregan días, sólo se informa de su carácter de laborable o no laborable. Pero bueno, eso será para otro post.&lt;/p&gt;

&lt;p&gt;Próximos temas: refactorizar, soporte de días feriados, feriados puentes, etc…&lt;/p&gt;

&lt;p&gt;Nos leemos!&lt;/p&gt;

&lt;p&gt;Angel “Java” Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 

  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1810311" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item><item><title>TDD Paso a Paso (5) Lunes como día no laborable</title><link>http://msmvps.com/blogs/lopez/archive/2012/05/09/tdd-paso-a-paso-5-lunes-como-d-237-a-no-laborable.aspx</link><pubDate>Wed, 09 May 2012 09:11:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1809647</guid><dc:creator>lopez</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://msmvps.com/blogs/lopez/rsscomments.aspx?PostID=1809647</wfw:commentRss><comments>http://msmvps.com/blogs/lopez/archive/2012/05/09/tdd-paso-a-paso-5-lunes-como-d-237-a-no-laborable.aspx#comments</comments><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/04/24/tdd-paso-a-paso-4-otro-tipo-de-semana.aspx"&gt;Anterior post&lt;/a&gt;&amp;nbsp;&lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2012/05/25/tdd-paso-a-paso-6-la-semana-del-panadero.aspx"&gt;Siguiente post&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Veamos ahora otro test, que como los anteriores, nos va a obligar a implementar mejor nuestro software en construcci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Queremos configurar, sobre la semana b&amp;aacute;sica, cu&amp;aacute;les son los d&amp;iacute;as laborables y cu&amp;aacute;les son no laborables. En el anterior post, agregu&amp;eacute; la capacidad de especificar un nuevo d&amp;iacute;a laboral. Ahora, quiero poder especificar que los lunes son no laborables. Este es el test que escrib&amp;iacute;:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="background-color:black;color:white;"&gt;&lt;span style="color:cyan;"&gt;[&lt;/span&gt;TestMethod&lt;span style="color:cyan;"&gt;]&lt;/span&gt;
&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;void&lt;/span&gt; SetMondayAsANonWorkingDay&lt;span style="color:cyan;"&gt;()&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	WorkingDaysCalendar calendar = &lt;span style="color:orange;"&gt;new&lt;/span&gt; WorkingDaysCalendar&lt;span style="color:cyan;"&gt;();&lt;/span&gt;

	calendar.AddDayOfWeekAsNonWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek.Monday&lt;span style="color:cyan;"&gt;);&lt;/span&gt;

	DateTime monday = &lt;span style="color:orange;"&gt;new&lt;/span&gt; DateTime&lt;span style="color:cyan;"&gt;(&lt;/span&gt;2012&lt;span style="color:cyan;"&gt;,&lt;/span&gt; 3&lt;span style="color:cyan;"&gt;,&lt;/span&gt; 12&lt;span style="color:cyan;"&gt;);&lt;/span&gt;
	Assert.AreEqual&lt;span style="color:cyan;"&gt;(&lt;/span&gt;monday.DayOfWeek&lt;span style="color:cyan;"&gt;,&lt;/span&gt; DayOfWeek.Monday&lt;span style="color:cyan;"&gt;);&lt;/span&gt;

	Assert.IsFalse&lt;span style="color:cyan;"&gt;(&lt;/span&gt;calendar.IsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;monday&lt;span style="color:cyan;"&gt;));&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Primero, no compila. Porque usa el m&amp;eacute;todo no existente, &lt;strong&gt;AddDayOfWeekAsNonWorkingDay &lt;/strong&gt;. Lo creo, lanzando una excepci&amp;oacute;n de no implementado, ejecuto el test, y da rojo. Pongamos el m&amp;iacute;nimo c&amp;oacute;digo que hace que esto funcione, con alg&amp;uacute;n refactor de nombre de par&amp;aacute;metros.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="background-color:black;color:white;"&gt;&lt;span style="color:orange;"&gt;private&lt;/span&gt; DayOfWeek&lt;span style="color:cyan;"&gt;?&lt;/span&gt; workingDay&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
&lt;span style="color:orange;"&gt;private&lt;/span&gt; DayOfWeek&lt;span style="color:cyan;"&gt;?&lt;/span&gt; nonWorkingDay&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;bool&lt;/span&gt; IsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DateTime day&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.workingDay.HasValue &lt;span style="color:cyan;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:orange;"&gt;this&lt;/span&gt;.workingDay.Value == day.DayOfWeek&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;true&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

	&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;&lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDay.HasValue &lt;span style="color:cyan;"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDay.Value == day.DayOfWeek&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;false&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

	&lt;span style="color:orange;"&gt;if&lt;/span&gt; &lt;span style="color:cyan;"&gt;(&lt;/span&gt;day.DayOfWeek == DayOfWeek.Sunday &lt;span style="color:cyan;"&gt;||&lt;/span&gt; day.DayOfWeek == DayOfWeek.Saturday&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
		&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;false&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;

	&lt;span style="color:orange;"&gt;return&lt;/span&gt; &lt;span style="color:orange;"&gt;true&lt;/span&gt;&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;void&lt;/span&gt; AddDayOfWeekAsWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek dayOfWeek&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;this&lt;/span&gt;.workingDay = dayOfWeek&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;

&lt;span style="color:orange;"&gt;public&lt;/span&gt; &lt;span style="color:orange;"&gt;void&lt;/span&gt; AddDayOfWeekAsNonWorkingDay&lt;span style="color:cyan;"&gt;(&lt;/span&gt;DayOfWeek dayOfWeek&lt;span style="color:cyan;"&gt;)&lt;/span&gt;
&lt;span style="color:cyan;"&gt;{&lt;/span&gt;
	&lt;span style="color:orange;"&gt;this&lt;/span&gt;.nonWorkingDay = dayOfWeek&lt;span style="color:cyan;"&gt;;&lt;/span&gt;
&lt;span style="color:cyan;"&gt;}&lt;/span&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ahora el test est&amp;aacute; en verde. Agregu&amp;eacute; una nueva variable interna &amp;ldquo;nullable&amp;rdquo; &lt;strong&gt;nonWorkingDay&lt;/strong&gt;. Ciertamente que la clase escrita s&amp;oacute;lo soporta un s&amp;oacute;lo d&amp;iacute;a laborable configurable y un s&amp;oacute;lo d&amp;iacute;a no laborable configurable. Pero los tests que escribimos pasan. Voy por &amp;ldquo;baby steps&amp;rdquo;, de a &amp;ldquo;pasos de beb&amp;eacute;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Pero van viendo la aplicaci&amp;oacute;n de TDD: en cada test, hay una nueva especificaci&amp;oacute;n de c&amp;oacute;mo queremos que act&amp;uacute;e nuestro software en construcci&amp;oacute;n. Y s&amp;oacute;lo implementamos lo que necesitamos para pasar el test. Poco a poco, va emergiendo la implementaci&amp;oacute;n interna, donde ponemos lo que conocemos como programadores. Pero sin caer en la tentanci&amp;oacute;n de &amp;ldquo;Ah! ac&amp;aacute; pongo esto que lo voy a necesitar&amp;rdquo;. Si el test no lo necesita, nosotros tampoco :-)&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;
&lt;p&gt;Angel &amp;ldquo;Java&amp;rdquo; Lopez 
  &lt;br /&gt;&lt;a href="http://www.ajlopez.com"&gt;http://www.ajlopez.com&lt;/a&gt; 
  &lt;br /&gt;&lt;a href="http://twitter.com/ajlopez"&gt;http://twitter.com/ajlopez&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://msmvps.com/aggbug.aspx?PostID=1809647" width="1" height="1"&gt;</description><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+de+Software/default.aspx">Desarrollo de Software</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/C+Sharp/default.aspx">C Sharp</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/Desarrollo+Agil/default.aspx">Desarrollo Agil</category><category domain="http://msmvps.com/blogs/lopez/archive/tags/TDD/default.aspx">TDD</category></item></channel></rss>