<?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>Search results for 'app:weblogs' matching tags 'TDD' and 'QUnit'</title><link>http://msmvps.com/search/SearchResults.aspx?q=app:weblogs&amp;tag=TDD,QUnit&amp;orTags=0&amp;o=DateDescending</link><description>Search results for 'app:weblogs' matching tags 'TDD' and 'QUnit'</description><dc:language>en-US</dc:language><generator>CommunityServer 2008.5 SP2 (Build: 40407.4157)</generator><item><title>Programando Juegos Sociales en L&amp;#237;nea (Parte 6) Armando y Probando el Juego y los Servicios con TDD y QUnit</title><link>http://msmvps.com/blogs/lopez/archive/2011/12/30/social_2D00_games_2D00_programming_2D00_part_2D00_6_2D00_testing_2D00_game_2D00_and_2D00_service_2D00_with_2D00_tdd_2D00_and_2D00_qunit.aspx</link><pubDate>Fri, 30 Dec 2011 06:00:00 GMT</pubDate><guid isPermaLink="false">d67277c4-116b-43f1-b688-e9ef184ea916:1804233</guid><dc:creator>lopez</dc:creator><description>&lt;p&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/12/01/social_2D00_online_2D00_games_2D00_programming_2D00_part_2D00_5_2D00_new_2D00_azure_2D00_toolkit.aspx"&gt;Anterior Post&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;En mi anterior post, comenté la nueva versión 1.1 (hay ahora una 1.2 Beta) del &lt;a href="http://watgames.codeplex.com/"&gt;Windows Azure Toolkit for Social Games&lt;/a&gt;. Tiene juegos simples para demostrar el uso de Javascript, HTML5, procesamiento de movidas del juego, uso de Azure web roles y worker roles. Veamos de explorar en este post el armado de la lógica del juego, en Javascript, usando TDD (Test-Driven Development) y QUnit.&lt;/p&gt;  &lt;p&gt;Hay tests en línea en:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://watgames4.cloudapp.net/Test"&gt;http://watgames4.cloudapp.net/Test&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/watgames05.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Ejecutemos los test de Tic Tac Toe Game Logic:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://watgames4.cloudapp.net/Samples/ClientTest/TicTacToeGameTest"&gt;http://watgames4.cloudapp.net/Samples/ClientTest/TicTacToeGameTest&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/watgames06.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;Esta página está usando QUnit para tests en el cliente usando Javascripot. Escribí posts introductorios:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://ajlopez.wordpress.com/2011/07/11/tdd-with-javascript-and-qunit/"&gt;TDD with Javascript and QUnit&lt;/a&gt;    &lt;br /&gt;&lt;a href="http://msmvps.com/blogs/lopez/archive/2011/07/12/tdd_2D00_with_2D00_javascript_2D00_and_2D00_qunit.aspx"&gt;TDD con Javascript y QUnit&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;La página que visitamos está probando la lógica del juego de Ta Te Ti. Recordemos, cada juego está implementado en partes, la lógica es una de ellas:&lt;/p&gt;  &lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/watgames07.png" alt="" /&gt; &lt;/p&gt;  &lt;p&gt;El código cliente reside en &lt;strong&gt;TicTacToeGame.js&lt;/strong&gt; dentro del proyecto &lt;strong&gt;SocialGames.Web&lt;/strong&gt;. Sus primeras líneas:&lt;/p&gt;  &lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;TTTColor = { Empty: 0, Cross: 1, Circle: 2 };
&lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; TicTacToeGame() {
    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.board = [
     [TTTColor.Empty, TTTColor.Empty, TTTColor.Empty],
     [TTTColor.Empty, TTTColor.Empty, TTTColor.Empty],
     [TTTColor.Empty, TTTColor.Empty, TTTColor.Empty]
     ];
}
TicTacToeGame.&lt;span style="color:#0000ff;"&gt;prototype&lt;/span&gt;.move = &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; (x, y, color) {
    &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.board[x][y] = color;
};
TicTacToeGame.&lt;span style="color:#0000ff;"&gt;prototype&lt;/span&gt;.isEmpty = &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; (x, y) {
    &lt;span style="color:#0000ff;"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;this&lt;/span&gt;.board[x][y] == TTTColor.Empty;
};
....
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;La vista razor (&lt;strong&gt;TicTacToeGameTest.cshtml&lt;/strong&gt;) fue escrita al mismo tiempo que la lógica, usando TDD (Test-Driven Development). Veamos los primeros tests:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;test(&amp;quot;&lt;span style="color:#8b0000;"&gt;Create Empty Board&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; () {
    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; game = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TicTacToeGame();
    &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; x = 0; x &amp;lt; 3; x++)
        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; y = 0; y &amp;lt; 3; y++)
            ok(game.isEmpty(x, y));
    equal(game.isTie(), &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;);
    equal(game.hasWinner(), &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;);
});
test(&amp;quot;&lt;span style="color:#8b0000;"&gt;Valid Moves on Empty Board&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; () {
    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; game = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TicTacToeGame();
    &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; x = 0; x &amp;lt; 3; x++)
        &lt;span style="color:#0000ff;"&gt;for&lt;/span&gt; (&lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; y = 0; y &amp;lt; 3; y++) {
            ok(game.isValid(x, y, TTTColor.Cross));
            ok(game.isValid(x, y, TTTColor.Circle));
        }
});
test(&amp;quot;&lt;span style="color:#8b0000;"&gt;No Winner in Empty Board&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; () {
    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; game = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TicTacToeGame();
    equal(game.getWinner(), TTTColor.Empty);
});
test(&amp;quot;&lt;span style="color:#8b0000;"&gt;Get Winner in First Row&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; () {
    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; game = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; TicTacToeGame();
    game.move(0, 0, TTTColor.Cross);
    game.move(1, 0, TTTColor.Cross);
    game.move(2, 0, TTTColor.Cross);
    equal(game.getWinner(), TTTColor.Cross);
    equal(game.isTie(), &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;);
    equal(game.hasWinner(), &lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;);
});
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;La idea es avanzar de a pequeños pasos, test por test, diseñando la API de la lógica del juego, y su conducta esperada. De esta manera, vamos avanzando sin gastar tanto tiempo en prueba manual, y menos tiempo en depuración. Esto es recomendable, pero más aún cuando se trabaja con un lenguaje dinámico como Javascript. Una batería de pruebas puede salvarnos el día en caso de un refactoreo grande. Vean que el Four In A Row siguió un camino similar.&lt;/p&gt;

&lt;p&gt;Bien, no todo puede ser testeado fácilmente, o construido usando TDD. Algunos de los servicios agnósticos del juego (es decir, independientes del juego que se implemente) estan usando Ajax y Blob Storage, y para probarlos debemos considerar el uso de Ajax asincrónico (pueden comenzar construyendo tests sincrónicos si quieren). Pueden ver:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://watgames4.cloudapp.net/Test/ServerInterfaceTest"&gt;http://watgames4.cloudapp.net/Test/ServerInterfaceTest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(Para esta página, deben ingresar usando una cuenta de Facebook o de Windows Live ID, el ejemplo usa Federated Security y Access Control Service (ACS))&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/watgames08.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Esta vez, el sistema bajo prueba es el Service Interface:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://www.ajlopez.com/images/articles2/watgames09.png" alt="" /&gt; &lt;/p&gt;

&lt;p&gt;Hay algunos trucos en el código de prueba (&lt;strong&gt;ServerInterfaceTest.cshmlt&lt;/strong&gt;), un fragmento:&lt;/p&gt;

&lt;pre&gt;&lt;pre style="background-color:#ffffff;margin:0em;width:100%;font-family:consolas,courier,monospace;font-size:12px;"&gt;test(&amp;quot;&lt;span style="color:#8b0000;"&gt;Call User/Verify&lt;/span&gt;&amp;quot;, &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; () {
    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; success = &lt;span style="color:#0000ff;"&gt;function&lt;/span&gt; (result) { ok(&lt;span style="color:#0000ff;"&gt;true&lt;/span&gt;); start(); };
    &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; error = ajaxGetError;
    &lt;span style="color:#0000ff;"&gt;stop&lt;/span&gt;(10000);
    expect(1);
    si.sendAjaxGet(apiURL + &amp;quot;&lt;span style="color:#8b0000;"&gt;user/verify&lt;/span&gt;&amp;quot;, success);
});
&lt;/pre&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;expect&lt;/strong&gt; es una función provista por QUnit que prepara al framework para recibir un &lt;strong&gt;ok(true) &lt;/strong&gt;alguna vez durante la ejecución de la prueba. Esa confirmación se incluye en la función callback &lt;strong&gt;success&lt;/strong&gt; que será llamada luego de la ejecución exitosa de la llamada asincrónica &lt;strong&gt;.sendAjaxGet&lt;/strong&gt;. La vida Async no es fácil ;-)&lt;/p&gt;

&lt;p&gt;Más análisis del código en próximos posts. Debería adaptar algún juego para que use Node.js para procesar sus jugadas.&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;</description></item></channel></rss>