{"id":230094,"date":"2022-11-27T14:53:00","date_gmt":"2022-11-27T11:53:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=230094"},"modified":"2022-11-27T15:05:53","modified_gmt":"2022-11-27T12:05:53","slug":"escritura-de-pruebas-unitarias-con-phpunit-parte-2-el-derribo","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/escritura-de-pruebas-unitarias-con-phpunit-parte-2-el-derribo\/","title":{"rendered":"Escritura de pruebas unitarias con PHPUnit, parte 2: el derribo"},"content":{"rendered":"\n<p><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/escritura-de-pruebas-unitarias-con-phpunit-parte-1-la-configuracion\/\" title=\"A fines del mes pasado\">A fines del mes pasado<\/a><\/strong>, comenc\u00e9 a hablar sobre escribir pruebas unitarias en PHPUnit para c\u00f3digo basado en WordPress. Esto inclu\u00eda principalmente la idea de configurar <strong><a href=\"https:\/\/phpunit.de\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">PHPUnit<\/a><\/strong>, la <strong>funci\u00f3n de configuraci\u00f3n<\/strong> y escribir pruebas b\u00e1sicas.<\/p>\n<p>Sin embargo, esto no discuti\u00f3 lo que s\u00e9 sobre la funci\u00f3n <strong>tearDown<\/strong>, que sigue siendo una caracter\u00edstica importante de escribir usando pruebas. Adem\u00e1s, tambi\u00e9n hay dos formas de considerar escribir pruebas para proyectos de WordPress.<\/p>\n<p>A saber:<\/p>\n<ol>\n<li>escribir pruebas espec\u00edficamente para complementos y funcionalidad de capa de aplicaci\u00f3n,<\/li>\n<li>ejecutando pruebas unitarias contra la aplicaci\u00f3n de WordPress.<\/li>\n<\/ol>\n<p>Sin embargo, antes de continuar con esta publicaci\u00f3n en particular, recomiendo ponerse al d\u00eda con lo que he cubierto hasta ahora. Esto incluye las siguientes publicaciones:<\/p>\n<ol>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/un-entorno-de-desarrollo-de-wordpress-usando-un-administrador-de-paquetes\/\" title=\"Un entorno de desarrollo de WordPress (usando un administrador de paquetes)\">Un entorno de desarrollo de WordPress (usando un administrador de paquetes)<\/a><\/strong><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/es\/un-ide-para-el-desarrollo-de-wordpress-independientemente-de-la-experiencia\/\" title=\"Un IDE para el desarrollo de WordPress\">Un IDE para el desarrollo de WordPress<\/a><\/li>\n<li><strong><a href=\"https:\/\/wordpress.mediadoma.com\/es\/trabajar-con-la-configuracion-de-usuario-en-visual-studio-code\/\" title=\"Trabajar con la configuraci\u00f3n de usuario en Visual Studio Code\">Trabajar con la configuraci\u00f3n de usuario en Visual Studio Code<\/a><\/strong><\/li>\n<li><a href=\"https:\/\/wordpress.mediadoma.com\/es\/escritura-de-pruebas-unitarias-con-phpunit-parte-1-la-configuracion\/\" title=\"Escritura de pruebas unitarias con PHPUnit, Parte 1: La configuraci\u00f3n\">Escritura de pruebas unitarias con PHPUnit, Parte 1: La configuraci\u00f3n<\/a><\/li>\n<\/ol>\n<p>Una vez que haya hecho eso, regrese a esta publicaci\u00f3n y continuemos discutiendo la funci\u00f3n tearDown y c\u00f3mo se ven realmente las pruebas unitarias en el contexto de WordPress.<\/p>\n<h2>Pruebas unitarias con PHPUnit, Parte 2: El derribo<\/h2>\n<p>Antes de continuar, recuerde que los desarrolladores a menudo tratan la <strong>funci\u00f3n<\/strong> de instalaci\u00f3n como el constructor y la funci\u00f3n de <strong>desmontaje<\/strong> como un destructor; sin embargo, recuerde que esto \u00faltimo no siempre es necesario.<\/p>\n<p>Aqu\u00ed hay una buena regla general para recordar:<\/p>\n<ul>\n<li>Cualquier cosa que necesite una funci\u00f3n de prueba llamar\u00e1 a la funci\u00f3n <strong>setUp<\/strong> para que se necesiten las clases necesarias.<\/li>\n<li>La funci\u00f3n <strong>tearDown<\/strong> no siempre es necesaria ya que la funci\u00f3n <strong>setUp<\/strong> puede reinicializar una clase.<\/li>\n<\/ul>\n<p>Entonces, \u00bfqu\u00e9 significa esto para la funci\u00f3n <strong>tearDown<\/strong> si no restablece los datos que se crean durante la funci\u00f3n de <strong>configuraci\u00f3n<\/strong>? <\/p>\n<h3>1 La funci\u00f3n de desmontaje<\/h3>\n<p>El mejor consejo que puedo dar sobre la funci\u00f3n <strong>tearDown<\/strong> es que debe usarse si se configura algo durante una de las pruebas que se quedan atr\u00e1s.<\/p>\n<p>Esto podr\u00eda ser algo que se escribe en una base de datos, algo que se escribe en un registro o, de manera m\u00e1s general, algo que se escribe en el disco duro.<\/p>\n<p>Por lo tanto, si una prueba escribe un registro o un archivo, el m\u00e9todo <strong>tearDown<\/strong> se ejecutar\u00e1 despu\u00e9s de una prueba y deber\u00eda eliminar cualquier prueba grabada en la unidad que no sea parte de la prueba pero que no se necesite permanentemente para la pr\u00f3xima prueba o que debe limpiarse despu\u00e9s de s\u00ed mismo.<\/p>\n<p>Entonces, en cierto sentido, es como un <strong><a href=\"http:\/\/en.cppreference.com\/w\/cpp\/language\/destructor\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">destructor<\/a><\/strong>, pero si nunca ha usado un lenguaje que tiene un destructor, esa nomenclatura parece irrelevante o no tiene sentido.<\/p>\n<blockquote>\n<p>Un <strong>destructor<\/strong> es una funci\u00f3n miembro especial que se llama cuando finaliza el tiempo de vida de un objeto. El prop\u00f3sito del <strong>destructor<\/strong> es liberar los recursos que el objeto haya podido adquirir durante su vida.<\/p>\n<\/blockquote>\n<p>Por lo tanto, tal vez sea mejor simplemente pensar en la funci\u00f3n como una forma de limpieza despu\u00e9s de una prueba (y no en el sentido de establecer una variable igual a nula ya que la funci\u00f3n <strong>setUp<\/strong> puede hacer eso).<\/p>\n<h3>2 pruebas unitarias para proyectos de WordPress<\/h3>\n<p>Al escribir pruebas unitarias para proyectos de WordPress, debemos asegurarnos de ser claros sobre el tipo de pruebas unitarias de las que estamos hablando.<\/p>\n<p>Por ejemplo, a lo que me referir\u00e9 como pruebas unitarias cl\u00e1sicas o est\u00e1ndar siguen la metodolog\u00eda de &quot;desarrollo basado en pruebas&quot; de la que hablar\u00e9 en un momento. Por otro lado, WordPress tiene su propio conjunto de pruebas unitarias para temas y similares, de los que tambi\u00e9n hablar\u00e9 un poco m\u00e1s adelante en esta publicaci\u00f3n.<\/p>\n<p>Pero para esta secci\u00f3n, pens\u00e9 que podr\u00eda ser \u00fatil hablar un poco sobre lo primero en lugar de lo segundo para que pueda ver c\u00f3mo podr\u00eda funcionar.<\/p>\n<p>En el siguiente ejemplo, estoy escribiendo pruebas contra un complemento que es responsable de comunicarse con una API de terceros. Este complemento en particular requiere un nombre de usuario y contrase\u00f1a o una API <strong>y<\/strong> queremos asegurarnos de que, para los fines de esta publicaci\u00f3n, recupere correctamente un error cada vez que se ejecute la prueba.<\/p>\n<p>Tenga en cuenta que al leer este c\u00f3digo, me ver\u00e1 hablar un poco sobre la reflexi\u00f3n. Voy a hacer una publicaci\u00f3n completa sobre PHP Reflection pronto para arrojar algo de luz sobre esto.<\/p>\n<p>Sin embargo, para el c\u00f3digo a continuaci\u00f3n, suponga que es una forma en que podemos obtener acceso a propiedades que de otro modo estar\u00edan marcadas como privadas.<\/p>\n<p>Recordemos de la \u00faltima publicaci\u00f3n de esta serie, tuvimos una prueba inicial que se ve\u00eda <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/248c7741273e6be414c1f98c11085fe7#file-01-acme-cache-test-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">as\u00ed:<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nuse PHPUnitFrameworkTestCase;\n\nclass AcmeCacheTest extends TestCase\n{\n  protected $cache;\n\n  protected function setUp()\n  {\n    $this-&gt;cache = new AcmeCache();\n  }\n\n  public function testDefaultDuration()\n  {\n    $this-&gt;assertTrue($this-&gt;cache-&gt;getDuration() === 43200);\n  }\n\n  public function testNewDuration()\n  {\n    $this-&gt;cache-&gt;setDuration(1000);\n\n    $this-&gt;assertFalse($this-&gt;cache-&gt;getDuration() === 43200);\n    $this-&gt;assertTrue($this-&gt;cache-&gt;getDuration() === 1000);\n  }\n\n  \/\/ More to come...\n}<\/code><\/pre>\n<p>Tenga en cuenta, sin embargo, que en esta prueba no hay una funci\u00f3n <strong>de desmontaje<\/strong> que tenga sentido, \u00bfverdad? Despu\u00e9s de todo, no se escribe nada en una base de datos o en un archivo.<\/p>\n<p>Pero digamos que queremos presentar un caso de prueba que tendr\u00e1 un nombre de archivo, contenido y escribir\u00e1 el contenido en el archivo. En este caso, ser\u00e1n datos est\u00e1ticos, pero t\u00e9cnicamente podr\u00edan ser cualquier cosa que est\u00e9 escrita en el disco.<\/p>\n<h4>1 Configuraci\u00f3n de la prueba<\/h4>\n<p><strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/ca4f83191255e661a84e3563b27263de#file-00-initial-set-up-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Primero<\/a><\/strong>, queremos configurar la prueba definiendo el nombre del archivo, el contenido del archivo y preparando las propiedades.<\/p>\n<pre><code>&lt;?php\n\nnamespace PresswareAcmeTestsAPI;\n\nuse PHPUnitFrameworkTestCase;\n\nclass AcmeFileTest extends TestCase\n{\n\n  private $filename;\n\n  private $content;\n\n  public function setUp()\n  {\n    $this-&gt;filename = 'testFile.txt';\n    $this-&gt;content = 'This is a string of data that is meant to be written to the file.';\n  }\n\n  \/\/ More to come...\n}\n<\/code><\/pre>\n<p>Bastante f\u00e1cil, \u00bfverdad?<\/p>\n<h4>2 Escribir y leer datos<\/h4>\n<p>A continuaci\u00f3n, queremos escribir los datos, leer los datos y afirmar que los contenidos <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/ca4f83191255e661a84e3563b27263de#file-01-testing-contents-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">son los mismos.<\/a><\/strong><\/p>\n<pre><code>&lt;?php\n\nnamespace PresswareAcmeTestsAPI;\n\nuse PHPUnitFrameworkTestCase;\n\nclass AcmeFileTest extends TestCase\n{\n\n  private $filename;\n\n  private $content;\n\n  public function setUp()\n  {\n    $this-&gt;filename = 'testFile.txt';\n    $this-&gt;content = 'This is a string of data that is meant to be written to the file.';\n  }\n\n  public function testWriteReadData()\n  {    \n    \/\/ Writes the content to the file with the given filename.\n    $fileHandle = fopen($this-&gt;filename, 'w');\n    fwrite($fileHandle, $this-&gt;content);\n    fclose($fileHandle);\n\n    \/\/ Reads the contents of the file that was just written\n    $fileHandle = fopen($this-&gt;filename, 'r');\n    $contents = fread($fileHandle, filesize($this-&gt;filename));\n    fclose($fileHandle);\n\n    $this-&gt;assertSame($this-&gt;content, $contents);\n  }\n\n  \/\/ More to come..\n}\n<\/code><\/pre>\n<p>En este punto, si ejecuta la prueba (que a\u00fan no he cubierto t\u00e9cnicamente sobre c\u00f3mo hacerlo), notar\u00e1 que <strong>testFile.txt<\/strong> a\u00fan reside en su sistema.<\/p>\n<h4>3 Uso de desmontaje<\/h4>\n<p>Finalmente, debemos trabajar con el m\u00e9todo <strong>tearDown<\/strong> para asegurarnos de que el archivo se elimine al finalizar la prueba unitaria. <strong><a href=\"https:\/\/gist.github.com\/tommcfarlin\/ca4f83191255e661a84e3563b27263de#file-02-full-test-php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">As\u00ed es como puede verse<\/a><\/strong> si ha implementado su c\u00f3digo como lo que ve arriba.<\/p>\n<pre><code>&lt;?php\n\nnamespace PresswareAcmeTestsAPI;\n\nuse PHPUnitFrameworkTestCase;\n\nclass AcmeFileTest extends TestCase\n{\n\n  private $filename;\n\n  private $content;\n\n  public function setUp()\n  {\n    $this-&gt;filename = 'testFile.txt';\n    $this-&gt;content = 'This is a string of data that is meant to be written to the file.';\n  }\n\n  public function testWriteReadData()\n  {    \n    \/\/ Writes the content to the file with the given filename.\n    $fileHandle = fopen($this-&gt;filename, 'w');\n    fwrite($fileHandle, $this-&gt;content);\n    fclose($fileHandle);\n\n    \/\/ Reads the contents of the file that was just written\n    $fileHandle = fopen($this-&gt;filename, 'r');\n    $contents = fread($fileHandle, filesize($this-&gt;filename));\n    fclose($fileHandle);\n\n    $this-&gt;assertSame($this-&gt;content, $contents);\n  }\n\n  public function tearDown()\n  {\n    if (file_exists($this-&gt;filename)) {\n      unlink($this-&gt;filename);\n    }\n  }\n}\n<\/code><\/pre>\n<p>Tenga en cuenta que en el m\u00e9todo <strong>tearDown, primero verifico si existe un<\/strong> <a href=\"https:\/\/php.net\/manual\/en\/function.file-exists.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">archivo<\/a>. Esto se debe a que si simplemente intenta <a href=\"https:\/\/php.net\/manual\/en\/function.unlink.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">desvincular<\/a> un archivo que no est\u00e1 presente, obtendr\u00e1 un error al ejecutar sus pruebas porque si <strong>tearDown<\/strong> est\u00e1 presente, intentar\u00e1 eliminar algo despu\u00e9s de cada funci\u00f3n de prueba. Y si el archivo no existe, entonces no hay nada que eliminar y, por lo tanto, resultar\u00e1 en un problema.<\/p>\n<p>Entonces, en un intento de escribir c\u00f3digo a la defensiva, creo que es responsable de verificar si el archivo existe antes de intentar eliminarlo.<\/p>\n<h3>3 Orden de Operaciones<\/h3>\n<p>Cuando se trata de pruebas unitarias puras, normalmente leer\u00e1 esto en t\u00e9rminos de <strong><a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">desarrollo basado en pruebas<\/a><\/strong>. Este es un gran tema en s\u00ed mismo; sin embargo, vale la pena mencionarlo aqu\u00ed si opta por investigarlo m\u00e1s e incluso implementarlo en sus esfuerzos de desarrollo.<\/p>\n<p>La idea general detr\u00e1s de este enfoque a menudo se denomina &quot;repetici\u00f3n rojo-verde&quot;. Y no lo niego, hay algo en este enfoque. Es decir, le permite a usted, como desarrollador, escribir c\u00f3digo como espera que funcione antes de escribir el c\u00f3digo.<\/p>\n<p>La psicolog\u00eda detr\u00e1s de esto es la siguiente: si sabe c\u00f3mo funciona el c\u00f3digo, es m\u00e1s probable que escriba pruebas que pasen; mientras que, si escribe pruebas sobre c\u00f3mo deber\u00eda funcionar el c\u00f3digo, deber\u00eda escribir un mejor c\u00f3digo.<\/p>\n<p>Desafortunadamente, no siempre tenemos ese lujo. Pero eso no significa que debamos tirar al proverbial beb\u00e9 con el agua. En cambio, tengo la mentalidad de que debe escribir pruebas cuando pueda y escribir el c\u00f3digo despu\u00e9s; de lo contrario, escriba sus pruebas despu\u00e9s de su c\u00f3digo.<\/p>\n<p>En \u00faltima instancia, tener pruebas independientemente ser\u00e1 mejor que ninguna prueba.<\/p>\n<h3>4 Pruebas con WordPress<\/h3>\n<p>Cuando se trata de pruebas unitarias en WordPress, hay algunas cosas con las que probablemente te hayas topado. A veces, el contenido es un nombre inapropiado o incluso puede ser enga\u00f1oso en t\u00e9rminos de &quot;pruebas unitarias en WordPress&quot;.<\/p>\n<p><a href=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-164139-61e75e67162bf.png\" data-rel=\"lightbox\"><img decoding=\"async\" class=\"SDStudio-light-box-enable SDStudio-editor-tools-md-imp\" src=\"https:\/\/wordpress.mediadoma.com\/wp-content\/uploads\/2022\/01\/post-164139-61e75e67162bf.png\" alt=\"Escritura de pruebas unitarias con PHPUnit, parte 2: el derribo\"><\/a><\/p>\n<p>Por ejemplo, hay dos cosas que vale la pena se\u00f1alar:<\/p>\n<ol>\n<li><strong><a href=\"https:\/\/codex.wordpress.org\/Theme_Unit_Test\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">La prueba de unidad tem\u00e1tica<\/a><\/strong>. Este conjunto particular de contenido est\u00e1 destinado a ayudar a los desarrolladores de temas a probar todos los casos principales y secundarios de sus temas. No hay herramientas automatizadas, por ejemplo, que usar\u00eda como en lo que hemos discutido anteriormente.<\/li>\n<li><strong><a href=\"https:\/\/make.wordpress.org\/core\/handbook\/testing\/automated-testing\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Pruebas automatizadas<\/a><\/strong>. WordPress se env\u00eda con su propio conjunto de pruebas unitarias para que no tengamos que escribir pruebas contra la mayor\u00eda de las funciones de WordPress (como si las funciones de la API funcionan o no como se esperaba). Esto nos permite centrarnos en escribir pruebas unitarias para nuestra propia l\u00f3gica de dominio.<\/li>\n<li><strong><a href=\"https:\/\/make.wordpress.org\/cli\/handbook\/plugin-unit-tests\/\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">Pruebas unitarias de complementos<\/a><\/strong>. Si ha usado WP-CLI (o est\u00e1 interesado en \u00e9l), probablemente haya le\u00eddo esta p\u00e1gina o incluso haya usado esta herramienta. Es \u00fatil, pero tambi\u00e9n se enfoca en aspectos espec\u00edficos de la prueba de complementos de WordPress.<\/li>\n<\/ol>\n<p>Todo lo anterior es informaci\u00f3n \u00fatil, y no digo que deba ser ignorada. En cambio, debe combinarse con el resto de la informaci\u00f3n utilizada en esta publicaci\u00f3n.<\/p>\n<h2>Ejecuci\u00f3n de pruebas unitarias<\/h2>\n<p>En la pr\u00f3xima publicaci\u00f3n, lo guiar\u00e9 a trav\u00e9s de todo lo que necesita saber para configurar un archivo XML que informar\u00e1 a PHPUnit sobre d\u00f3nde residen las pruebas y c\u00f3mo ejecutarlas.<\/p>\n<p>Sin embargo, por ahora, revise el c\u00f3digo que se encuentra en esta publicaci\u00f3n y prep\u00e1rese para desarrollarlo en la pr\u00f3xima publicaci\u00f3n de esta serie.<\/p>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/tommcfarlin.com\" class=\"external external_icon\">tommcfarlin.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Un tutorial sobre c\u00f3mo escribir pruebas unitarias que aprovechen adecuadamente los m\u00e9todos de configuraci\u00f3n y desmontaje de PHPUnit.<\/p>\n","protected":false},"author":1,"featured_media":164140,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[716,800,840],"tags":[1172],"class_list":["post-230094","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-desarrollador","category-php-2","category-tutoriales","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230094","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=230094"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/230094\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/164140"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=230094"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=230094"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=230094"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}