¿Cómo escribo pruebas unitarias en PHP? [closed]

7 minutos de lectura

avatar de usuario
Déjalo ir

He leído en todas partes sobre lo geniales que son, pero por alguna razón parece que no puedo entender cómo se supone que debo probar algo exactamente. ¿Podría alguien publicar un código de ejemplo y cómo lo probarían? Si no es mucho problema 🙂

avatar de usuario
Hasta

Hay un tercer “marco”, que es mucho más fácil de aprender, incluso más fácil que SimplePrueba, se llama phpt.

Una cartilla se puede encontrar aquí:
http://qa.php.net/write-test.php

Editar: Acabo de ver su solicitud de código de muestra.

Supongamos que tiene la siguiente función en un archivo llamado lib.php:

<?php
function foo($bar)
{
  return $bar;
}
?>

Realmente simple y directo, se devuelve el parámetro que pasa. Así que veamos una prueba para esta función, llamaremos al archivo de prueba foo.phpt:

--TEST--
foo() function - A basic test to see if it works. :)
--FILE--
<?php
include 'lib.php'; // might need to adjust path if not in the same dir
$bar="Hello World";
var_dump(foo($bar));
?>
--EXPECT--
string(11) "Hello World"

En pocas palabras, proporcionamos el parámetro $bar con valor "Hello World" y nosotros var_dump() la respuesta de la llamada de función a foo().

Para ejecutar esta prueba, utilice: pear run-test path/to/foo.phpt

Esto requiere una instalación funcional de PEAR en su sistema, lo cual es bastante común en la mayoría de las circunstancias. Si necesita instalarlo, le recomiendo instalar la última versión disponible. En caso de que necesite ayuda para configurarlo, no dude en preguntar (pero proporcione el sistema operativo, etc.).

  • ¿No debería ser run-tests?

    – Darman

    26 de marzo de 2019 a las 23:01

avatar de usuario
okomán

Hay dos marcos que puede usar para las pruebas unitarias. más simple y Unidad PHP, que prefiero. Lea los tutoriales sobre cómo escribir y ejecutar pruebas en la página de inicio de PHPUnit. Es bastante fácil y está bien descrito.

avatar de usuario
Preston

Puede hacer que las pruebas unitarias sean más efectivas cambiando su estilo de codificación para adaptarlo.

Recomiendo navegar por el Blog de pruebas de Googleen particular la publicación sobre Escribir código comprobable.

  • Creo que mencionaste una gran publicación. Sin embargo, comenzar su respuesta con ‘Las pruebas unitarias no son muy efectivas’ casi me hizo votar negativamente, siendo un experto en pruebas … Posiblemente, reformular de manera positiva alentaría a las personas a leer el artículo.

    – xtofl

    5 de noviembre de 2013 a las 5:53

  • @xtofl lo editó para aumentar ligeramente la ‘positividad’ 🙂

    – icc97

    25 de febrero de 2016 a las 1:02

avatar de usuario
Kris

Hice el mío porque no tuve tiempo de aprender la forma de hacer las cosas de otra persona, me llevó unos 20 minutos escribirlo y 10 adaptarlo para publicarlo aquí.

La prueba unitaria es muy util para mi

esto es un poco largo pero se explica solo y hay un ejemplo en la parte inferior.

/**
 * Provides Assertions
 **/
class Assert
{
    public static function AreEqual( $a, $b )
    {
        if ( $a != $b )
        {
            throw new Exception( 'Subjects are not equal.' );
        }
    }
}

/**
 * Provides a loggable entity with information on a test and how it executed
 **/
class TestResult
{
    protected $_testableInstance = null;

    protected $_isSuccess = false;
    public function getSuccess()
    {
        return $this->_isSuccess;
    }

    protected $_output="";
    public function getOutput()
    {
        return $_output;
    }
    public function setOutput( $value )
    {
        $_output = $value;
    }

    protected $_test = null;
    public function getTest()
    {
        return $this->_test;
    }

    public function getName()
    {
        return $this->_test->getName();
    }
    public function getComment()
    {
        return $this->ParseComment( $this->_test->getDocComment() );
    }

    private function ParseComment( $comment )
    {
        $lines = explode( "\n", $comment );
        for( $i = 0; $i < count( $lines ); $i ++ )
        {
            $lines[$i] = trim( $lines[ $i ] );
        }
        return implode( "\n", $lines );
    }

    protected $_exception = null;
    public function getException()
    {
        return $this->_exception;
    }

    static public function CreateFailure( Testable $object, ReflectionMethod $test, Exception $exception )
    {
        $result = new self();
        $result->_isSuccess = false;
        $result->testableInstance = $object;
        $result->_test = $test;
        $result->_exception = $exception;

        return $result;
    }
    static public function CreateSuccess( Testable $object, ReflectionMethod $test )
    {
        $result = new self();
        $result->_isSuccess = true;
        $result->testableInstance = $object;
        $result->_test = $test;

        return $result;
    }
}

