{"id":1278,"date":"2014-09-07T12:15:07","date_gmt":"2014-09-07T11:15:07","guid":{"rendered":"http:\/\/qualilogy.com\/es\/?p=1278"},"modified":"2014-09-08T16:36:58","modified_gmt":"2014-09-08T15:36:58","slug":"aplicacion-legacy-refactorizacion-reingenieria-5","status":"publish","type":"post","link":"http:\/\/qualilogy.com\/es\/aplicacion-legacy-refactorizacion-reingenieria-5\/","title":{"rendered":"Aplicaci\u00f3n Legacy \u2013 \u00bfRefactorizaci\u00f3n o reingenier\u00eda? (V)"},"content":{"rendered":"<p><a href=\"http:\/\/500px.com\/Vicken\" target=\"_blank\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-1992\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/Qualilogy-Legacy-Characterization-Tests.jpg\" alt=\"Legacy ou Reengineering - Tests de caracterisation\" width=\"239\" height=\"360\" \/><\/a>En nuestro <a title=\"Aplicaci\u00f3n Legacy \u2013 \u00bfRefactorizaci\u00f3n o reingenier\u00eda? (IV)\" href=\"http:\/\/qualilogy.com\/es\/aplicacion-legacy-refactorizacion-reingenieria-4\/\" target=\"_blank\">post anterior<\/a>, hemos hablado de la d\u00e9finici\u00f3n de Michael Feathers (en su libro \u00ab\u00a0Working Effectively with Legacy Code\u00a0\u00bb) explicando que la ausencia de pruebas unitarias es el factor determinante de una aplicaci\u00f3n Legacy. El propone el concepto de prueba de caracterizaci\u00f3n para entender el comportamiento de la aplicaci\u00f3n, es decir, lo que realmente hace, sin tratar de descubrir a trav\u00e9s del c\u00f3digo que se supone que debe hacer.<\/p>\n<p>Pero \u00bfqu\u00e9 pasa cuando nuestra aplicaci\u00f3n Legacy no tiene nada de pruebas unitarias? La respuesta a uno de nuestros tres escenarios \u2013 el plan de transferencia de la aplicaci\u00f3n a otro equipo \u2013 puede hacerse escribiendo estas pruebas? \u00bfEs posible facilitar la transferencia de conocimientos con pruebas unitarias? <!--more--><\/p>\n<h2>Las pruebas de caracterizaci\u00f3n<\/h2>\n<p>Michael Feathers recomienda en su libro hacer pruebas dise\u00f1adas no s\u00f3lo para verificar que el c\u00f3digo es correcto, pero tambi\u00e9n y sobre todo para caracterizar su comportamiento, es decir, para averiguar lo que realmente hace este c\u00f3digo. Las ventajas son:<\/p>\n<ul>\n<li>Permitir, sino la transferencia, pero al menos facilitar la adquisici\u00f3n del conocimiento de la aplicaci\u00f3n por un nuevo equipo.<\/li>\n<li>Desarrollar pruebas que ser\u00e1n v\u00e1lidas para nuestra futura operaci\u00f3n de refactorizaci\u00f3n o de reingenier\u00eda puesto que el comportamiento de nuestra aplicaci\u00f3n debe permanecer constante despu\u00e9s de esta operaci\u00f3n.<\/li>\n<\/ul>\n<p>Michael Feathers recomienda proceder de la siguiente manera:<\/p>\n<ol>\n<li>Para un bloque de c\u00f3digo a probar \/ documentar, escribir una prueba que sabemos que va a fallar.<\/li>\n<li>Ejecutar la prueba y registrar la repuesta esperada por el bloque de c\u00f3digo, que corresponde con el comportamiento esperado.<\/li>\n<li>A\u00f1adir una prueba para reflejar el comportamiento correcto, es decir, que devuelve un resultado positivo.<\/li>\n<li>Repetir tantas veces como deseado para este bloque de c\u00f3digo.<\/li>\n<\/ol>\n<p><a href=\"http:\/\/www.objectmentor.com\/resources\/articles\/WorkingEffectivelyWithLegacyCode.pdf\" target=\"_blank\">El ejemplo<\/a> que utiliza Michael Feathers corresponde al lenguaje Java, y puede ser diferente para otro c\u00f3digo Legado, especialmente para C, pero depender\u00e1 en todo caso de lo que quieres hacer, especialmente si tienes un framework de pruebas. No voy a profundizar este punto: los desarrolladores en C\/C++ saben mejor que yo sobre este tema.<\/p>\n<h2>Ejemplo de la funci\u00f3n RTFOUT<\/h2>\n<p>El m\u00e9todo recomendado por Michael Feathers sigue siendo el mismo, sea cual sea la tecnolog\u00eda (C, Java, etc.) que deseamos &#8216;caracterizar&#8217; y las herramientas que vamos a utilizar. Veamos un ejemplo con nuestra aplicaci\u00f3n Word 1.1a.<\/p>\n<p>Sabemos que <a title=\"Aplicaci\u00f3n Legacy C \u2013 \u00bfRefactorizaci\u00f3n o reingenier\u00eda? (II)\" href=\"http:\/\/qualilogy.com\/es\/aplicacion-legacy-c-refactorizacion-reingenieria-2\/\" target=\"_blank\">la funci\u00f3n m\u00e1s compleja<\/a>, con 355 puntos de CC (Complejidad Ciclom\u00e1tica) cuenta 2063 LOC (Lines Of Code)!<br \/>\nEl dashboard SonarQube me dice que esta funci\u00f3n est\u00e1 en un archivo con el mismo nombre &#8216;Opus\\RTFOUT.c&#8217;, y ella representa casi todo el c\u00f3digo (hay otra funci\u00f3n con 2 puntos de CC), con 1 124 instrucciones y una tasa de 17.5% de comentarios.<\/p>\n<p><a href=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOut1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2000\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOut1.jpg\" alt=\"La fonction RTFOut (Word) dans le dashboard SonarQube\" width=\"506\" height=\"142\" \/><\/a><br \/>\nLas primeras 200 l\u00edneas son una acumulaci\u00f3n de includes y variables con nombres esot\u00e9ricos, sin comentarios o mal documentados:<\/p>\n<p><a href=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOut2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2001\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOut2.jpg\" alt=\"La fonction RTFOUT (Word)\" width=\"546\" height=\"331\" \/><\/a>Ni siquiera sirve intentar de entender de que se trata.<\/p>\n<p>Sin embargo, despu\u00e9s de unos &#8216;if .. else&#8217;, encuentro\u00a0r\u00e1pidamente el siguiente &#8216;switch&#8217;:<\/p>\n<p><a href=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOutSwitchFF.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2002\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOutSwitchFF.jpg\" alt=\"Switch dans la fonction TRFOut\" width=\"501\" height=\"416\" \/><\/a>Ahora entiendo que estamos en presencia de una funci\u00f3n responsable de la producci\u00f3n del formato RTF (Rich Text Format) del texto escrito en Word, y este primer &#8216;switch&#8217; especifica el tipo de fuente &#8211; Modern, Roman, Swiss, etc. &#8211; utilizado en este formato. Y la variable &#8216;fmc&#8217; gestionar\u00e1 estos valores.<\/p>\n<p>Otro &#8216;switch&#8217;, bastante largo, gestiona las propiedades del documento, si est\u00e1n disponibles: t\u00edtulo, tema, autor, etc.<br \/>\n<a href=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOutSwitchP1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2003\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOutSwitchP1.jpg\" alt=\"Switch fonction RTFOut\" width=\"321\" height=\"344\" \/><\/a>\u00a0&#8230; la fecha de la \u00faltima edici\u00f3n del documento, el n\u00famero de p\u00e1ginas, n\u00famero de palabras o de caracteres:<\/p>\n<p><a href=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOutSwitchP2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2004\" src=\"http:\/\/qualilogy.com\/fr\/wp-content\/uploads\/sites\/2\/2014\/09\/WordRTFOutSwitchP2.jpg\" alt=\"Switch fonction RTFOut\" width=\"307\" height=\"232\" \/><\/a><\/p>\n<p>Sin embargo me doy cuenta que puedo identificar todos los bloques de c\u00f3digo bastante simples y legibles y desarrollar pruebas de caracterizaci\u00f3n, una para cada valor posible encontrado en una estructura condicional (&#8216;end .. if&#8217;, &#8216;switch&#8217;) o bucle (que requiere tambi\u00e9n una condici\u00f3n). En este caso, se puede escribir una o m\u00e1s pruebas para verificar los valores existentes o no.<\/p>\n<p>Por ejemplo, voy a probar los diferentes estados de la variable &#8216;fmc&#8217; con los valores que podemos encontrar en el c\u00f3digo: &#8216;FF_ROMAN&#8217;, &#8216;FF_MODERN&#8217; &#8230; o un valor inexistente &#8216;FF_WRONG&#8217; para ver c\u00f3mo reacciona la aplicaci\u00f3n.<\/p>\n<p>Del mismo modo para la variable &#8216;flt&#8217; que maneja las propiedades del documento: puedo probar todo tipo de valores impossibles para ver de nuevo c\u00f3mo se comporta la aplicaci\u00f3n en este caso. \u00bfQu\u00e9 est\u00e1 pasando, por ejemplo, si hago una prueba:<\/p>\n<ul>\n<li>Con un n\u00famero de p\u00e1ginas igual a 999 999?<\/li>\n<li>Con caracteres especiales (@, #,!, \u00bf, &#8230;) en el nombre del autor?<\/li>\n<li>Con diferentes formatos para la fecha de la \u00faltima actualizaci\u00f3n?<\/li>\n<\/ul>\n<p>Por supuesto, unos bloques de c\u00f3digo, como la gesti\u00f3n en memoria de la tabla de los marcadores (bookmarks) en un documento Word, ser\u00e1n demasiado complejos para que sea posible entender y probar de manera adecuada y sin ning\u00fan tipo de ayuda. Pero recuerda que el objetivo principal no es de entender lo que se supone que debe hacer la aplicaci\u00f3n a trav\u00e9s de su c\u00f3digo, sino caracterizar su comportamiento.<\/p>\n<p>Tambi\u00e9n descubr\u00ed muy r\u00e1pidamente l\u00edneas de c\u00f3digo que se repiten antes de cada bucle o cada &#8216;switch&#8217;. Supongo que son variables que se inicializan antes de cada tratamiento y se actualizan durante aquellos. Tomo nota de revisar la documentaci\u00f3n (si la hay) o pedir informaci\u00f3n al equipo actual respecto a estas variables. Si se repiten con tanta frecuencia, eso puede tener un impacto en un nuevo dise\u00f1o de esta funci\u00f3n durante una refactorizaci\u00f3n o reingenier\u00eda.<\/p>\n<p>NOTA: Un problema con el lenguaje C es que ciertos objetos se externalizan (en un include o una macro). Como lo describe Michael Feathers en su libro, es muy posible modificar el c\u00f3digo para crear y utilizar nuestro propio include con una llamada a estos componentes para comprobar r\u00e1pidamente si se les llama con el n\u00famero correcto de par\u00e1metros y con los tipos adecuados. Por favor, consulte su libro si tiene alguna pregunta, no voy a mencionar todas ellas en este post.<\/p>\n<p>Otro problema que encontr\u00e9 en el c\u00f3digo: una gran cantidad de directivas de compilador #IFNDEF o para diferentes plataformas (Mac). Por lo tanto, se deben tener en cuenta en la reingenier\u00eda.<\/p>\n<h2>S\u00edntesis<\/h2>\n<p>La ventaja del enfoque recomendado por Michael Feathers es de investigar, no lo que la aplicaci\u00f3n se supone que debe hacer, a trav\u00e9s de su c\u00f3digo \u2013 tarea larga, y a veces imposible \u2013 pero en lo que la aplicaci\u00f3n hace realmente. Sobre todo porque la aplicaci\u00f3n no siempre se comporta como se supone que deber\u00eda hacerlo.<\/p>\n<p>Podemos crear r\u00e1pidamente pruebas en bloques de c\u00f3digo con estructuras condicionales (&#8216;if .. else&#8217;, &#8216;switch&#8217;) o bucle. Recuerda que cada camino o \u00abpath\u00bb en estas estructuras es una regla de l\u00f3gica de negocio y por lo tanto normalmente deber\u00eda estar cubierto por una prueba correspondiente.<\/p>\n<p>Lo cual nos lleva a la pregunta siguiente: \u00bfcu\u00e1ntos tests de caracterizaci\u00f3n son necesarios para asegurar la transferencia de conocimientos de esta aplicaci\u00f3n Legacy? \u00bfQu\u00e9 cobertura de c\u00f3digo asegurar antes de empiezar una refactorizaci\u00f3n o una reingenier\u00eda? \u00bfPodemos estimar el esfuerzo de pruebas que se necesitan? Esto es lo que veremos en nuestro pr\u00f3ximo post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En nuestro post anterior, hemos hablado de la d\u00e9finici\u00f3n de Michael Feathers (en su libro \u00ab\u00a0Working Effectively with Legacy Code\u00a0\u00bb) explicando que la ausencia de pruebas unitarias es el factor determinante de una aplicaci\u00f3n Legacy. El propone el concepto de prueba de caracterizaci\u00f3n para entender el comportamiento de la aplicaci\u00f3n, es decir, lo que realmente [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-1278","post","type-post","status-publish","format-standard","hentry","category-calidad-de-aplicaciones"],"_links":{"self":[{"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/posts\/1278"}],"collection":[{"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/comments?post=1278"}],"version-history":[{"count":24,"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/posts\/1278\/revisions"}],"predecessor-version":[{"id":1280,"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/posts\/1278\/revisions\/1280"}],"wp:attachment":[{"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/media?parent=1278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/categories?post=1278"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/qualilogy.com\/es\/wp-json\/wp\/v2\/tags?post=1278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}