<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://geeks.ms/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>devnettips</title><link>http://geeks.ms/blogs/devnettips/default.aspx</link><description>Nuestra visión del desarrollo y las metodologías ágiles</description><dc:language /><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Se buscan beta testers</title><link>http://geeks.ms/blogs/devnettips/archive/2013/04/05/se-buscan-beta-testers.aspx</link><pubDate>Fri, 05 Apr 2013 06:29:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:209066</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=209066</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2013/04/05/se-buscan-beta-testers.aspx#comments</comments><description>&lt;p&gt;Hola a todos,&lt;/p&gt;
&lt;p&gt;los amigos de &lt;a target="_blank" title="Plastic SCM" href="http://www.plasticscm.com/"&gt;Plastic SCM&lt;/a&gt;, &amp;nbsp;est&amp;aacute;n buscando beta testers para su nueva herramienta de merging, como ellos mismos dicen, su &amp;quot;mergetool&amp;quot; que entiende tu c&amp;oacute;digo. Est&amp;aacute;n buscando&amp;nbsp;&lt;span&gt;p&amp;uacute;blico espec&amp;iacute;fico Microsoft que desarrolle en .NET (c#,&amp;nbsp;&lt;/span&gt;vb.net&lt;span&gt;) y que le interesen temas de merge. Aqu&amp;iacute; ten&amp;eacute;is los detalles de la petici&amp;oacute;n:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;La panacea del merge de ficheros de c&amp;oacute;digo que todos hemos deseado alguna vez es una herramienta que sea capaz de operar m&amp;eacute;todo a m&amp;eacute;todo, using a using, clase a clase en lugar de l&amp;iacute;nea a l&amp;iacute;nea. Algo capaz de entender que si un developer toca el m&amp;eacute;todo GetHostName() y otro mueve GetHostName() de sitio en el mismo fichero, se trata del mismo m&amp;eacute;todo, y aplique el movido y el cambio sin generar conflictos absurdos. Suena bien, no?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Pues esa herramienta existe, basada en el n&amp;uacute;cleo de merge de Plastic SCM pero disponible como standalone tool para TFS, Git, SVN... o el control de versiones que uses...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;De hecho, est&amp;aacute;n buscando &amp;quot;early adopters&amp;quot; que quieran proponer sugerencias, mejoras y por supuesto reportar bugs!!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Si te interesa, est&amp;aacute; disponible para lenguajes .net aqu&amp;iacute;:&amp;nbsp;&lt;/span&gt;&lt;a target="_blank" href="http://plasticscm.com/sm/index.html"&gt;http://plasticscm.com/sm/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Venga, animaros a ayudarles, que son buena gente y tienen un muy buen producto.&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=209066" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/merging/default.aspx">merging</category></item><item><title>Testing with CasperJs - Introduction</title><link>http://geeks.ms/blogs/devnettips/archive/2013/03/27/testing-with-casperjs-introduction.aspx</link><pubDate>Wed, 27 Mar 2013 15:38:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:208949</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=208949</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2013/03/27/testing-with-casperjs-introduction.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;(Crossposting from&lt;a href="http://vgaltes.com/index.php/2013/03/14/testing-with-casperjs-part-1/%20" title="vgaltes.com" target="_blank"&gt; vgaltes.com&lt;/a&gt; )&lt;/p&gt;
&lt;p&gt;Today we will start a serie of tutorials about testing websites using CasperJS. We will cover installation and basic error detection, integration with a Team Foundation Server build and executing tests.&lt;/p&gt;
&lt;h2&gt;What is CasperJS?&lt;/h2&gt;
&lt;p&gt;In words of its creators,&amp;nbsp;&lt;a title="CasperJS" href="http://casperjs.org/" target="_blank"&gt;CasperJS&lt;/a&gt;&amp;nbsp;is an open source&amp;nbsp;navigation scripting &amp;amp; testing utility&amp;nbsp;written in Javascript and based on&amp;nbsp;&lt;a title="PhantomJS" href="http://www.phantomjs.org/" target="_blank"&gt;PhantomJS&lt;/a&gt;&amp;nbsp;&amp;mdash; the scriptable headless&amp;nbsp;&lt;a title="WebKit" href="http://www.webkit.org/" target="_blank"&gt;WebKit&lt;/a&gt;&amp;nbsp;engine. It eases the process of&amp;nbsp;defining a full navigation scenario&amp;nbsp;and provides useful&amp;nbsp;high-level functions, methods &amp;amp; syntactic sugar&amp;nbsp;for doing common tasks.&lt;/p&gt;
&lt;h2&gt;Installation&lt;/h2&gt;
&lt;p&gt;First of all we have to download the latest version of&amp;nbsp;&lt;a title="Download PhantomJS" href="http://phantomjs.googlecode.com/files/phantomjs-1.8.2-windows.zip" target="_blank"&gt;PhantomJS&lt;/a&gt;&amp;nbsp;and extract the contact where you want. After that it&amp;rsquo;s recommended to add this path to your PATH environment variable.&lt;/p&gt;
&lt;p&gt;Now you can download the tag 1.0.2 of&amp;nbsp;&lt;a title="CasperJS repository" href="https://github.com/n1k0/casperjs" target="_blank"&gt;CasperJS&lt;/a&gt;&amp;nbsp;repository on&amp;nbsp;&lt;a title="GitHub" href="https://github.com/" target="_blank"&gt;GitHub&lt;/a&gt;. You can clone the repository and checkout this tag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone git://github.com/n1k0/casperjs.git $ cd casperjs $ git checkout tags/1.0.2&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or you can download directly from&amp;nbsp;&lt;a title="CasperJS tag 1.0.2" href="https://github.com/n1k0/casperjs/archive/1.0.2.zip" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As before,&amp;nbsp;it&amp;rsquo;s recommended to add the path where you have downloaded CasperJS to your PATH environment variable. But don&amp;rsquo;t add the base path, add the batchbin folder.&lt;/p&gt;
&lt;h2&gt;First steps&lt;/h2&gt;
&lt;p&gt;To test CasperJS we will use the web site created by the MVC internet application template of Visual Studio 2012. If you are not a .Net developer, please create a simple website with your prefered technology, and skip this step.&lt;/p&gt;
&lt;p&gt;For .Net developers, open your VS2012 in administrator mode and create a new project with the MVC4 application project type&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://vgaltes.com/wp-content/uploads/2013/03/ProjectCreation1.png"&gt;&lt;img class="size-medium wp-image-32 " alt="Project template" src="http://vgaltes.com/wp-content/uploads/2013/03/ProjectCreation1-300x207.png" width="300" height="207" /&gt;&lt;/a&gt;Project template&lt;/p&gt;
&lt;p&gt;And now chose the internet application template&lt;/p&gt;
&lt;p&gt;&lt;a href="http://vgaltes.com/wp-content/uploads/2013/03/ProjectCreation2.png"&gt;&lt;img class=" wp-image-34 alignnone" alt="ProjectCreation2" src="http://vgaltes.com/wp-content/uploads/2013/03/ProjectCreation2.png" width="683" height="619" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;In order to facilitate our job, we will create a new web site on IIS and link it to our brand-new project. So please, open IIS manager and create a new website&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://vgaltes.com/wp-content/uploads/2013/03/webSiteCreation.png"&gt;&lt;img class="size-full wp-image-35 " alt="Web site creation" src="http://vgaltes.com/wp-content/uploads/2013/03/webSiteCreation.png" width="599" height="576" /&gt;&lt;/a&gt;Web site creation&lt;/p&gt;
&lt;p&gt;And now open the properties window of the web site application project in VS2012 and associate the project to the new web site we&amp;rsquo;ve just created&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://vgaltes.com/wp-content/uploads/2013/03/projectProperties.png"&gt;&lt;img class="size-full wp-image-36" alt="project properties" src="http://vgaltes.com/wp-content/uploads/2013/03/projectProperties.png" width="1199" height="900" /&gt;&lt;/a&gt;project properties&lt;/p&gt;
&lt;p&gt;Now, add a folder under the Scripts folder and create a new JavaScript file called testCasperJS.js.&lt;/p&gt;
&lt;h2&gt;Working with CasperJS&lt;/h2&gt;
&lt;p&gt;All the scripts start with a call to &amp;lsquo;create&amp;rsquo; method. The simplest way to do it is this:&lt;/p&gt;
&lt;div id="highlighter_249297" class="syntaxhighlighter  Brush"&gt;
&lt;div class="lines"&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush keyword"&gt;var&lt;/code&gt;&amp;nbsp;&lt;code class="Brush plain"&gt;casper = require(&lt;/code&gt;&lt;code class="Brush string"&gt;&amp;#39;casper&amp;#39;&lt;/code&gt;&lt;code class="Brush plain"&gt;).create();&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You can pass a javascript settings object to this method with several parameters. For example, we could set the viewport size:&lt;/p&gt;
&lt;div id="highlighter_310685" class="syntaxhighlighter  Brush"&gt;
&lt;div class="lines"&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush keyword"&gt;var&lt;/code&gt;&amp;nbsp;&lt;code class="Brush plain"&gt;casper = require(&lt;/code&gt;&lt;code class="Brush string"&gt;&amp;#39;casper&amp;#39;&lt;/code&gt;&lt;code class="Brush plain"&gt;).create({&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="line alt2"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="spaces"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code class="Brush plain"&gt;viewportSize: {width: 1024, height: 768}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush plain"&gt;});&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The next function we need to call is &amp;lsquo;start&amp;rsquo;. This call could be without parameters or we could pass an Url and the function that will be called after the page downloading.&lt;/p&gt;
&lt;div id="highlighter_976098" class="syntaxhighlighter  Brush"&gt;
&lt;div class="lines"&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush plain"&gt;casper.start(&lt;/code&gt;&lt;code class="Brush string"&gt;&amp;#39;&lt;a href="http://localhost:8000/"&gt;http://localhost:8000/&lt;/a&gt;&amp;#39;&lt;/code&gt;&lt;code class="Brush plain"&gt;,&amp;nbsp;&lt;/code&gt;&lt;code class="Brush keyword"&gt;function&lt;/code&gt;&amp;nbsp;&lt;code class="Brush plain"&gt;() {&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="line alt2"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="spaces"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code class="Brush keyword"&gt;this&lt;/code&gt;&lt;code class="Brush plain"&gt;.echo(&lt;/code&gt;&lt;code class="Brush string"&gt;&amp;#39;page downloaded: &amp;#39;&lt;/code&gt;&amp;nbsp;&lt;code class="Brush plain"&gt;+&amp;nbsp;&lt;/code&gt;&lt;code class="Brush keyword"&gt;this&lt;/code&gt;&lt;code class="Brush plain"&gt;.getCurrentUrl());&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush plain"&gt;});&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Now, we only need one more code block to end our first CasperJS script&lt;/p&gt;
&lt;div id="highlighter_280258" class="syntaxhighlighter  Brush"&gt;
&lt;div class="lines"&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush plain"&gt;casper.run(&lt;/code&gt;&lt;code class="Brush keyword"&gt;function&lt;/code&gt;&amp;nbsp;&lt;code class="Brush plain"&gt;() {&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="line alt2"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;2&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="spaces"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;code class="Brush keyword"&gt;this&lt;/code&gt;&lt;code class="Brush plain"&gt;.echo(&lt;/code&gt;&lt;code class="Brush string"&gt;&amp;quot;Done.&amp;quot;&lt;/code&gt;&lt;code class="Brush plain"&gt;).exit();&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;3&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush plain"&gt;});&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;With this code, we are indicating to CasperJS that we want to run our script and that, when it finishes we &amp;nbsp;want to write &amp;lsquo;Done&amp;rsquo; in the console and exit CasperJS.&lt;/p&gt;
&lt;p&gt;Right now, we could save our script, open a Command Prompt, go where the script is located and write&lt;/p&gt;
&lt;div id="highlighter_273703" class="syntaxhighlighter  Brush"&gt;
&lt;div class="lines"&gt;
&lt;div class="line alt1"&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td class="number"&gt;&lt;code&gt;1&lt;/code&gt;&lt;/td&gt;
&lt;td class="content"&gt;&lt;code class="Brush plain"&gt;casperjs testCasperJs.js&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;And we will see the result of our script&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://vgaltes.com/wp-content/uploads/2013/03/scriptResult.png"&gt;&lt;img class="size-full wp-image-42" alt="script result" src="http://vgaltes.com/wp-content/uploads/2013/03/scriptResult.png" width="677" height="343" /&gt;&lt;/a&gt;script result&lt;/p&gt;
&lt;h2&gt;Conclusions&lt;/h2&gt;
&lt;p&gt;In this post we have seen how to install CasperJS and how to make a very simple script. In the next posts of this series, we will see more operations to use and how to integrate all these scripts in a build for our Team Foundation Server.&lt;/p&gt;
&lt;p&gt;See you soon!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208949" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/CasperJs/default.aspx">CasperJs</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/testing/default.aspx">testing</category></item><item><title>Actualización de febrero de TFSService</title><link>http://geeks.ms/blogs/devnettips/archive/2013/02/11/actualizaci-243-n-de-febrero-de-tfsservice.aspx</link><pubDate>Mon, 11 Feb 2013 20:52:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:208537</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=208537</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2013/02/11/actualizaci-243-n-de-febrero-de-tfsservice.aspx#comments</comments><description>&lt;p&gt;Buenas a todos,&lt;/p&gt;
&lt;p&gt;se acaba de anunciar el despliegue de la actualizaci&amp;oacute;n de febrero de TFSService. Despu&amp;eacute;s de las grandes novedades del sprint pasado capitaneadas por el soporte a Git ha tocado un sprint m&amp;aacute;s tranquilo pero no por ello m&amp;aacute;s interesante. Una de las principales novedades, y algo que ech&amp;eacute; de menos justo la semana pasada, es la posibilidad de configurar una build de integraci&amp;oacute;n continua teniendo un repositorio de Git. Sin duda una caracter&amp;iacute;stica muy importante en todo buen sistema de integraci&amp;oacute;n continua.&lt;/p&gt;
&lt;p&gt;Pod&amp;eacute;is leer m&amp;aacute;s detalles de la release en el &lt;a href="http://blogs.msdn.com/b/bharry/archive/2013/02/11/team-foundation-service-update-feb-11.aspx" title="Post de Brian Harry" target="_blank"&gt;post &lt;/a&gt;de &lt;a href="http://blogs.msdn.com/b/bharry/" title="Brian Harry" target="_blank"&gt;Brian Harry&lt;/a&gt; y en el &lt;a href="http://tfs.visualstudio.com/en-us/home/news/2013/feb-11/" title="novedades TFSService" target="_blank"&gt;feed &lt;/a&gt;de novedades de &lt;a href="http://tfs.visualstudio.com" title="TFSService" target="_self"&gt;TFSService&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;
&lt;p&gt;EDIT: para activar las builds de integraci&amp;oacute;n continua necesit&amp;aacute;is la CTP3 del Update 2 de Visual Studio 2012. La pod&amp;eacute;is descargar &lt;a target="_blank" title="CTP3 Update 2" href="http://www.microsoft.com/en-us/download/details.aspx?id=36539"&gt;aqu&amp;iacute;&lt;/a&gt;.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208537" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Actualizaci_26002300_243_3B00_n/default.aspx">Actualizaci&amp;#243;n</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/TFSService/default.aspx">TFSService</category></item><item><title>Cobertura de código en JavaScript con Blanket.js</title><link>http://geeks.ms/blogs/devnettips/archive/2013/01/05/code-coverage-en-javascript-con-blanket-js.aspx</link><pubDate>Sat, 05 Jan 2013 21:06:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:208140</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=208140</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2013/01/05/code-coverage-en-javascript-con-blanket-js.aspx#comments</comments><description>&lt;p&gt;Hac&amp;iacute;a tiempo que andaba buscando una manera de calcular la cobertura de c&amp;oacute;digo en JavaScript. Con el amigo &lt;a href="http://geeks.ms/blogs/aarroyo/default.aspx" title="Andoni Arroyo" target="_blank"&gt;Andoni&lt;/a&gt; hab&amp;iacute;amos visto algunas soluciones que no ve&amp;iacute;amos claras y parec&amp;iacute;a que al final tendr&amp;iacute;amos que acabar tirando de &lt;a href="http://code.google.com/p/js-test-driver/" title="jsTestDriver" target="_blank"&gt;jsTestDriver &lt;/a&gt;que tiene una herramienta para calcular la cobertura de c&amp;oacute;digo. Lo malo de esto es que no nos val&amp;iacute;a la&amp;nbsp;infraestructura&amp;nbsp;que ahora tenemos montada para pasar los tests y esto nos complicaba un poco la vida.&lt;/p&gt;
&lt;p&gt;Pero el otro d&amp;iacute;a llegaba a mi timeline un tweet del amigo &lt;a href="https://twitter.com/jjcoellov" title="@jjcoellov" target="_blank"&gt;Juanjo Coello&lt;/a&gt; como este:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/tweet.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/tweet.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y la verdad es que la librer&amp;iacute;a funciona muy bien. Aqu&amp;iacute; van los pasos que ten&amp;eacute;is que seguir si la quer&amp;eacute;is utilizar junto con &lt;a href="http://pivotal.github.com/jasmine/" title="Jasmine" target="_blank"&gt;Jasmine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;1.- Bajarse la librer&amp;iacute;a. La pod&amp;eacute;is descargar aqu&amp;iacute;:&amp;nbsp;&lt;a target="_blank" title="Blanket" href="http://migrii.github.com/blanket/"&gt;http://migrii.github.com/blanket/&lt;/a&gt;&lt;br /&gt;2.- Bajarse el adapter de Blanket para Jasmine de aqu&amp;iacute;:&amp;nbsp;&lt;a target="_blank" title="Jasmine adapter" href="https://raw.github.com/Migrii/blanket/master/src/adapters/jasmine-blanket.js"&gt;https://raw.github.com/Migrii/blanket/master/src/adapters/jasmine-blanket.js&lt;/a&gt;&lt;br /&gt;3.- En el runner de Jasmine (t&amp;iacute;picamente SpecRunner.html) incluir el script de blanket y el adapter de Jasmine de la siguiente manera:&lt;/p&gt;
&lt;p&gt;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;../libs/blanket/blanket.min.js&amp;quot; data-cover-adapter=&amp;quot;../libs/blanket/jasmine-blanket.js&amp;quot; &amp;gt;&amp;lt;/script&amp;gt;&lt;/p&gt;
&lt;p&gt;Para incluir los archivos a los que queremos pasar la cobertura de c&amp;oacute;digo tenemos dos opciones. La primera es utilizar esta misma l&amp;iacute;nea que acabamos de escribir. Utilizando el atributo data-cover-only podemos indicar los archivos a los que queremos pasar la cobertura, ya sea con una expresi&amp;oacute;n regular, con un string con &amp;quot;comodines&amp;quot; o con un array de nombres de archivo. Un posible ejemplo ser&amp;iacute;a el siguiente:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&amp;lt;script src=&amp;quot;blanket.min.js&amp;quot; data-cover-adapter=&amp;quot;jasmine-blanket.js&amp;quot; data-cover-only=&amp;quot;[&amp;#39;source1.js&amp;#39;,&amp;#39;src/source2.js&amp;#39;]&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Y ya est&amp;aacute;, ya lo tenemos todo configurado. Ahora solo falta pasar los tests y al final del archivo se nos adjuntar&amp;aacute; la informaci&amp;oacute;n sobre la cobertura.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/blanketResults.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/blanketResults.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Saludos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=208140" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Testeo+unitario/default.aspx">Testeo unitario</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Jasmine/default.aspx">Jasmine</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/cobertura+c_26002300_243_3B00_digo/default.aspx">cobertura c&amp;#243;digo</category></item><item><title>Espiando a jQuery</title><link>http://geeks.ms/blogs/devnettips/archive/2012/12/02/espiando-a-jquery.aspx</link><pubDate>Sun, 02 Dec 2012 21:03:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207673</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=207673</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/12/02/espiando-a-jquery.aspx#comments</comments><description>&lt;p&gt;Como vimos en un anterior &lt;a href="http://geeks.ms/blogs/devnettips/archive/2012/06/08/nuestro-primer-spy-con-jasmine.aspx" title="Nuestro primer spy con Jasmine" target="_blank"&gt;art&amp;iacute;culo&lt;/a&gt;, podemos utilizar &lt;a href="http://pivotal.github.com/jasmine/" title="Jasmine" target="_blank"&gt;Jasmine&lt;/a&gt; para espiar a &lt;a href="http://jquery.com/" title="jQuery" target="_blank"&gt;jQuery&lt;/a&gt;. En aqu&amp;eacute;l caso, lo hicimos para simular el retorno de una llamada ajax, convirtiendo un posible test de integraci&amp;oacute;n en un test unitario en el que se mockea al colaborador.&lt;/p&gt;
&lt;p&gt;Imaginemos que nuestro c&amp;oacute;digo tiene una funci&amp;oacute;n parecida a esta:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;&lt;div class="line" id="LC33"&gt;&lt;span class="nx"&gt;muestraConfirmacion&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC34"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;#dialog&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;fadeToggle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;fast&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC34"&gt;};&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Puede que nos interese testear que se ha llamado a fadeToggle y que el selector utilizado ha sido #dialog. Esto lo haremos espiando la funci&amp;oacute;n fn de &lt;a href="http://jquery.com/" title="jQuery" target="_blank"&gt;jQuery&lt;/a&gt;. Como explican muy bien &lt;a href="http://stackoverflow.com/questions/4083351/what-does-jquery-fn-mean" title="Funci&amp;oacute;n fn" target="_blank"&gt;aqu&amp;iacute;&lt;/a&gt;&amp;nbsp;fn es un alias de la propiedad prototype de &lt;a href="http://jquery.com/" title="jQuery" target="_blank"&gt;jQuery&lt;/a&gt;, con lo que podremos utilizarlo como punto de entrada para mockear las funciones de &lt;a href="http://jquery.com/" title="http://jquery.com/" target="_blank"&gt;jQuery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Por lo tanto el test podr&amp;iacute;a quedar as&amp;iacute;:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;&lt;div class="line" id="LC286"&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;espiamos un selector&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC287"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nx"&gt;spyOn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;fadeToggle&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC288"&gt;&lt;/div&gt;&lt;div class="line" id="LC289"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;lechazoService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;LechazoService&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC290"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nx"&gt;lechazoService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;muestraConfirmacion&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC291"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&lt;div class="line" id="LC292"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fadeToggle&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toHaveBeenCalled&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC293"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fadeToggle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mostRecentCall&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;#dialog&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC294"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="p"&gt;});&lt;/span&gt;&lt;/div&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Como pod&amp;eacute;is observar en el c&amp;oacute;digo, comprobamos que se ha llamado a la funci&amp;oacute;n fadeToggle y que el selector utilizado ha sido #dialog.&lt;/p&gt;
&lt;p&gt;Pod&amp;eacute;is encontrar m&amp;aacute;s c&amp;oacute;digo de ejemplos de test en Jasmine en este repositorio de GitHub:&amp;nbsp;&lt;a href="https://github.com/vgaltes/PucelaTechDay" title="Pucela Tech Day" target="_blank"&gt;https://github.com/vgaltes/PucelaTechDay&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Espero que os sea &amp;uacute;til.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207673" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Testeo+unitario/default.aspx">Testeo unitario</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Jasmine/default.aspx">Jasmine</category></item><item><title>TFS Express</title><link>http://geeks.ms/blogs/devnettips/archive/2012/11/19/tfs-express.aspx</link><pubDate>Mon, 19 Nov 2012 19:37:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207474</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=207474</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/11/19/tfs-express.aspx#comments</comments><description>&lt;p&gt;Mucho hemos hablado por estos lares de la versi&amp;oacute;n de &lt;a href="http://tfs.visualstudio.com" title="TFSService" target="_blank"&gt;TFS en Azure&lt;/a&gt;, pero todav&amp;iacute;a no hemos comentado que tenemos otra versi&amp;oacute;n gratuita de TFS lista para utilizar:el &lt;a href="http://www.microsoft.com/visualstudio/eng/products/visual-studio-team-foundation-server-express#product-express-tfs-details" title="TFS Express" target="_blank"&gt;TFS Express&lt;/a&gt;.&amp;nbsp;Esta versi&amp;oacute;n, al igual que TFS Service, es gratuita para equipos de hasta cinco usuarios, aunque es ampliable a m&amp;aacute;s usuarios con la compra de las CAL&amp;#39;s correspondientes. Se instala sobre un SQLExpress, con lo que no tenemos reportes ni tampoco Sharepoint. Lo malo de esto es que tampoco tenemos la preciosa Task Board de la versi&amp;oacute;n en la nube :( Ten&amp;eacute;is m&amp;aacute;s detalles en este &lt;a href="http://blogs.msdn.com/b/bharry/archive/2012/02/23/coming-soon-tfs-express.aspx" title="Art&amp;iacute;culo Brian Harry" target="_blank"&gt;art&amp;iacute;culo&lt;/a&gt; de Brian Harry.&lt;/p&gt;
&lt;p&gt;Instalar el servicio es extremadamente sencillo. Basta con descargarse el instalador de la &lt;a href="http://www.microsoft.com/visualstudio/eng/downloads#d-team-foundation-server-express" title="Descargar TFS Express" target="_blank"&gt;p&amp;aacute;gina &lt;/a&gt;del producto y seguir sus instrucciones paso a paso.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso1.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso1.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso2.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso2.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pasamos las verificaciones:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso3.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso3.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E instalamos:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso4.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso4.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso5.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso5.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ahora mismo ya tendr&amp;iacute;amos instalado el TFS. Vamos ahora a instalar el servicio de build:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso6.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso6.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso7.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso7.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Seleccionamos el servidor y la colecci&amp;oacute;n a la que conectarnos:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso8.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso8.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Seleccionamos los agentes a instalar:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso9.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso9.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Qu&amp;eacute; cuenta queremos utilizar:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso10.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso10.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso11.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso11.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Pasamos las verificaciones&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso12.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso12.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;E instalamos&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso13.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso13.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y ya lo tenemos!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso14.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Paso14.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Como veis, ha sido extremadamente sencillo. Ahora ya podemos abrir nuestro Visual Studio (o nuestro Eclipse) y conectarnos tan ricamente a nuestro reci&amp;eacute;n instalado TFS Express.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207474" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Microsoft/default.aspx">Microsoft</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/TFS11/default.aspx">TFS11</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/TFS+Express/default.aspx">TFS Express</category></item><item><title>Material de la charla Automatización de pruebas funcionales</title><link>http://geeks.ms/blogs/devnettips/archive/2012/11/01/material-de-la-charla-automatizaci-243-n-de-pruebas-funcionales.aspx</link><pubDate>Thu, 01 Nov 2012 17:30:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207291</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=207291</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/11/01/material-de-la-charla-automatizaci-243-n-de-pruebas-funcionales.aspx#comments</comments><description>&lt;p&gt;Hola a todos,&lt;/p&gt;
&lt;p&gt;solo comentaros que ten&amp;eacute;is disponible en este &lt;a target="_blank" title="PPTs" href="http://www.slideshare.net/vgaltes/automatizacin-de-pruebas-funcionales"&gt;enlace &lt;/a&gt;las PPTs de la charla que d&amp;iacute; el pasado martes en &lt;a target="_blank" title="Artalde" href="http://geeks.ms/blogs/artalde/"&gt;Artalde&amp;nbsp;&lt;/a&gt;sobre Automatizaci&amp;oacute;n de pruebas funcionales. Espero que a los asistentes les gustara y que a los que no pudisteis asistir encontr&amp;eacute;is &amp;uacute;til la presentaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Nos leemos!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207291" width="1" height="1"&gt;</description></item><item><title>Ladder of inference</title><link>http://geeks.ms/blogs/devnettips/archive/2012/10/23/ladder-of-inference.aspx</link><pubDate>Tue, 23 Oct 2012 12:49:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207208</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=207208</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/10/23/ladder-of-inference.aspx#comments</comments><description>&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong&gt;&amp;ldquo;Tenemos que despedir a
J&amp;uacute;lia&amp;rdquo;&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Esta acci&amp;oacute;n, que puede
ser importante para tu empresa, para tu equipo y, sobretodo, para la pobre
J&amp;uacute;lia, la tomas despu&amp;eacute;s de seguir (consciente o inconscientemente) una serie de
pasos llamados &lt;i&gt;ladder of inference&lt;/i&gt;. Realizar estos pasos de manera consciente
nos ayudar&amp;aacute; a tomar decisiones basadas en la realidad. Si recorremos estos
pasos demasiado r&amp;aacute;pido podemos acabar tomando decisiones basadas en creencias y
en visiones parciales de la realidad, lo que nos puede llevar a que estas
decisiones no sean todo lo buenas que deber&amp;iacute;an y podr&amp;iacute;amos acabar despidiendo a
J&amp;uacute;lia sin motivos.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Esto, que puede parecer
algo alejado de nuestra realidad como desarrolladores, es muy importante cuando
hacemos retrospectivas. Asegurando que recorremos los pasos con calma,
conseguiremos que nuestras retrospectivas sean mucho m&amp;aacute;s provechosas, con
acciones de mejora m&amp;aacute;s eficaces. &lt;/p&gt;
&lt;p class="MsoNormal"&gt;Los pasos del &lt;i&gt;ladder of
inference&lt;/i&gt; son los siguientes:&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/LadderofInference.gif"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/LadderofInference.gif" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Empezando por abajo,
tenemos los hechos y la realidad. Si recorremos estos pasos demasiado r&amp;aacute;pido
podr&amp;iacute;amos tener un escenario como este:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Seleccionamos los
hechos en funci&amp;oacute;n de nuestras creencias y la experiencia previa.&lt;/li&gt;
&lt;li&gt;Interpretamos qu&amp;eacute;
significan&lt;/li&gt;
&lt;li&gt;Aplicamos asunciones
previas, generalmente sin considerarlas.&lt;/li&gt;
&lt;li&gt;Extraemos
conclusiones basadas en los hechos interpretados y nuestras asunciones.&lt;/li&gt;
&lt;li&gt;Desarrollamos (o
afianzamos) creencias basadas en estas conclusiones.&lt;/li&gt;
&lt;li&gt;Tomamos acciones que
parecen &amp;ldquo;correctas&amp;rdquo; porqu&amp;eacute; est&amp;aacute;n basadas en nuestras creencias.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;Veamos un ejemplo:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Trabajamos en una
consultora. Nuestro superior nos ha puesto a J&amp;uacute;lia en nuestro equipo sin
nosotros pedirlo. J&amp;uacute;lia tiene un sueldo por encima de la media y me va a costar
m&amp;aacute;s cuadrar las cuentas a final de trimestre. Desde que est&amp;aacute; J&amp;uacute;lia tenemos
menos velocidad en el equipo y la build est&amp;aacute; rota constantemente.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;iquest;Qu&amp;eacute; pasos puedo seguir?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;De todo lo que veo,
selecciono que tenemos menos velocidad y que J&amp;uacute;lia rompe muchas builds.&lt;/li&gt;
&lt;li&gt;Interpreto que el
equipo est&amp;aacute; bajando la calidad de su trabajo.&lt;/li&gt;
&lt;li&gt;Como J&amp;uacute;lia viene
impuesta y encima del departamento de BI, asumo que no tiene los conocimientos
necesarios de programaci&amp;oacute;n.&lt;/li&gt;
&lt;li&gt;Llego a la conclusi&amp;oacute;n
que J&amp;uacute;lia no est&amp;aacute; haciendo bien su trabajo.&lt;/li&gt;
&lt;li&gt;Me formo la idea que
J&amp;uacute;lia no est&amp;aacute; capacitada para trabajar con nuestro equipo.&lt;/li&gt;
&lt;li&gt;Creo que lo mejor es
despedir a J&amp;uacute;lia.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;En este proceso hay dos
cosas importantes. La primera es que lo hemos recorrido muy r&amp;aacute;pido, sin
pararnos a pensar en cada paso ni preguntarnos si eran correctas las
interpretaciones, asunciones, conclusiones que hemos ido tomando. La segunda es
que estamos dejando que el proceso se retroalimente de una manera peligrosa.
Casi en la base del mismo, estamos dejando que nuestras creencias e ideas
preconcebidas nos influyan incluso en el primer paso.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Por tanto, antes de tomar
una acci&amp;oacute;n es necesario que nos cuestionemos cada paso:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;iquest;Estoy seleccionando
todos los hechos importantes?&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;iquest;Por qu&amp;eacute; estoy haciendo
estas asunciones? &lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;iquest;Puedo testar estas
asunciones?&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;iquest;Por qu&amp;eacute; creo que esto es
la acci&amp;oacute;n correcta a tomar?&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;iquest;Me estoy dejando
influenciar por mis creencias de una manera &amp;ldquo;peligrosa&amp;rdquo;?&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;strong&gt;La retrospectiva&lt;/strong&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&amp;iquest;C&amp;oacute;mo influye esto en las
retrospectivas? De la misma forma que antes hemos llegado a la acci&amp;oacute;n de
despedir a J&amp;uacute;lia seguramente de una manera equivocada o, por lo menos, sin
tener en cuenta otras acciones que podr&amp;iacute;an ser mejores, en una retrospectiva
podemos llegar a acciones de mejora que no sean todo lo provechosas que
deber&amp;iacute;an.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Para asegurarnos que
recorremos bien todos los pasos, Esther Derby y Diana Larsen definieron en su
famoso libro &amp;ldquo;&lt;a target="_blank" title="Agile retrospectives" href="http://www.amazon.es/Agile-Retrospectives-Making-Pragmatic-Programmers/dp/0977616649/ref=sr_1_1?ie=UTF8&amp;amp;qid=1351271974&amp;amp;sr=8-1"&gt;Agile Retrospectives: Making good teams great&lt;/a&gt;&amp;rdquo; un framework a
utilizar para facilitar una retrospectiva. Este framework dicta los siguientes pasos:&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i&gt;Set the stage&lt;br /&gt;&lt;/i&gt;En esta fase vamos a explicar el prop&amp;oacute;sito de la retrospectiva y a establecer el foco de esta retrospectiva (una semana, dos semanas, etc)&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i&gt;Gather data&lt;br /&gt;&lt;/i&gt;En esta fase recolectaremos los echos (no opiniones) relevantes para la retrospectiva que tienen los miembros del equipo en sus cabezas&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i&gt;Generate insights&lt;br /&gt;&lt;/i&gt;En esta fase interpretaremos los echos recolectados en la fase anterior observando patrones, buscando causas, identificando posibles soluciones o mejoras.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i&gt;Decide what to do&lt;br /&gt;&lt;/i&gt;Es esta fase, pasaremos de la discusi&amp;oacute;n a la acci&amp;oacute;n, llegando a un acuerdo entre todo el equipo de las acciones a tomar.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;i&gt;Close the retrospective&lt;br /&gt;&lt;/i&gt;Finalmente cerraremos la retrospectiva recordando las acciones y como haremos su seguimiento, reconoceremos el esfuerzo de todo el mundo e identificaremos la manera de hacer mejor la siguiente retrospectiva.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Como veis, hay un claro paralelismo entre los pasos del &lt;i&gt;ladder of inference&lt;/i&gt; y los pasos del framework. Siguiendo estos pasos, nos aseguraremos un mejor rendimiento de nuestras retrospectivas.&lt;/p&gt;
&lt;p class="MsoNormal"&gt;Espero que el art&amp;iacute;culo os haya resultado interesante. Nos leemos!&lt;/p&gt;
&lt;p&gt;Fuentes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mindtools.com/pages/article/newTMC_91.htm"&gt;http://www.mindtools.com/pages/article/newTMC_91.htm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.slideshare.net/estherderby/agile-retrospectives-4976896"&gt;http://www.slideshare.net/estherderby/agile-retrospectives-4976896&lt;/a&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207208" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/metodolog_26002300_237_3B00_as/default.aspx">metodolog&amp;#237;as</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/agile/default.aspx">agile</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/retrospectivas/default.aspx">retrospectivas</category></item><item><title>Control estático de código JavaScript con VS2012</title><link>http://geeks.ms/blogs/devnettips/archive/2012/10/15/control-est-225-tico-de-c-243-digo-javascript-con-vs2012.aspx</link><pubDate>Mon, 15 Oct 2012 17:44:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:207132</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=207132</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/10/15/control-est-225-tico-de-c-243-digo-javascript-con-vs2012.aspx#comments</comments><description>&lt;p&gt;Hace &lt;a href="http://blogs.msdn.com/b/esmsdn/archive/2012/07/16/ecosistema-de-desarrollo-de-aplicaciones-javascript-con-herramientas-microsoft.aspx" title="Ecosistema de desarrollo de aplicaciones JavaScript con herramientas Microsoft" target="_blank"&gt;poco&lt;/a&gt;&amp;nbsp;habl&amp;aacute;bamos que para pasar &lt;a href="http://www.jslint.com/" title="JSLint" target="_blank"&gt;JSLint&lt;/a&gt; ( o &lt;a href="http://www.jshint.com/" title="JSHint" target="_blank"&gt;JSHint&lt;/a&gt; ) en nuestro c&amp;oacute;digo JavaScript desde Visual Studio 2012 ten&amp;iacute;amos que echar mano de &lt;a href="http://chirpy.codeplex.com/" title="Chirpy" target="_blank"&gt;Chirpy&lt;/a&gt;. El otro d&amp;iacute;a investigando esto con Rodrigo, vimos que en este breve ( o no tan breve ) lapso de tiempo tenemos dos herramientas m&amp;aacute;s que nos ayudar&amp;aacute;n en esta tarea, &lt;a href="http://visualstudiogallery.msdn.microsoft.com/07d54d12-7133-4e15-becb-6f451ea3bea6" title="Web Essentials 2012" target="_blank"&gt;Web Essentials 2012&lt;/a&gt; y &lt;a href="http://visualstudiogallery.msdn.microsoft.com/1a417c37-4d6f-43ca-b753-6ea6eb5041fd" title="JSLint for Visual Studio 2012" target="_blank"&gt;JSLint for Visual Studio 2012&lt;/a&gt;. Aqu&amp;iacute; van las conclusiones que saqu&amp;eacute;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web Essentials 2012&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Web Essentials es una extensi&amp;oacute;n de Visual Studio muy conocida. A parte de ayudarnos con JSHint, maneja archivos LESS, TypeScript, CoffeScript, y un largo etc&amp;eacute;tera. Instalarlo es muy sencillo, solo ten&amp;eacute;is que ir a la opci&amp;oacute;n del men&amp;uacute; &amp;quot;Extensions and Updates&amp;quot; e instalaros la extensi&amp;oacute;n:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/webEssentials1.png"&gt;&lt;img border="0" src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/webEssentials1.png" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Una vez instalada la extensi&amp;oacute;n ( y reiniciado VS2012 ) veremos que si hacemos un fichero con un c&amp;oacute;digo tan simple como este:&lt;/p&gt;
&lt;p&gt;if ( a == 1 )&lt;/p&gt;
&lt;p&gt;veremos en la ventana de warnings los siguientes errores:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/errors1.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/errors1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;iexcl;La que podemos liar con tan s&amp;oacute;lo una l&amp;iacute;nea!&lt;/p&gt;
&lt;p&gt;Para configurar las opciones del analizador est&amp;aacute;tico de c&amp;oacute;digo tenemos que irnos a TOOLS -&amp;gt; Options&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/webEssentials2.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/webEssentials2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A parte de las configuraciones sobre qu&amp;eacute; errores mostrar o no mostrar (que os animo a qu&amp;eacute; explor&amp;eacute;is) algo que me parece importante es decidir donde se van a mostrar los mensajes de error. Por defecto estos se muestran en la pesta&amp;ntilde;a de Warnings, pero a mi me gusta tratar estos errores como tales y, por lo tanto, prefiero que Visual Studio me los marque como errores. Por tanto, cambiamos el &amp;quot;Error location&amp;quot; a Error. El problema con esta extensi&amp;oacute;n es que nos pone los mensajes en la pesta&amp;ntilde;a de errores pero no nos da la build por fallida, con lo que, si no somos muy cuidadosos, podemos obviar estos mensajes y nada malo nos pasar&amp;aacute;. Otro &amp;quot;problema&amp;quot; es que solo se pasa cuando un fichero .js se guarda.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JSLint for Visual Studio 2012&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;JSLint for Visual Studio 2012 es una extensi&amp;oacute;n cuya &amp;uacute;nica finalidad es pasarnos el analizador est&amp;aacute;tico de c&amp;oacute;digo. La manera de instalarla es id&amp;eacute;ntica a Web Essentials:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint1.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint1.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Las opciones de JSLint est&amp;aacute;n directamente debajo del men&amp;uacute; TOOLS y en la siguiente imagen podemos ver que son muy completas:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint2.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint2.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Algo importante que podemos ver es que podemos validar los archivos tanto al grabar como al realizar una build, que podemos tratar estos mensajes como errores y que podemos cancelar la build si hay errores. Si lo configuramos as&amp;iacute; podemos ver en nuesta ventana de errores lo siguiente:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint3.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint3.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como pod&amp;eacute;is ver, en la &amp;uacute;ltima l&amp;iacute;nea nos informa que ha cancelado la compilaci&amp;oacute;n por errores de validaci&amp;oacute;n de JSLint.&lt;/p&gt;
&lt;p&gt;Otra cosa interesante que tiene JSLint for Visual Studio 2012 y que no tiene Web Essentials es que podemos marcar tanto ficheros individuales como carpetas enteras para que no se le pase el analizador de c&amp;oacute;digo. Esto es recomendable cuando trabajamos con librer&amp;iacute;as de terceros y no queremos que influyan en nuestra build.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Y por &amp;uacute;ltimo, algo tambi&amp;eacute;n muy interesante es que, haciendo click con el bot&amp;oacute;n derecho sobre la soluci&amp;oacute;n en el Explorador de Soluciones, podemos a&amp;ntilde;adir el archivo de configuraci&amp;oacute;n de JSLint.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint4.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/jslint4.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Esto nos permitir&amp;aacute; subir este archivo a nuestro repositorio de fuentes y que todos los miembros del equipo compartan la misma configuraci&amp;oacute;n de la extensi&amp;oacute;n para esta soluci&amp;oacute;n ya que la extensi&amp;oacute;n por defecto carga la configuraci&amp;oacute;n de este archivo.&lt;/p&gt;
&lt;p&gt;Espero que os haya parecido de utilidad!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=207132" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/JSHint/default.aspx">JSHint</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Visual+Studio+2012/default.aspx">Visual Studio 2012</category></item><item><title>Cariño, he perdido el foco</title><link>http://geeks.ms/blogs/devnettips/archive/2012/08/19/cari-241-o-he-perdido-el-foco.aspx</link><pubDate>Sun, 19 Aug 2012 17:37:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:206505</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=206505</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/08/19/cari-241-o-he-perdido-el-foco.aspx#comments</comments><description>&lt;p&gt;El orden de tabulaci&amp;oacute;n en una aplicaci&amp;oacute;n es uno de esos peque&amp;ntilde;os detalles que, no siendo a veces ni un requerimiento funcional, hace perder calidad y buena presencia a tu aplicaci&amp;oacute;n. Es por tanto importante decidir a qu&amp;eacute; elementos vamos a dejar navegar pulsando el tabulador y en qu&amp;eacute; orden lo vamos a hacer. Esto en &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc838158(v=vs.95)"&gt;Silverlight&lt;/a&gt; lo hacemos mediante las propiedades &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/cc917845(v=vs.95).aspx"&gt;IsTabStop&lt;/a&gt; y &lt;a target="_blank" href="http://msdn.microsoft.com/en-us/library/system.windows.controls.control.tabindex(v=VS.95).aspx"&gt;TabIndex&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pero a veces hacer esto no es tan f&amp;aacute;cil. Podemos tener controles que no sepamos que pueden recoger el foco y a los que no estemos estableciendo correctamente las propiedades, o que el estilo de los controles no contemple el foco y no sepamos por donde anda. &lt;/p&gt;
&lt;p&gt;Si nos pasa esto, necesitamos de un mecanismo que nos ayude a saber qu&amp;eacute; elemento tiene actualmente el foco. Con esta clase de ayuda podremos conseguir este objetivo:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;"&gt;&lt;span style="font-size:xx-small;"&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;static class&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;FocusHelper&lt;/span&gt;        &lt;br /&gt;{        &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private static&lt;/span&gt; System.Threading.&lt;span style="color:#4bacc6;"&gt;Timer&lt;/span&gt; focusTimer;        &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;private static&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;Control&lt;/span&gt; lastFocus = null;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;font-size:xx-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;public static&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;void&lt;/span&gt; Start()      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; focusTimer = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; Timer(&lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;TimerCallback&lt;/span&gt;((o) =&amp;gt;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#4bacc6;"&gt;Deployment&lt;/span&gt;.Current.Dispatcher.BeginInvoke(() =&amp;gt;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;object&lt;/span&gt; temp = &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;font-size:xx-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; temp = &lt;span style="color:#4bacc6;"&gt;FocusManager&lt;/span&gt;.GetFocusedElement();&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;font-size:xx-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (temp != lastFocus)      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;if&lt;/span&gt; (temp &lt;span style="color:#0000ff;"&gt;is&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;Control&lt;/span&gt;)      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#4bacc6;"&gt;Control&lt;/span&gt; conTemp = temp &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Control;      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;var&lt;/span&gt; conTempParent = conTemp.Parent;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;font-size:xx-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; lastFocus = temp &lt;span style="color:#0000ff;"&gt;as&lt;/span&gt; Control;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;font-size:xx-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#4bacc6;"&gt;Debug&lt;/span&gt;.WriteLine(&amp;quot;Current Focus: Control &amp;quot; + conTemp.Name + &amp;quot; of Type &amp;quot; + conTemp + &amp;quot; in &amp;quot; + conTempParent);&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;font-size:xx-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }     &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }), null, 0, 100);      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="font-family:&amp;#39;Courier New&amp;#39;;font-size:xx-small;"&gt;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt; public static void&lt;/span&gt; Stop()      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; focusTimer.Change(0, System.Threading.&lt;span style="color:#4bacc6;"&gt;Timeout&lt;/span&gt;.Infinite);      &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }      &lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Y con esto, llamamos a FocusHelper.Start() donde nos interese debugar el orden de tabulaci&amp;oacute;n y en la pantalla de Output del Visual Studio iremos viendo por donde est&amp;aacute; el foco.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Espero que os sirva de ayuda!&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Nota: c&amp;oacute;digo basado en este post: &lt;a href="http://codeblog.larsholm.net/2009/12/focushelper/"&gt;http://codeblog.larsholm.net/2009/12/focushelper/&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=206505" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Silverlight/default.aspx">Silverlight</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/tip/default.aspx">tip</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/focus/default.aspx">focus</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/helper/default.aspx">helper</category></item><item><title>Problema de rendimiento en Silverlight</title><link>http://geeks.ms/blogs/devnettips/archive/2012/07/26/problema-de-rendimiento-en-silverlight.aspx</link><pubDate>Thu, 26 Jul 2012 21:41:25 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:206258</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=206258</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/07/26/problema-de-rendimiento-en-silverlight.aspx#comments</comments><description>&lt;p&gt;Es común que en nuestras vistas de una aplicación Silverlight queramos añadir un borde con un bonito &lt;a href="http://msdn.microsoft.com/en-us/library/system.windows.media.effects.dropshadoweffect(VS.95).aspx" target="_blank"&gt;DropShadowEffect&lt;/a&gt; que agrupe todo nuestro control o un conjunto de controles. Un posible XAML de ejemplo podría ser el siguiente (aunque de bonito no tenga mucho):&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;Grid HorizontalAlignment=&amp;quot;Center&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Border Background=&amp;quot;AntiqueWhite&amp;quot; &amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Border.Effect&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DropShadowEffect BlurRadius=&amp;quot;0.2&amp;quot; Direction=&amp;quot;55&amp;quot; Color=&amp;quot;Red&amp;quot;&amp;gt;&amp;lt;/DropShadowEffect&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Border.Effect&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;StackPanel&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBlock&amp;gt;TextBlock 1&amp;lt;/TextBlock&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBlock&amp;gt;TextBlock 2&amp;lt;/TextBlock&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBlock&amp;gt;TextBlock 1&amp;lt;/TextBlock&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ProgressBar Grid.Row=&amp;quot;1&amp;quot; IsIndeterminate=&amp;quot;True&amp;quot; Height=&amp;quot;8&amp;quot; Margin=&amp;quot;5&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/StackPanel&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Border&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Grid&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Si nuestra pantalla no fuera tan sencilla sino un poco más compleja (un DataGrid y unos cuantos UserControls por ejemplo) podríamos observar una considerable caída en el rendimiento. &lt;/p&gt;  &lt;p&gt;Para intentar mejorar el comportamiento de nuestra aplicación, vamos a analizar que componentes se están redibujando. La lógica nos diría que simplemente se tendría que redibujar el control del ProgressBar o, como mucho, el TextBox que tenga el foco (por el cursor). Para ver que es lo que realmente se está redibujando tenemos que pasar el siguiente parámetro a a nuestra aplicación Silverlight:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;param name=&amp;quot;enableRedrawRegions&amp;quot; value=&amp;quot;true&amp;quot;/&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Ejecutamos la aplicación y vemos que se redibuja toda la pantalla!!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/RedrawAll_5F00_44757F73.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="RedrawAll" border="0" alt="RedrawAll" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/RedrawAll_5F00_thumb_5F00_5C98E9CE.png" width="86" height="182" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esto sucede porque cuando añadimos un DropShadowEffect a un borde, siempre que se redibuja un elemento que está dentro de este borde, se redibujan todos los elementos que están dentro del borde.&lt;/p&gt;  &lt;p&gt;Por suerte la solución es muy sencilla: tenemos que “partir” nuestro borde en dos bordes: en el primero ponemos tan solo el DropShadowEffect y en el segundo agrupamos todo los elementos que nos interesen. Por lo tanto nuestro código original quedaría así:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;&amp;lt;Grid HorizontalAlignment=&amp;quot;Center&amp;quot; VerticalAlignment=&amp;quot;Center&amp;quot;&amp;gt;     &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Border Background=&amp;quot;AntiqueWhite&amp;quot; &amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Border.Effect&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;DropShadowEffect BlurRadius=&amp;quot;0.2&amp;quot; Direction=&amp;quot;55&amp;quot; Color=&amp;quot;Red&amp;quot;&amp;gt;&amp;lt;/DropShadowEffect&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Border.Effect&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Border&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;Border&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;StackPanel&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBlock&amp;gt;TextBlock 1&amp;lt;/TextBlock&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBlock&amp;gt;TextBlock 2&amp;lt;/TextBlock&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBlock&amp;gt;TextBlock 1&amp;lt;/TextBlock&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;TextBox&amp;gt;&amp;lt;/TextBox&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;ProgressBar Grid.Row=&amp;quot;1&amp;quot; IsIndeterminate=&amp;quot;True&amp;quot; Height=&amp;quot;8&amp;quot; Margin=&amp;quot;5&amp;quot;/&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/StackPanel&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Border&amp;gt;      &lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; &amp;lt;/Grid&amp;gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;Si ahora ejecutamos la aplicación veremos que solo se redibuja la ProgressBar:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/RedrawProgress_5F00_425880AA.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="RedrawProgress" border="0" alt="RedrawProgress" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/RedrawProgress_5F00_thumb_5F00_768CA9F0.png" width="84" height="182" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;Así que ya sabéis, vigilad con los bordes!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=206258" width="1" height="1"&gt;</description></item><item><title>Nuestro primer spy con Jasmine</title><link>http://geeks.ms/blogs/devnettips/archive/2012/06/08/nuestro-primer-spy-con-jasmine.aspx</link><pubDate>Fri, 08 Jun 2012 19:21:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:205545</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=205545</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/06/08/nuestro-primer-spy-con-jasmine.aspx#comments</comments><description>&lt;p&gt;Esta ma&amp;ntilde;ana el amigo &lt;a target="_blank" href="http://mrubino.net/"&gt;Marc Rubi&amp;ntilde;o&lt;/a&gt; ha escrito un interesant&amp;iacute;simo &lt;a target="_blank" href="http://geeks.ms/blogs/mrubino/archive/2012/06/08/javascript-visual-studio-and-tdd.aspx"&gt;post&lt;/a&gt; sobre como empezar con TDD y JavaScript, utilizando &lt;a target="_blank" href="http://docs.jquery.com/QUnit"&gt;qUnit&lt;/a&gt; y &lt;a target="_blank" href="http://www.jetbrains.com/resharper/"&gt;ReSharper&lt;/a&gt;. Esto ha iniciado una peque&amp;ntilde;a charla en &lt;a target="_blank" href="http://twitter.com/Marc_Rubino/status/211004394240622595"&gt;twitter&lt;/a&gt;.&amp;nbsp; Con todo esto me he lanzado a hacer una peque&amp;ntilde;&amp;iacute;sima introducci&amp;oacute;n a los spy con &lt;a target="_blank" href="http://pivotal.github.com/jasmine/"&gt;Jasmine&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Mi primera tentaci&amp;oacute;n, como ha comentado Marc en su post, ha sido utilizar &lt;a target="_blank" href="http://chutzpah.codeplex.com/"&gt;Chutzpah&lt;/a&gt;. Ya hab&amp;iacute;a hecho &lt;a target="_blank" href="http://geeks.ms/blogs/devnettips/archive/2012/03/30/tests-unitarios-con-nunit-u-otros-con-vs11-y-en-tfsservice.aspx"&gt;pruebas&lt;/a&gt; con el con Visual Studio 2012 y hab&amp;iacute;a quedado encantado, pero la verdad es que para Visual Studio 2010 no lo tienen tan bien resuelto. En lugar de correr junto con los otros tests de la soluci&amp;oacute;n, hay un dos men&amp;uacute;s contextuales para ejecutar los tests. Uno para ejecutarlos en el propio Visual Studio e informando de los errores en la ventana de Output y de Error List (pero no en la de test) y otro para ejecutarlos en un browser. Si escogemos esta segunda opci&amp;oacute;n, veremos que la versi&amp;oacute;n de Jasmine con la que est&amp;aacute; pasando los tests es la 1.1.0 y no he encontrado manera de actualizarlo a la 1.2.0. En VS2012 es bastante sencillo, pero en VS2010 no. As&amp;iacute; que al final he desestimado esta opci&amp;oacute;n y he tirado por la de toda la vida de tener un html que pase los tests (pod&amp;eacute;is ver uno de ejemplo en el mismo zip en el que se distribuye Jasmine). &lt;/p&gt;
&lt;p&gt;Empecemos pues con el proyecto. La estructura del mismo es algo como esto&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Solucion_5F00_51B4027D.png"&gt;&lt;img height="244" width="179" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Solucion_5F00_thumb_5F00_57227321.png" alt="Solucion" border="0" title="Solucion" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Vamos a empezar nuestro primer test para comprobar que tenemos bien configurado el SpecRunner.html.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/FirstTest_5F00_3C75D708.png"&gt;&lt;img height="68" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/FirstTest_5F00_thumb_5F00_0690E1EE.png" alt="FirstTest" border="0" title="FirstTest" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Alucinados con el test, &amp;iquest;eh? Es sencillo pero ya podemos ver muchas cosas. Primero como definir un Suite con &lt;em&gt;describe&lt;/em&gt; y un spec con &lt;em&gt;it&lt;/em&gt;. Y despu&amp;eacute;s como hacer un aserci&amp;oacute;n muy sencilla. Con esto, ejecutamos SpecRunner.html desde nuestro navegador favorito y vemos que todo ha ido bien.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/FirstTestExecution_5F00_1E481954.png"&gt;&lt;img height="103" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/FirstTestExecution_5F00_thumb_5F00_592F4C1D.png" alt="FirstTestExecution" border="0" title="FirstTestExecution" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Perfecto, ya nos podemos poner con el test que nos interesa. Ech&amp;eacute;mosle un ojo a la clase que queremos testear.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/SimpleClass_5F00_57EAB33E.png"&gt;&lt;img height="232" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/SimpleClass_5F00_thumb_5F00_1A7A4EB7.png" alt="SimpleClass" border="0" title="SimpleClass" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como veis es una clase muy sencilla que hace una llamada por ajax a un controlador y guarda el resultado en un atributo de la clase. Imaginaros que todav&amp;iacute;a no tengo el controlador hecho, o que yo no lo voy a hacer y que, a parte, quiero que mis tests sean unitarios, r&amp;aacute;pidos y que no dependan de elementos externos. &amp;iquest;Qu&amp;eacute; tendr&amp;iacute;a que hacer? Pues claramente, mockear la llamada al controlador. Si lo hacemos con nuestras clases en .Net con &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;, &lt;a target="_blank" href="http://hibernatingrhinos.com/open-source/rhino-mocks"&gt;Rhino&lt;/a&gt;, &lt;a target="_blank" href="http://research.microsoft.com/en-us/projects/moles/"&gt;Moles&lt;/a&gt; o el framework que utilicemos, por qu&amp;eacute; no lo tenemos que hacer en JavaScript?&lt;/p&gt;
&lt;p&gt;Y aqu&amp;iacute; tenemos una de las ventajas de Jasmine sobre otros frameworks de testeo unitario de BLOCKED SCRIPT ella misma ya lleva el framework de mockeo incorporado, lo que ella le llama los spy.&lt;/p&gt;
&lt;p&gt;Crear un spy es muy sencillo: tenemos que indicar cual es el objeto y la funci&amp;oacute;n que queremos espiar y despu&amp;eacute;s ya podemos simular callbacks, mirar si se ha llamado con los par&amp;aacute;metros adecuados, si se ha llamado las veces esperadas, simular los valores de retorno, etc.&lt;/p&gt;
&lt;p&gt;Vamos a quedarnos con la primera de las opciones y vamos a simular la llamada al controlador via la funci&amp;oacute;n &lt;a target="_blank" href="http://api.jquery.com/jQuery.ajax/"&gt;ajax&lt;/a&gt; de &lt;a target="_blank" href="http://jquery.com"&gt;jquery&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/MockingJquery_5F00_2DBB0556.png"&gt;&lt;img height="59" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/MockingJquery_5F00_thumb_5F00_735F8F74.png" alt="MockingJquery" border="0" title="MockingJquery" style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como veis, estamos indicando a Jasmine que queremos espiar la funci&amp;oacute;n ajax de jquery y que queremos que al llamarla, llame a un fake que simule el success. Con esto, ya podemos hacer despu&amp;eacute;s el expect que m&amp;aacute;s nos interese, en nuestro caso que se est&amp;aacute; igualando el resultado al objeto asset. Podr&amp;iacute;amos haber espiado otras cosas, como que solo se ha llamado una vez, o que se haya llamado con el id 1 como par&amp;aacute;metro.&lt;/p&gt;
&lt;p&gt;Y hasta aqu&amp;iacute; esta peque&amp;ntilde;&amp;iacute;sima demo. Espero que entre el art&amp;iacute;culo de Marc y este, ya no teng&amp;aacute;is excusas para testear vuestro c&amp;oacute;digo JavaScript!&lt;/p&gt;
&lt;p&gt;Hasta la pr&amp;oacute;xima!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=205545" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Testeo+unitario/default.aspx">Testeo unitario</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/JavaScript/default.aspx">JavaScript</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Jasmine/default.aspx">Jasmine</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/TDD/default.aspx">TDD</category></item><item><title>Storyboarding con PowerPoint en TFS11</title><link>http://geeks.ms/blogs/devnettips/archive/2012/04/01/storyboarding-con-powerpoint-en-tfs11.aspx</link><pubDate>Sun, 01 Apr 2012 16:11:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:204161</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=204161</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/04/01/storyboarding-con-powerpoint-en-tfs11.aspx#comments</comments><description>&lt;p&gt;&amp;quot;Un &lt;i&gt;&lt;b&gt;storyboard&lt;/b&gt;&lt;/i&gt; o &lt;b&gt;guion gr&amp;aacute;fico&lt;/b&gt; es un conjunto de ilustraciones mostradas en secuencia con el objetivo de servir de gu&amp;iacute;a para entender una historia, previsualizar una &lt;a href="http://es.wikipedia.org/wiki/Animaci%C3%B3n" title="Animaci&amp;oacute;n"&gt;animaci&amp;oacute;n&lt;/a&gt; o seguir la estructura de una &lt;a href="http://es.wikipedia.org/wiki/Pel%C3%ADcula" title="Pel&amp;iacute;cula"&gt;pel&amp;iacute;cula&lt;/a&gt; antes de realizarse o filmarse.&amp;quot; (Fuente: &lt;a target="_blank" href="http://es.wikipedia.org/wiki/Storyboard" title="Definici&amp;oacute;n Storyboard en la Wikipedia"&gt;Wikipedia&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Seg&amp;uacute;n esta definici&amp;oacute;n de la &lt;a target="_blank" href="http://www.wikipedia.org" title="Wikipedia"&gt;Wikipedia&lt;/a&gt; parece l&amp;oacute;gico que un storyboard sea algo que podamos linkar a, por ejemplo, un work item de historia de usuario en nuestro TFS. A los desarrolladores de la nueva versi&amp;oacute;n de TFS tambi&amp;eacute;n les ha parecido l&amp;oacute;gico y por eso nos proporcionan de serie una nueva pesta&amp;ntilde;a en el work &amp;iacute;tem de historia de usuario para gestionar este tipo de artefactos y, a parte, han desarrollado una extensi&amp;oacute;n para Power Point para poder crearlos con facilidad.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Historia.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Historia.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si abrimos Power Point despu&amp;eacute;s de haber instalado el nuevo &lt;a target="_blank" href="http://www.microsoft.com/download/en/details.aspx?id=28976" title="Team Explorer 11"&gt;Team Explorer&lt;/a&gt; veremos que si abrimos Power Point tenemos una nueva pesta&amp;ntilde;a llamada Storyboarding&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/PPStoryboarding.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/PPStoryboarding.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Si clicamos sobre Storyboard Shapes se nos abrir&amp;aacute; una pantalla con todas las formas predefinidas que tenemos para crear nuestro storyboard&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/StoryboardingShapes.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/StoryboardingShapes.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ahora solo nos queda crear la pantalla que necesitemos para el dispositivo requerido. Por ejemplo, vamos a intentar (con las limitaciones que mis capacidades de dise&amp;ntilde;o me permitan) crear una pantalla de settings para una aplicaci&amp;oacute;n m&amp;oacute;vil.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/settings.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/settings.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como veis, como dise&amp;ntilde;ador no doy para mucho, pero como Product Owner estoy razonablemente contento. La pantalla tiene todo aquello que yo quiero que tenga. Esta pantalla se puede enriquecer tanto como queramos, ya sea con im&amp;aacute;genes, shapes hechas con PowerPoint, capturas de pantalla.&lt;/p&gt;
&lt;p&gt;Ahora solo nos queda guardar el archivo (en una carpeta compartida o en un site de Sharepoint) y mediante el bot&amp;oacute;n de Storyboard links ( o desde el work item de la historia, claro) relacionarlo con nuestra historia de usuario.&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=204161" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/VS11/default.aspx">VS11</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/TFS11/default.aspx">TFS11</category></item><item><title>Tests unitarios con NUnit (u otros) con VS11 y en TFSService</title><link>http://geeks.ms/blogs/devnettips/archive/2012/03/30/tests-unitarios-con-nunit-u-otros-con-vs11-y-en-tfsservice.aspx</link><pubDate>Fri, 30 Mar 2012 14:51:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:204112</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=204112</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/03/30/tests-unitarios-con-nunit-u-otros-con-vs11-y-en-tfsservice.aspx#comments</comments><description>&lt;p&gt;Con Visual Studio 2010 para poder correr tests unitarios con &lt;a target="_blank" href="http://www.nunit.org/" title="NUnit"&gt;NUnit&lt;/a&gt; ten&amp;iacute;amos que hacer un poco de trabajo extra, desde instalar una extensi&amp;oacute;n que nos creaba un tipo de proyecto especial, utilizar plugins como &lt;a target="_blank" href="http://www.testdriven.net/" title="TestDriven"&gt;TestDriven&lt;/a&gt; o simplemente correr los tests desde el runner de NUnit. Ahora con VS11 tenemos esta integraci&amp;oacute;n mucho m&amp;aacute;s sencilla, tanto con NUnit como con &lt;a target="_blank" href="http://blogs.msdn.com/b/visualstudioalm/archive/2012/03/02/visual-studio-11-beta-unit-testing-plugins-list.aspx" title="Frameworks de tests con plugins para VS11"&gt;otros&lt;/a&gt; frameworks de test.&lt;/p&gt;
&lt;p&gt;Lo que tenemos que hacer es irnos al extension manager de VS11 (Tools -&amp;gt;&amp;nbsp; Extension Manager ) y bajar por el &amp;aacute;rbol hasta Online Extensions -&amp;gt; Visual Studio Gallery -&amp;gt; Tools -&amp;gt; Testing. En nuestro caso, seleccionaremos NUnit Test Adapter.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ExtensionManager_5F00_NUnit.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ExtensionManager_5F00_NUnit.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como veis, ya hay otros adaptadores disponibles y seguro que ir&amp;aacute;n apareciendo m&amp;aacute;s. Los adaptadores lo que son es un puente entre los comandos a los que llama Visual Studio ( como podr&amp;iacute;an ser &amp;quot;descubre tests&amp;quot;, &amp;quot;corre tests&amp;quot;, etc ) y las propias llamadas del framework con el que se trabaje. Esto permite que se puedan integrar todos los diferentes tests unitarios en el IDE y tener una mejor experiencia. Pod&amp;eacute;is leer m&amp;aacute;s informaci&amp;oacute;n en este &lt;a target="_blank" href="http://blogs.msdn.com/b/visualstudioalm/archive/2012/03/08/what-s-new-in-visual-studio-11-beta-unit-testing.aspx" title="Novedades de VS11 en Unit Testing"&gt;art&amp;iacute;culo&lt;/a&gt; de Peter Provost.&lt;/p&gt;
&lt;p&gt;Al a&amp;ntilde;adir la extensi&amp;oacute;n de Visual Studio este nos pide reiniciar y al hacerlo, voil&amp;agrave;!! Ya tenemos nuestros tests con NUnit pas&amp;aacute;ndose y mostrando el resultado en la ventana de Test Explorer. Obviamente, tendremos que haber incluido, preferiblemente por NuGet, la librer&amp;iacute;a de NUnit para poder compilar los tests.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/TestResults.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/TestResults.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Es curioso ver como el primer tests de NUnit tarda un poquit&amp;iacute;n m&amp;aacute;s que el primer test de MSTest.&lt;/p&gt;
&lt;p&gt;Si tuvi&amp;eacute;ramos una build de integraci&amp;oacute;n continua configurada en el nuevo servicio de builds de TFSService ( como vimos en el &lt;a target="_blank" href="http://geeks.ms/blogs/devnettips/archive/2012/03/29/creaci-243-n-de-una-build-con-el-nuevo-servicio-de-builds-para-tfs-service.aspx" title="Builds con TFSService"&gt;art&amp;iacute;culo&lt;/a&gt; de ayer ) y subi&amp;eacute;ramos nuestros cambios a TFSService, podr&amp;iacute;amos ver que los tests de NUnit no se est&amp;aacute;n pasando, ya que las m&amp;aacute;quinas de TFSService, no lo traen configurado por defecto. Por suerte, arreglar esto es algo muy sencillo.&lt;/p&gt;
&lt;p&gt;Primero de todo nos vamos a bajar la misma extensi&amp;oacute;n de Visual Studio a nuestro ordenador (a no ser que ya lo hubi&amp;eacute;ramos hecho antes en lugar de instalarla por NuGet). Esto lo podemos hacer accediendo a la siguiente p&amp;aacute;gina &lt;a href="http://aka.ms/nunit-vs11"&gt;http://aka.ms/nunit-vs11&lt;/a&gt;. Cuando tengamos el vsix en nuestro disco duro, le cambiamos la extensi&amp;oacute;n a .zip y lo descomprimimos a una carpeta.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NUnitAdapter.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NUnitAdapter.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Copiamos todas las dlls y las metemos en una carpeta de nuestro control de c&amp;oacute;digo fuente.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NUnitAdapterSourceControl.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NUnitAdapterSourceControl.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Ahora solo hace falta indicarle a nuestro controlador de builds que los custom assemblies los busque en esta carpeta. As&amp;iacute; que nos vamos a la secci&amp;oacute;n de builds del Team Explorer, clicamos sobre Actions y seleccionamos la acci&amp;oacute;n Manage Build Controllers&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/BuildController.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/BuildController.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;En la ventana de configuraci&amp;oacute;n que nos sale, seleccionamos el Hosted Build Controller&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ManageBuildController.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ManageBuildController.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y accedemos a sus propiedades y modificamos el valor de Versi&amp;oacute;n Control&amp;nbsp;Path to Custom Assemblies al valor adecuado en nuestro caso.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ManageBuildControllerProperties.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ManageBuildControllerProperties.png" border="0" alt="" /&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Ya podemos volver a correr la build y podremos ver como se pasan tanto los tests de MSTest como los de NUnit.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/BuildSucceeded.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/BuildSucceeded.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un saludo!!&lt;/p&gt;
&lt;p&gt;Fuente: &lt;a href="http://blogs.msdn.com/b/visualstudioalm/archive/2012/03/27/build-on-the-team-foundation-service.aspx"&gt;http://blogs.msdn.com/b/visualstudioalm/archive/2012/03/27/build-on-the-team-foundation-service.aspx&lt;/a&gt;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=204112" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Testeo+unitario/default.aspx">Testeo unitario</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/VS11/default.aspx">VS11</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/TFS11/default.aspx">TFS11</category></item><item><title>Creación de una build con el nuevo servicio de builds para TFS Service</title><link>http://geeks.ms/blogs/devnettips/archive/2012/03/29/creaci-243-n-de-una-build-con-el-nuevo-servicio-de-builds-para-tfs-service.aspx</link><pubDate>Thu, 29 Mar 2012 21:03:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:204099</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=204099</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/03/29/creaci-243-n-de-una-build-con-el-nuevo-servicio-de-builds-para-tfs-service.aspx#comments</comments><description>&lt;p&gt;Hace un par de d&amp;iacute;as, Brian Harry anunci&amp;oacute; que ya estaba disponible el nuevo servicio en la nube para poder crear builds de un proyecto alojado en TFS Service. Como ya sab&amp;eacute;is, TFS Service es un TFS11 alojado en Azure y, por ahora, con acceso gratuito mediante invitaci&amp;oacute;n.&lt;/p&gt;
&lt;p&gt;Hasta hace un par de d&amp;iacute;as, una de las limitaciones que ten&amp;iacute;a este servicio es que no prove&amp;iacute;a de la posibilidad de crear builds tambi&amp;eacute;n alojadas en la nube, con lo que nos ten&amp;iacute;amos que crear nosotros la infraestructura necesaria para ello, ya sea instalando en una m&amp;aacute;quina local un agente de build de TFS11 o aloj&amp;aacute;ndolo nosotros mismos en Azure. Ahora esto ya no es as&amp;iacute;, y Microsoft ya nos provee de un servicio donde poder alojar nuestras builds y, a parte, facil&amp;iacute;simo de configurar.&lt;/p&gt;
&lt;p&gt;Para crear una build, haremos lo que estamos acostumbrados a hacer con nuestro TFS de toda la vida, es decir, ir al apartado de builds de nuestro Team Explorer y clicar sobre New Build Definition.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NewBuildDefinition.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/NewBuildDefinition.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;Se nos abrir&amp;aacute; la pantalla de definici&amp;oacute;n de builds donde configuraremos los par&amp;aacute;metros de la build que nos interesen. En este caso, hay dos par&amp;aacute;metros cr&amp;iacute;ticos: el controlador de la build y el drop folder.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/BuildDefinition.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/BuildDefinition.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Como veis, nos ha aparecido un controlador nuevo, llamado Hosted Build Controller, que es el que tenemos que seleccionar. Por otra parte, por una limitaci&amp;oacute;n de azure, no podemos copiar el output de la build a un path UNC, as&amp;iacute; que tendremos que escoger la opci&amp;oacute;n de copiarlo en una carpeta del Source Control. Vigilad en no poner una carpeta que teng&amp;aacute;is mapeada en un proyecto, para no bajaros informaci&amp;oacute;n innecesaria.&lt;/p&gt;
&lt;p&gt;Y ya est&amp;aacute;, ya tenemos todo lo necesario para correr nuestra build. Ya podemos poner una build en la cola y esperar que esta finalice, a poder ser de manera satisfactoria claro :-)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ResultBuild.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ResultBuild.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ma&amp;ntilde;ana veremos como podemos configurar el adaptador de nUnit para pasar los tests con este framework desde Visual Studio y como configurar la build para que tambi&amp;eacute;n lo haga.&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=204099" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Azure/default.aspx">Azure</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/VS11/default.aspx">VS11</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/TFS11/default.aspx">TFS11</category></item><item><title>Mi participación en el Codemotion.es</title><link>http://geeks.ms/blogs/devnettips/archive/2012/03/29/mi-participaci-243-n-en-el-codemotion-es.aspx</link><pubDate>Thu, 29 Mar 2012 14:32:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:204094</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=204094</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2012/03/29/mi-participaci-243-n-en-el-codemotion-es.aspx#comments</comments><description>&lt;p&gt;El pasado 24 de marzo tuve el placer de participar en la primera edici&amp;oacute;n espa&amp;ntilde;ola del &lt;a target="_blank" href="http://codemotion.es" title="Codemotion"&gt;Codemotion&lt;/a&gt;. Mi charla fue una introducci&amp;oacute;n a Kinect y tuve el gusto de compartirla con el gran &lt;a target="_blank" href="http://www.twitter.com/elbruno" title="El bruno"&gt;@elbruno&lt;/a&gt;. Pod&amp;eacute;is ver en la &lt;a target="_blank" href="http://geeks.ms/blogs/elbruno/archive/2012/03/25/codemotion-materiales-del-evento-de-kinectsdk-y-mi-paso-por-el-codemotion-es.aspx" title="Materiales sesi&amp;oacute;n Kinect"&gt;entrada&lt;/a&gt; de su blog una descripci&amp;oacute;n de la charla as&amp;iacute; como la descarga de los materiales y slides.&lt;/p&gt;
&lt;p&gt;En este art&amp;iacute;culo me gustar&amp;iacute;a centrarme m&amp;aacute;s en dar mi opini&amp;oacute;n sobre las cosas que me gustaron&amp;nbsp;y las que considero que son mejorables del evento en s&amp;iacute;, tanto desde el punto de vista de ponente como desde el punto de vista de asistente. Vaya por delante mi respeto enorme por la organizaci&amp;oacute;n, que fue capaz de convocar y gestionar la participaci&amp;oacute;n de unas 1000 personas. &lt;/p&gt;
&lt;p&gt;Empecemos por lo mejorable. Como ponente me parece que la selecci&amp;oacute;n de las charlas fue un poco ca&amp;oacute;tica. Nosotros mismos no nos enteramos de que nos hab&amp;iacute;an seleccionado la charla hasta 15 d&amp;iacute;as antes, que es un tiempo un poco justo para organizar una buena charla, sobretodo teniendo en cuenta de que hab&amp;iacute;a gente que hac&amp;iacute;a un mes que lo sab&amp;iacute;a. Tambi&amp;eacute;n fue un poco justo el aviso de la cena de ponentes, con solo un par de d&amp;iacute;as de antelaci&amp;oacute;n, que nos cogi&amp;oacute; con los billetes ya comprados con lo que nos fue imposible asistir.&lt;/p&gt;
&lt;p&gt;En cuanto al punto de vista de&amp;nbsp;asistente, me sumo a la petici&amp;oacute;n de&amp;nbsp;aulas m&amp;aacute;s grandes. Hubo charlas en que el aula estaba a reventar (tuvimos la &amp;quot;suerte&amp;quot; de ser una de estas, s&amp;iacute;ntoma de que la charla interesaba) y la gente no pudo entrar a escuchar temas que le interesaban. A parte, el sonido en algunas de ellas era bastante mejorable, siendo dif&amp;iacute;cil de escuchar n&amp;iacute;tidamente al ponente.&lt;/p&gt;
&lt;p&gt;Por otra parte, aunque esto es un problema de los eventos en general, sigo sin ver claro el valor que aporta a los patrocinadores tener un peque&amp;ntilde;o stand en medio de un pasillo. No tengo claro que el retorno de inversi&amp;oacute;n del patrocinio sea elevado con esta forma de promoci&amp;oacute;n. Es algo en que las organizaciones de los eventos y los patrocinadores en s&amp;iacute; deber&amp;iacute;an mejorar para poder ofrecer algo diferente y de m&amp;aacute;s valor.&lt;/p&gt;
&lt;p&gt;Y vamos ahora a por lo bueno. Me parece incre&amp;iacute;ble juntar a unas 1000 personas en un evento de desarrollo en nuestro pa&amp;iacute;s. Creo que la gesti&amp;oacute;n del registro y de los 15 minutos entre charlas estuvo muy bien resuelto, no habiendo demasiado foll&amp;oacute;n ni colas. La comida, un punto cr&amp;iacute;tico en toda organizaci&amp;oacute;n de eventos, estuvo muy bien resuelta con la bolsa con el bocadillo y la bebida, permitiendo a la gente que se sentara donde le apeteciera, evitando colas interminables y saturaci&amp;oacute;n de la cafeter&amp;iacute;a y facilitando un buen tiempo de networking.&lt;/p&gt;
&lt;p&gt;En definitiva, me pareci&amp;oacute; un muy buen evento con un amplio rango de mejora.&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=204094" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/eventos/default.aspx">eventos</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Kinect/default.aspx">Kinect</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/codemotion/default.aspx">codemotion</category></item><item><title>Work Item de retrospectiva</title><link>http://geeks.ms/blogs/devnettips/archive/2011/12/27/work-item-de-retrospectiva.aspx</link><pubDate>Tue, 27 Dec 2011 16:39:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202336</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=202336</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2011/12/27/work-item-de-retrospectiva.aspx#comments</comments><description>&lt;p&gt;Hola a todos,&lt;/p&gt;
&lt;p&gt;como muchos sabr&amp;eacute;is, la plantilla &lt;a href="http://msdn.microsoft.com/library/dd380647.aspx" target="_blank"&gt;MSF for Agile&lt;/a&gt; es una plantilla gen&amp;eacute;rica de TFS 2010 que se adapta bien a cualquier metodolog&amp;iacute;a &amp;aacute;gil, sin centrarse en las particularidades de una u otra como, por ejemplo, s&amp;iacute; que hace &lt;a href="http://msdn.microsoft.com/en-us/library/ff731587.aspx" target="_blank"&gt;Visual Studio Scrum&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En MSF for Agile, las iteraciones las definimos en la pantalla de &amp;aacute;reas e iteraciones de la plantilla, pero en ning&amp;uacute;n caso le ponemos l&amp;iacute;mites temporales a las mismas. Esto en la plantilla Visual Studio Scrum lo hacemos gracias al elemento de trabajo &lt;a href="http://msdn.microsoft.com/en-us/library/ff731582.aspx" target="_blank"&gt;Sprint&lt;/a&gt;, en el que definimos una fecha de inicio y una fecha de fin del sprint.&amp;nbsp; Otra informaci&amp;oacute;n que podemos introducir en este elemento de trabajo es la informaci&amp;oacute;n resultante de la &lt;a href="http://www.scrumalliance.org/articles/39-glossary-of-scrum-terms#1113" target="_blank"&gt;retrospectiva&lt;/a&gt;. Si quer&amp;eacute;is saber un poco m&amp;aacute;s de retrospectivas pod&amp;eacute;is echarle un vistazo a la &lt;a href="http://vimeo.com/32774513" target="_blank"&gt;charla&lt;/a&gt; que dio el amigo &lt;a href="https://twitter.com/#!/joserra_diaz" target="_blank"&gt;Jose Ram&amp;oacute;n D&amp;iacute;az&lt;/a&gt; en la &lt;a href="http://conferencia2011.agile-spain.org/" target="_blank"&gt;CAS2011&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En cambio, en la plantilla MSF for Agile no tenemos ninguna manera clara de introducir esta informaci&amp;oacute;n (aunque siempre hay maneras alternativas de hacerlo, como un documento en el Sharepoint, por ejemplo). Es por esto que en &lt;a href="http://www.plainconcepts.com" target="_blank"&gt;Plain Concepts&lt;/a&gt; hemos hecho un nuevo elemento de trabajo para poder guardar mejor esta informaci&amp;oacute;n en nuestro TFS. Aqu&amp;iacute; ten&amp;eacute;is un pantallazo de como es el nuevo elemento de trabajo.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/wiretrospective_5F00_2DCA436A.png"&gt;&lt;img style="background-image:none;border-bottom:0px;border-left:0px;padding-left:0px;padding-right:0px;display:inline;border-top:0px;border-right:0px;padding-top:0px;" title="wiretrospective" border="0" alt="wiretrospective" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/wiretrospective_5F00_thumb_5F00_5A3327B6.png" width="244" height="184" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Y aqu&amp;iacute; ten&amp;eacute;is la definici&amp;oacute;n del elemento de trabajo por si lo quer&amp;eacute;is utilizar en vuestro TFS.&amp;nbsp;(Por favor, visita la web para ver este medio)&lt;/p&gt;
&lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202336" width="1" height="1"&gt;</description></item><item><title>Mockeo de servicios WCF con Moq</title><link>http://geeks.ms/blogs/devnettips/archive/2011/12/13/mockeo-de-servicios-wcf-con-moq.aspx</link><pubDate>Tue, 13 Dec 2011 18:17:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:202135</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=202135</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2011/12/13/mockeo-de-servicios-wcf-con-moq.aspx#comments</comments><description>&lt;p align="justify"&gt;Muy buenas a todos. Despu&amp;eacute;s de un tiempo de inactividad bloguera, volvemos a la carga con uno de nuestros temas favoritos: el testeo unitario. Esta vez vamos a ver como podemos &lt;em&gt;mockear&lt;/em&gt; (o hacer un doble de prueba, como prefir&amp;aacute;is) un servicio WCF con la ayuda de &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;. Recordad que ten&amp;eacute;is dos tutoriales introductorios a &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; en este mismo blog (&lt;a target="_blank" href="http://geeks.ms/blogs/devnettips/archive/2011/01/29/primeros-pasos-con-moq.aspx"&gt;parte 1&lt;/a&gt;, &lt;a target="_blank" href="http://geeks.ms/blogs/devnettips/archive/2011/03/12/primeros-pasos-con-moq-parte-ii.aspx"&gt;parte 2&lt;/a&gt;).&lt;/p&gt;
&lt;p align="justify"&gt;Para nuestro ejemplo vamos a utilizar uno de los servicios web que proporciona Sharepoint. Imaginaos que tenemos una clase que utiliza dicho servicio. Los pasos para hacerlo podr&amp;iacute;an ser:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Agregar la referencia al servicio &lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ConfigurarServicioSinAsync_5F00_6F0569C5.png"&gt;&lt;img height="227" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ConfigurarServicioSinAsync_5F00_thumb_5F00_58631B7E.png" alt="ConfigurarServicioSinAsync" border="0" title="ConfigurarServicioSinAsync" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;Crear una instancia de la clase cliente en nuestro c&amp;oacute;digo &lt;br /&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;DwsSoapClient&lt;/span&gt; sharepointClient = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;DwsSoapClient&lt;/span&gt;(); &lt;/li&gt;
&lt;li&gt;Hacer la llamada a la funci&amp;oacute;n deseada &lt;br /&gt;sharepointClient.CreateFolder(&amp;quot;&lt;span style="color:#0000ff;"&gt;http://share:81/sites/TestSite&lt;/span&gt;&amp;quot;); &lt;/li&gt;
&lt;/ol&gt;
&lt;p align="justify"&gt;Hasta aqu&amp;iacute; nada nuevo. &amp;iquest;Pero qu&amp;eacute; pasa si queremos testear unitariamente nuestra clase? Pues para empezar lo que pasar&amp;aacute; es que si no hacemos ning&amp;uacute;n cambio, lo que nos salga no ser&amp;aacute; un test unitario, pues necesitar&amp;aacute; de un elemento externo como puede ser un Sharepoint para poder funcionar. Lo que tendremos que hacer ser&amp;aacute; &lt;em&gt;mockear&lt;/em&gt; la clase proxy. Esto con &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; directamente no lo podemos hacer, pues esta clase no es abstracta ni tiene m&amp;eacute;todos virtuales. Si le echamos un ojo al fichero reference.cs que tiene la implementaci&amp;oacute;n del cliente (haciendo un &lt;em&gt;Go to reference&lt;/em&gt; en una funci&amp;oacute;n) veremos que la clase implementa una interfaz del servicio. &amp;iexcl;Magn&amp;iacute;fico! Pues no, ya que los m&amp;eacute;todos que normalmente utilizaremos desde el cliente no se pueden acceder desde esta interfaz, ya que est&amp;aacute;n directamente codificados en la clase. Lo mismo nos pasar&amp;aacute; con los m&amp;eacute;todos as&amp;iacute;ncronos si creamos el proxy del servicio con el &lt;em&gt;check&lt;/em&gt; activado:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ConfigurarServicioConAsync_5F00_571E829F.png"&gt;&lt;img height="227" width="244" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/ConfigurarServicioConAsync_5F00_thumb_5F00_23761641.png" alt="ConfigurarServicioConAsync" border="0" title="ConfigurarServicioConAsync" style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="justify"&gt;En este caso, Visual Studio pone estos m&amp;eacute;todos, y sus correspondientes eventos, directamente en el c&amp;oacute;digo de la clase cliente, y tampoco los a&amp;ntilde;ade a la interfaz. &amp;iquest;Que opci&amp;oacute;n tenemos? Pues crearnos nosotros una interfaz que incorpore los m&amp;eacute;todos as&amp;iacute;ncronos y los eventos para as&amp;iacute; ser capaz de &lt;em&gt;mockearlos&lt;/em&gt;. Tambi&amp;eacute;n, apoy&amp;aacute;ndonos en que la clase cliente es una clase parcial, haremos que la clase cliente implemente esta interfaz sin tener que tocar el fichero reference.cs, que es un fichero generado autom&amp;aacute;ticamente por Visual Studio y no es nada recomendable modificarlo. As&amp;iacute; pues, generaremos un fichero con el siguiente c&amp;oacute;digo, recordando de especificar el mismo &lt;em&gt;namespace&lt;/em&gt; que la clase cliente.&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#0000ff;"&gt;public interface&lt;/span&gt; ISharepointDWSAsyncService : &lt;span style="color:#4bacc6;"&gt;DwsSoap&lt;/span&gt;&amp;nbsp; &lt;br /&gt;{ &lt;br /&gt;&lt;span style="color:#0000ff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void&lt;/span&gt; CreateFolderAsync(&lt;span style="color:#0000ff;"&gt;string&lt;/span&gt; url);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;event&lt;/span&gt; System.EventHandler&amp;lt;&lt;span style="color:#4bacc6;"&gt;CreateFolderCompletedEventArgs&lt;/span&gt;&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; CreateFolderCompleted;&amp;nbsp; &lt;br /&gt;}&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#0000ff;"&gt;public partial class&lt;/span&gt; DwsSoapClient : &lt;span style="color:#4bacc6;"&gt;ISharepointDWSAsyncService&lt;/span&gt; &lt;br /&gt;{ }&lt;/p&gt;
&lt;p align="justify"&gt;En este caso s&amp;oacute;lo hemos a&amp;ntilde;adido un m&amp;eacute;todo que ser&amp;aacute; el que utilizaremos para el ejemplo, pero aqu&amp;iacute; tendr&amp;iacute;ais que a&amp;ntilde;adir todos los m&amp;eacute;todos y eventos que necesit&amp;eacute;is.&lt;/p&gt;
&lt;p align="justify"&gt;Ahora que tenemos la interfaz, tenemos que modificar el c&amp;oacute;digo de nuestro &lt;a target="_blank" href="http://xunitpatterns.com/SUT.html"&gt;SUT&lt;/a&gt; para que utilice la interfaz y no directamente la clase. Despu&amp;eacute;s utilizaremos inyecci&amp;oacute;n de dependencias para inyectar la implementaci&amp;oacute;n que nos interese. La inyecci&amp;oacute;n la podemos hacer de m&amp;uacute;ltiples maneras, por ejemplo por constructor o por propiedad. &lt;a target="_blank" href="http://osherove.com/"&gt;Roy Osherove&lt;/a&gt; recomienda en su libro &lt;a target="_blank" href="http://artofunittesting.com/"&gt;The Art of Unit Testing, with examples in .Net&lt;/a&gt; (que os recomiendo) que las dependencias obligatorias se inyecten por constructor y las opcionales por propiedad. Pod&amp;eacute;is utilizar esta regla como referencia. En nuestro caso, la inyectamos por propiedad:&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#0000ff;"&gt;private&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;ISharepointDWSAsyncService&lt;/span&gt; sharepointClient;&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#0000ff;"&gt;public&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;ISharepointDWSAsyncService&lt;/span&gt; SharepointClient &lt;br /&gt;{ &lt;br /&gt;&lt;span style="color:#0000ff;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&lt;/span&gt;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sharepointClient = &lt;span style="color:#0000ff;"&gt;value&lt;/span&gt;; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp; &lt;br /&gt;}&lt;/p&gt;
&lt;p align="justify"&gt;El resto del c&amp;oacute;digo del &lt;a target="_blank" href="http://xunitpatterns.com/SUT.html"&gt;SUT&lt;/a&gt; deber&amp;iacute;a quedar igual.&lt;/p&gt;
&lt;p align="justify"&gt;Ahora ya podemos pasar a escribir nuestro test. Gracias a las bondades de &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt;, nos queda un c&amp;oacute;digo bastante compacto y elegante:&lt;/p&gt;
&lt;p&gt;&lt;span style="color:#4bacc6;"&gt;[TestMethod]&lt;/span&gt;&amp;nbsp; &lt;br /&gt;&lt;span style="color:#0000ff;"&gt;public void&lt;/span&gt; TestAsynCall()&amp;nbsp; &lt;br /&gt;{&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;&lt;span style="color:#4bacc6;"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color:#4bacc6;"&gt;IDAO&lt;/span&gt;&amp;gt;&lt;/span&gt; mockDao = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color:#4bacc6;"&gt;IDAO&lt;/span&gt;&amp;gt;();&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#4bacc6;"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color:#4bacc6;"&gt;ISharepointDWSAsyncService&lt;/span&gt;&amp;gt; sharepointMock = &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#4bacc6;"&gt;Mock&lt;/span&gt;&amp;lt;&lt;span style="color:#4bacc6;"&gt;ISharepointDWSAsyncService&lt;/span&gt;&amp;gt;(); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#4bacc6;"&gt;AssetManager&lt;/span&gt; assetManager = &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#4bacc6;"&gt;AssetManager&lt;/span&gt;(mockDao.Object);&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; assetManager.SharepointClient = sharepointMock.Object;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; assetManager.CallWSAsync();&amp;nbsp; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sharepointMock.Raise(sp =&amp;gt; sp.CreateFolderCompleted += &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; CreateFolderCompletedEventArgs( &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff;"&gt;string&lt;/span&gt;[] { &lt;span style="color:#c0504d;"&gt;&amp;quot;CreateFolderCompleted&amp;quot;&lt;/span&gt; }, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;false&lt;/span&gt;, &lt;span style="color:#0000ff;"&gt;null&lt;/span&gt;));&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color:#0000ff;"&gt;Assert&lt;/span&gt;.AreEqual(&lt;span style="color:#c0504d;"&gt;&amp;quot;CreateFolderCompleted&amp;quot;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; assetManager.resultCall);&amp;nbsp; &lt;br /&gt;}&lt;/p&gt;
&lt;p align="justify"&gt;Como veis, primero creamos los dos &lt;em&gt;mocks&lt;/em&gt; que utilizar&amp;aacute; nuestro SUT, uno lo inyectamos por constructor y otro por propiedad. Despu&amp;eacute;s hacemos la llamada a la funci&amp;oacute;n que har&amp;aacute; la llamada as&amp;iacute;ncrona al servicio y despu&amp;eacute;s utilizamos la capacidad de &lt;a target="_blank" href="http://code.google.com/p/moq/"&gt;Moq&lt;/a&gt; para lanzar eventos en un &lt;em&gt;mock&lt;/em&gt; para lanzar el evento de &lt;em&gt;completed&lt;/em&gt; de nuestra interfaz. Finalmente haremos el &lt;em&gt;Assert&lt;/em&gt; que toque, en nuestro caso simplemente miraremos que se ha establecido el valor de una propiedad al valor correspondiente.&lt;/p&gt;
&lt;p align="justify"&gt;Y ya tenemos nuestro servicio WCF mockeado! Obviamente, esto &amp;uacute;ltimo explicado sirve para cualquier clase as&amp;iacute;ncrona, no solo para servicios WCF. De echo, otra cosa que podemos hacer y que tambi&amp;eacute;n os recomiendo es poner un nivel de &lt;em&gt;indirecci&amp;oacute;n&lt;/em&gt; [1] entre vuestra clase y el servicio WCF, es decir, una clase intermedia con las llamadas y eventos que necesit&amp;eacute;is. Esto os permitir&amp;aacute; una mayor abstracci&amp;oacute;n del servicio WCF (y poder cambiar su implementaci&amp;oacute;n sin sufrir demasiado) y el c&amp;oacute;digo seguramente os quedar&amp;aacute; m&amp;aacute;s legible y usable.&lt;/p&gt;
&lt;p align="justify"&gt;Nos leemos!!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p align="justify"&gt;[1] &amp;ndash;&amp;gt; &amp;quot;There is no object-oriented problem that cannot be solved by adding a layer of indirection, except, of course, too many layers of indirection.&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=202135" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Moq/default.aspx">Moq</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Testeo+unitario/default.aspx">Testeo unitario</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/Visual+Studio/default.aspx">Visual Studio</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/.Net/default.aspx">.Net</category></item><item><title>No hagas un deploy de lo que no tengas que hacer un deploy</title><link>http://geeks.ms/blogs/devnettips/archive/2011/09/13/no-hagas-un-deploy-de-lo-que-no-tengas-que-hacer-un-deploy.aspx</link><pubDate>Mon, 12 Sep 2011 22:26:49 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200472</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=200472</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2011/09/13/no-hagas-un-deploy-de-lo-que-no-tengas-que-hacer-un-deploy.aspx#comments</comments><description>&lt;p&gt;Hoy nos hemos encontrado con uno de esos &lt;a href="http://www.youtube.com/watch?v=8hQkBLrd1rE" target="_blank"&gt;poltergeist&lt;/a&gt; que tan locos nos vuelven de tanto en cuanto.&lt;/p&gt;  &lt;p&gt;Resulta que estábamos haciendo un despliegue de una aplicación MVC en un entorno de pruebas. Es una aplicación sencillita con autenticación windows y una autorización personalizada como explicábamos en el &lt;a href="http://geeks.ms/blogs/devnettips/archive/2011/09/05/autorizaci-243-n-personalizada-en-asp-net-mvc.aspx" target="_blank"&gt;anterior artículo&lt;/a&gt;. Lo primero que nos hemos encontrado es que al acceder a la aplicación nos daba un error &lt;a href="http://www.checkupdown.com/status/E403_es.html" target="_blank"&gt;403&lt;/a&gt;. Esto es debido a que el AppPool con el que estaba configurada la aplicación en el IIS tenia el &lt;a href="https://help.maximumasp.com/KB/a657/explanation-of-classic-vs-integrated-mode-in-iis-7x.aspx" target="_blank"&gt;Pipeline Mode&lt;/a&gt; a Classic. Este modo evita que podamos acceder a direcciones sin extensión, aunque hay &lt;a href="http://www.tikalk.com/net/aspnet-mvc-3-extensionless-urls-iis-7-classic-mode" target="_blank"&gt;workarounds&lt;/a&gt; que solventan el problema.&lt;/p&gt;  &lt;p&gt;Pero todavía no sabíamos que teníamos este problema, así que una de las (erróneas) creencias que hemos tenido ha sido pensar que nuestro IIS tenia algún problema con el MVC. Pensando esto, hemos querido desplegar las dlls necesarias con nuestra aplicación, así que nos hemos ido a nuestro querido Visual Studio, hemos hecho clic con el botón derecho sobre la solución y hemos seleccionado la opción “add deployable dependencies”&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/adddeploymentdependencies2_5F00_4B3BFBCC.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="adddeploymentdependencies2" border="0" alt="adddeploymentdependencies2" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/adddeploymentdependencies2_5F00_thumb_5F00_5E7CB26B.png" width="208" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esto, después de pedirnos que dependencias queríamos añadir…&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/adddeploymentdependenciesStep2_5F00_3D1D0CCF.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="adddeploymentdependenciesStep2" border="0" alt="adddeploymentdependenciesStep2" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/adddeploymentdependenciesStep2_5F00_thumb_5F00_4701FE3A.png" width="244" height="116" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;…nos ha creado un directorio en la solución con las dependencias necesarias&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/bin_5F00_deployableAssemblies_5F00_7AC9F48B.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="bin_deployableAssemblies" border="0" alt="bin_deployableAssemblies" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/bin_5F00_deployableAssemblies_5F00_thumb_5F00_4478CC7C.png" width="228" height="244" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Esto no nos ha solucionado nada ya que todavía teníamos el AppPool mal configurado. Finalmente nos hemos dado cuenta de nuestro error, hemos cambiado el AppPool y hemos vuelto a ejecutar la aplicación… y todavía nos ha dado un error más sorprendente!!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/404_5F00_62E30D65.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="404" border="0" alt="404" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/404_5F00_thumb_5F00_4FC1E0B9.png" width="244" height="118" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Un 404!! Y un 404 sobre un controlador y una acción que no tenemos definido. Repasamos el web.config para ver si tenemos alguna redirección mal configurada y vemos que no es así. Finalmente, después de mucho buscar nos hemos encontrado con este salvador &lt;a href="http://nickstips.wordpress.com/2011/07/27/asp-net-mvc-unauthenticated-user-always-redirected-to-accountlogon-despite-custom-sign-in-url/" target="_blank"&gt;blog&lt;/a&gt;. En él, su autor explica que si teniendo una aplicación con autenticación forms y cambiándole en el web.config el controlador de autenticación, la aplicación se le redirige hacia el mismo controlador que a nosotros. El autor explica que esto es un bug conocido que pasa cuando estamos desplegando las librerías WebMatrix.Data.dll y WebMatrix.DataWeb.dll junto con nuestra aplicación. Aquí podéis ver el error en el &lt;a href="https://connect.microsoft.com/webmatrix/feedback/details/665150/including-webmatrix-data-dll-webmatrix-webdata-dll-overrides-forms-loginurl" target="_blank"&gt;Windows Connect&lt;/a&gt;. Esto que a él le pasa con autenticación forms, parece que también pasa con autenticación windows.&lt;/p&gt;  &lt;p&gt;Finalmente hemos borrado estas dos librerías del bin de nuestra aplicación y voilà!&lt;/p&gt;  &lt;p&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/appok_5F00_079424DD.png"&gt;&lt;img style="background-image:none;border-right-width:0px;padding-left:0px;padding-right:0px;display:inline;border-top-width:0px;border-bottom-width:0px;border-left-width:0px;padding-top:0px;" title="appok" border="0" alt="appok" src="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/appok_5F00_thumb_5F00_3B5C1B2E.png" width="244" height="151" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Así que ya sabéis, id con cuidado con lo que desplegáis, no vayáis a tener resultados inesperados!!&lt;/p&gt;  &lt;p&gt;Un saludo!&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200472" width="1" height="1"&gt;</description></item><item><title>Autorización personalizada en ASP .Net MVC</title><link>http://geeks.ms/blogs/devnettips/archive/2011/09/05/autorizaci-243-n-personalizada-en-asp-net-mvc.aspx</link><pubDate>Mon, 05 Sep 2011 20:03:00 GMT</pubDate><guid isPermaLink="false">2a2e7ade-7474-448b-9de5-1515d8bb7d1b:200360</guid><dc:creator>Vicenç García Altés</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://geeks.ms/blogs/devnettips/rsscomments.aspx?PostID=200360</wfw:commentRss><comments>http://geeks.ms/blogs/devnettips/archive/2011/09/05/autorizaci-243-n-personalizada-en-asp-net-mvc.aspx#comments</comments><description>&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;El otro d&amp;iacute;a nos surgi&amp;oacute; un problema al realizar una aplicaci&amp;oacute;n Asp .Net MVC 3. Lo que necesit&amp;aacute;bamos era poder autorizar una aplicaci&amp;oacute;n en funci&amp;oacute;n de unos grupos que a priori no conoc&amp;iacute;amos, es decir, que quer&amp;iacute;amos poder configurar en el .config una serie de grupos que fueran los que tuvieran acceso a la aplicaci&amp;oacute;n. Esto nos llev&amp;oacute; a tener que hacer una autorizaci&amp;oacute;n personalizada en MVC. Veamos los pasos que tenemos que seguir para llevarla a cabo.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Para hacer esto nos apoyaremos en los action filters de MVC. Un action filter es un atributo que podemos aplicar a una acci&amp;oacute;n de un controlador o a un controlador entero que modifica la manera en que la acci&amp;oacute;n se ejecuta. En nuestro caso lo que haremos ser&amp;aacute; crear un action filter personalizado para poder implementar la autorizaci&amp;oacute;n personalizada que queremos.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Si nos vamos al global.asax vemos que hay una funci&amp;oacute;n llamada RegisterGlobalFilters en la que se est&amp;aacute; a&amp;ntilde;adiendo el HandleErrorAttribute. Vamos a a&amp;ntilde;adir nosotros aqu&amp;iacute; mismo un nuevo filtro llamado CustomAuthenticationAttribute:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/globalasax.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/globalasax.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;Vamos a echarle un ojo a la clase CustomAuthenticationAttribute. &lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;Lo primero que vemos es que es una clase que deriva de AuthorizeAttribute, para poder as&amp;iacute; sobrescribir el comportamiento por defecto de la autorizaci&amp;oacute;n. En el constructor, lo que estamos haciendo es cargar la lista de roles permitidos de nuestro web.config.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/customauthentication.png"&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/customauthentication.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/customauthentication.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="mso-ansi-language:ES;"&gt;Despu&amp;eacute;s vemos que hacemos un override de tres m&amp;eacute;todos:&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="mso-ansi-language:ES;"&gt;
&lt;p class="MsoListParagraph"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;em&gt;OnAuthorization&lt;/em&gt;&lt;br /&gt;Este es el m&amp;eacute;todo que se llama cuando un proceso solicita autorizaci&amp;oacute;n. En &amp;eacute;l, lo que haremos ser&amp;aacute; mirar si la acci&amp;oacute;n o el controlador est&amp;aacute; decorado con el atributo AllowAnonymous, hecho tambi&amp;eacute;n por nosotros. Esto nos permitir&amp;aacute; tener m&amp;eacute;todos accesibles para todo el mundo.&lt;br /&gt;&lt;/span&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/OnAuthorization.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/OnAuthorization.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;/span&gt;
&lt;p&gt;&lt;em&gt;A&lt;/em&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;em&gt;uthorizeCore&lt;br /&gt;&lt;/em&gt;&lt;/span&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;Este es el m&amp;eacute;todo que realiza la autorizaci&amp;oacute;n. Devuelve true si el acceso est&amp;aacute; permitido y false si no lo est&amp;aacute;. En nuestro caso, miraremos si el usuario que hace la petici&amp;oacute;n es miembro de alg&amp;uacute;n grupo de los definidos en el web.config. Aqu&amp;iacute; podr&amp;iacute;amos poner la l&amp;oacute;gica que fuera necesaria para cada caso en concreto.&lt;br /&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/authorizeCore.png" border="0" alt="" /&gt;&lt;/span&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;em&gt;HandleUnauthorizedRequest&lt;br /&gt;&lt;/em&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="line-height:115%;font-family:&amp;#39;Calibri&amp;#39;,&amp;#39;sans-serif&amp;#39;;font-size:11pt;mso-ansi-language:ES;mso-ascii-theme-font:minor-latin;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-hansi-theme-font:minor-latin;mso-bidi-font-family:&amp;#39;Times New Roman&amp;#39;;mso-bidi-theme-font:minor-bidi;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;&lt;span style="mso-ansi-language:ES;"&gt;Este es el m&amp;eacute;todo que se llama cuando una petici&amp;oacute;n a una acci&amp;oacute;n no ha sido autorizada. En nuestro caso haremos un redirect a un controlador que mostrar&amp;aacute; el mensaje de error.&lt;br /&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/HandleUnauthorized.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/HandleUnauthorized.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Tal y como hemos comentado anteriormente, tenemos que hacer el atributo que nos permitir&amp;aacute; tener un acceso an&amp;oacute;nimo a una acci&amp;oacute;n:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;&lt;a href="http://geeks.ms/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Anonymous.png"&gt;&lt;img src="http://geeks.ms/resized-image.ashx/__size/550x0/__key/CommunityServer.Blogs.Components.WeblogFiles/devnettips/Anonymous.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Para finalizar modificamos el Web.config. En nuestro caso a&amp;ntilde;adimos una entrada en el appSettings para indicar los roles que tienen permisos y configuramos la seguridad b&amp;aacute;sica denegando el acceso a todo usuario que no est&amp;eacute; autenticado.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Y con esto ya estamos. Espero que os haya servido. &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-family:Calibri;font-size:small;"&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p class="MsoNormal"&gt;&lt;span style="mso-ansi-language:ES;"&gt;&lt;span style="font-size:small;"&gt;&lt;span style="font-family:Calibri;"&gt;Un saludo!&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://geeks.ms/aggbug.aspx?PostID=200360" width="1" height="1"&gt;</description><category domain="http://geeks.ms/blogs/devnettips/archive/tags/asp/default.aspx">asp</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/mvc/default.aspx">mvc</category><category domain="http://geeks.ms/blogs/devnettips/archive/tags/autorizaci_26002300_243_3B00_n/default.aspx">autorizaci&amp;#243;n</category></item></channel></rss>