/**
 * Provides a base class to derive tests from
 **/
abstract class Testable
{
    protected $test_log = array();

    /**
     * Logs the result of a test. keeps track of results for later inspection, Overridable to log elsewhere.
     **/
    protected function Log( TestResult $result )
    {
        $this->test_log[] = $result;

        printf( "Test: %s was a %s %s\n"
            ,$result->getName()
            ,$result->getSuccess() ? 'success' : 'failure'
            ,$result->getSuccess() ? '' : sprintf( "\n%s (lines:%d-%d; file:%s)"
                ,$result->getComment()
                ,$result->getTest()->getStartLine()
                ,$result->getTest()->getEndLine()
                ,$result->getTest()->getFileName()
                )
            );

    }
    final public function RunTests()
    {
        $class = new ReflectionClass( $this );
        foreach( $class->GetMethods() as $method )
        {
            $methodname = $method->getName();
            if ( strlen( $methodname ) > 4 && substr( $methodname, 0, 4 ) == 'Test' )
            {
                ob_start();
                try
                {
                    $this->$methodname();
                    $result = TestResult::CreateSuccess( $this, $method );
                }
                catch( Exception $ex )
                {
                    $result = TestResult::CreateFailure( $this, $method, $ex );
                }
                $output = ob_get_clean();
                $result->setOutput( $output );
                $this->Log( $result );
            }
        }
    }
}

/**
 * a simple Test suite with two tests
 **/
class MyTest extends Testable
{
    /**
     * This test is designed to fail
     **/
    public function TestOne()
    {
        Assert::AreEqual( 1, 2 );
    }

    /**
     * This test is designed to succeed
     **/
    public function TestTwo()
    {
        Assert::AreEqual( 1, 1 );
    }
}

// this is how to use it.
$test = new MyTest();
$test->RunTests();

Esto da como resultado:

Test: TestOne was a failure 
/**
* This test is designed to fail
**/ (lines:149-152; file:/Users/kris/Desktop/Testable.php)
Test: TestTwo was a success 

Obtener PHPUnit. Es muy fácil de usar.

Luego comience con afirmaciones muy simples. Puedes hacer mucho con AssertEquals antes de entrar en cualquier otra cosa. Esa es una buena manera de mojarte los pies.

También puede intentar escribir su prueba primero (ya que le dio a su pregunta la etiqueta TDD) y luego escribir su código. Si no has hecho esto antes, es una revelación.

require_once 'ClassYouWantToTest';
require_once 'PHPUnit...blah,blah,whatever';

class ClassYouWantToTest extends PHPUnit...blah,blah,whatever
{
    private $ClassYouWantToTest;

   protected function setUp ()
    {
        parent::setUp();
        $this->ClassYouWantToTest = new ClassYouWantToTest(/* parameters */);
    }

    protected function tearDown ()
    {
        $this->ClassYouWantToTest = null;
        parent::tearDown();
    }

    public function __construct ()
    {   
        // not really needed
    }

    /**
     * Tests ClassYouWantToTest->methodFoo()
     */
    public function testMethodFoo ()
    {
        $this->assertEquals(
            $this->ClassYouWantToTest->methodFoo('putValueOfParamHere), 'expectedOutputHere);

    /**
     * Tests ClassYouWantToTest->methodBar()
     */
    public function testMethodFoo ()
    {
        $this->assertEquals(
            $this->ClassYouWantToTest->methodBar('putValueOfParamHere), 'expectedOutputHere);
}

avatar de usuario
Comunidad

Para pruebas simples Y documentación, php-doctest es bastante bueno y es una manera muy fácil de comenzar ya que no tiene que abrir un archivo separado. Imagina la siguiente función:

/**
* Sums 2 numbers
* <code>
* //doctest: add
* echo add(5,2);
* //expects:
* 7
* </code>
*/
function add($a,$b){
    return $a + $b;   
}

Si ahora ejecuta este archivo a través de phpdt (ejecutor de línea de comandos de php-doctest), se ejecutará 1 prueba. El doctest está contenido dentro del bloque . Doctest se originó en python y está bien para dar ejemplos útiles y ejecutables sobre cómo se supone que funciona el código. No puede usarlo exclusivamente porque el código en sí se llenaría de casos de prueba, pero descubrí que es útil junto con una biblioteca tdd más formal: uso phpunit.

Esta primera respuesta aquí lo resume muy bien (no es unit vs doctest).

avatar de usuario
invitado

phpunit es prácticamente el marco de prueba de unidades de facto para php. también hay prueba de documento (disponible como paquete PEAR) y algunos otros. php en sí mismo se prueba para regresiones y similares a través de pruebas phpt que también se puede ejecutar a través de pera.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad