Testing
A partir de CakePHP 1.2 disponemos de soporte para un completo entorno
de testing incorporado en CakePHP. Este entorno es una extensión del
entorno SimpleTest para PHP. En esta sección discutiremos cómo preparar
la aplicación para testing y cómo construir y ejecutar tus tests.
Preparándose para el testing
¿Preparado/a para empezar a hacer test? ¡Bien! ¡Vamos allá entonces!
Installing SimpleTest
Instalación de SimpleTest
El entorno de testing provisto con CakePHP 1.2 está construido sobre el
entorno de testing SimpleTest. SimpleTest no se distribuye con la
instalación por defecto de CakePHP por lo que debemos descargarlo
primero. Lo puedes encontrar aquí:
https://simpletest.sourceforge.net/
Consigue la última versión y descomprime el código en tu carpeta
cake/vendors, o en tu carpeta app/vendors, según tus preferencias. Ahora
deberías tener un directorio vendors/simpletest con todos los archivos y
carpetas de SimpleTest dentro. ¡Recuerda tener el nivel de DEBUG al
menos a 1 en tu archivo app/config/core.php antes de ejecutar cualquier
test!
Si no tienes una conexión de base de datos para test definida en
app/config/database.php, las tablas de test se crearán con un prefijo
test_suite_
. Puedes crear una conexión de base de adtos $test
para que contenga sólo las tablas de test como la que te mostramos
debajo:
var $test = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'dbhost',
'login' => 'dblogin',
'password' => 'dbpassword',
'database' => 'databaseName'
);
Si la base de datosd e test está disponible y CakePHP puede conectarse a
ella, todas las tablas serán creadas en esta base de datos.
Ejecutando los test-cases incorporados
CakePHP 1.2 se distribuye con un gran paquete de test-cases sobre la
funcionalidad del núcleo de CakePHP
Puedes acceder a estos test navegando a
http://your.cake.domain/cake_folder/test.php - dependiendo de como sea
la disposición específica de tu aplicación. Intenta ejecutar alguno de
los grupos de test del núcleo haciendo click en el enlace
correspondiente. Ejecutar un test puede llevar un rato, pero deberías
ver algo parecido a «2/2 test casese complete: 49 passes, 0 fails and 0
exceptions.».
¡Felicidades, ya estás listo/a para empezar a escribir tests!
Introducción a los test - Unit testing vs. Web testing
El entorno de test de CakePHP soporta dos tipos de testing. Uno es el
Unit Testing, en el cual tú pruebas pequeñas partes de tu código, como
pueden ser un método en un componente o una acción en un controlador. El
otro tipo de testing soportado es el Web Testing, en el cual automatizas
el trabajo de evaluar tu aplicación mediante la navegación por las
páginas, relleno de formularios, hacer clic en enlaces y demás.
Preparando datos de prueba
Acerca de las fixtures
Cuando pruebes código que dependa de modelos y datos, puedes usar
fixtures como una forma de generar tablas temporales de datos
cargados con datos de ejemplo que pueden ser utilizados por el test. El
beneficio de usar fixtures es que tus test no pueden de ningún modo
alterar los datos de la aplicación en marcha. Además, así puedes empezar
a probar tu código antes de desarrollar contenido en vivo para tu
aplicación.
CakePHP intenta utilizar la conexión denominada $test
en tu archivo
app/config/database.php. Si esta conexión no es utilizable, usará la
configuración de base de datos $default
y creará las tablas de test
en la base de datos definida en esa configuración. En cualquier caso,
añadirá el prefijo «test_suite_» a tu propio prefijo para las tablas
(si es que hay alguno) para evitar colisiones con las tablas existentes.
CakePHP realiza los siguientes pasos durante el curso de un test case
basado en fixture:
Crea tablas para cada una de las fixtures necesarias
Rellena las tablas con datos, si es que se han proporcionado éstos en
la fixture
Ejecuta los métodos de los test
Vacía las tablas fixture
Elimina las tablas fixture de la base de datos
Creando fixtures
Cuando se crea un fixture se deben definir 2 cosas:
cómo se crea la tabla (que campos serán parte de la tabla)
cómo se guardarán los registros en la tabla de prueba. Luego
podremos crear nuestro primer fixture, que utilizaremos para testear
nuestro modelo Article. Creamos un archivo llamado
article\_fixture.php
en la carpeta app/tests/fixtures
, con el
siguiente código:
<?php
class ArticleFixture extends CakeTestFixture {
var $name = 'Article';
var $fields = array(
'id' => array('type' => 'integer', 'key' => 'primary'),
'title' => array('type' => 'string', 'length' => 255, 'null' => false),
'body' => 'text',
'published' => array('type' => 'integer', 'default' => '0', 'null' => false),
'created' => 'datetime',
'updated' => 'datetime'
);
var $records = array(
array ('id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => '1', 'created' => '2007-03-18 10:39:23', 'updated' => '2007-03-18 10:41:31'),
array ('id' => 2, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => '1', 'created' => '2007-03-18 10:41:23', 'updated' => '2007-03-18 10:43:31'),
array ('id' => 3, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => '1', 'created' => '2007-03-18 10:43:23', 'updated' => '2007-03-18 10:45:31')
);
}
?>
Usamos $fields para indicar los campos que serán parte de la tabla, y
cómo serán definidos. El formato que se usa para definir los campos es
el mismo que usamos en la funcion generateColumnSchema() definida en
el motor de base de datos de Cake (por ejemplo en dbo_mysql.php.) Los
atributos que un campo puede tenes son los siguientes:
- type
es el tipo de dato de CakePHP. Actualmente los soportados son:
string (mapea como VARCHAR), text (mapea como TEXT), integer (mapea
como INT), float (mapea como FLOAT), datetime (mapea como DATETIME),
timestamp (mapea como TIMESTAMP), time (mapea como TIME), date
(mapea como DATE), y binary (mapea como BLOB)
- key
setea el campo como primary para hacerlo auto-incrementable
(AUTO_INCREMENT), y clave primaria (PRIMARY KEY) de la tabla.
- length
setea el tamaño del campo.
- null
setea true o false. Si puede ser nulo indicamos true, si no se
permiten nulos va false
- default
el valor por defecto del campo.
Finalmente podemos setear un conjunto de registros que seran cargados
luego de que la tabla de testeo se crea. El formato es bastante simple,
sin embargo necesita un poco más de expilcación. Solo ten en cuenta que
cada registro del array $records debe tener una key para cada campo
del array $fields. Si un campo para un registro en particular necesita
tener el valor nulo, solo especifica el valor de ese campo como nulo
(NULL true).
Creando los tests
En primer lugar, revisar una serie de normas y directrices para los
tests:
Los archivos de PHP que contiene los tests deben estar en :
app/tests/cases/[algun_ archivo].
Los nombres de estos archivos deben terminar con un .test.php en
lugar de sólo .php.
Las clases que contienen los tests debe extender o heredar de
CakeTestCase o CakeWebTestCase.
El nombre de cualquier método que contenga un test (por ejemplo, que
contiene una afirmación) debería comenzar con test, como en
testPublished().
Cuando se crea un caso test, puede ejecutarce por medio del navegador en
la siguiente dirección https://tu.dominio.cake/carpeta_cake/test.php
(dependiendo de cómo se ve específicamente tu configuración) y haciendo
clic en App casos de test, y a continuación, haga clic en el enlace a su
archivo.
CakeTestCase Callback Methods
If you want to sneak in some logic just before or after an individual
CakeTestCase method, and/or before or after your entire CakeTestCase,
the following callbacks are available:
start()
end()
startCase()
endCase()
before($method)
after($method)
startTest($method)
endTest($method)
Testing models
Creating a test case
Let’s say we already have our Article model defined on
app/models/article.php, which looks like this:
<?php
class Article extends AppModel {
var $name = 'Article';
function published($fields = null) {
$params = array(
'conditions' => array(
$this->name . '.published' => 1
),
'fields' => $fields
);
return $this->find('all',$params);
}
}
?>
We now want to set up a test that will use this model definition, but
through fixtures, to test some functionality in the model. CakePHP test
suite loads a very minimum set of files (to keep tests isolated), so we
have to start by loading our parent model (in this case the Article
model which we already defined), and then inform the test suite that we
want to test this model by specifying which DB configuration it should
use. CakePHP test suite enables a DB configuration named test_suite
that is used for all models that rely on fixtures. Setting $useDbConfig
to this configuration will let CakePHP know that this model uses the
test suite database connection.
CakePHP Models will only use the test_suite DB config if they rely on
fixtures in your testcase!
a test model that will extend from Article, set $useDbConfig and $name
appropiately. Let’s now create a file named article.test.php in your
app/tests/cases/models directory, with the following contents:
<?php
App::import('Model','Article');
class ArticleTestCase extends CakeTestCase {
var $fixtures = array( 'app.article' );
}
?>
We have created the ArticleTestCase. In variable $fixtures we define
the set of fixtures that we’ll use.
If your model is associated with other models, you will need to include
ALL the fixtures for each associated model even if you don’t use them.
For example: A hasMany B hasMany C hasMany D. In ATestCase you will have
to include fixtures for a, b, c and d.
Creating a test method
Let’s now add a method to test the function published() in the Article
model. Edit the file app/tests/cases/models/article.test.php so it
now looks like this:
<?php
App::import('Model', 'Article');
class ArticleTestCase extends CakeTestCase {
var $fixtures = array( 'app.article' );
function testPublished() {
$this->Article =& ClassRegistry::init('Article');
$result = $this->Article->published(array('id', 'title'));
$expected = array(
array('Article' => array( 'id' => 1, 'title' => 'First Article' )),
array('Article' => array( 'id' => 2, 'title' => 'Second Article' )),
array('Article' => array( 'id' => 3, 'title' => 'Third Article' ))
);
$this->assertEqual($result, $expected);
}
}
?>
by creating an instance of our fixture based Article model, and then
run our published() method. In $expected we set what we expect
should be the proper result (that we know since we have defined which
records are initally populated to the article table.) We test that the
result equals our expectation by using the assertEqual method. See
the section Creating Tests for information on how to run the test.
Testing controllers
Creando un test case
Digamos que tienes un típico controlador de artículos, con su
correspondiente modelo, y que se parece a éste:
<?php
class ArticlesController extends AppController {
var $name = 'Articles';
var $helpers = array('Ajax', 'Form', 'Html');
function index($short = null) {
if (!empty($this->data)) {
$this->Article->save($this->data);
}
if (!empty($short)) {
$result = $this->Article->findAll(null, array('id',
'title'));
} else {
$result = $this->Article->findAll();
}
if (isset($this->params['requested'])) {
return $result;
}
$this->set('title', 'Articles');
$this->set('articles', $result);
}
}
?>
Crea un archivo llamado articles_controller.test.php y pon lo siguiente
dentro:
<?php
class ArticlesControllerTest extends CakeTestCase {
function startCase() {
echo '<h1>Comenzando Test Case</h1>';
}
function endCase() {
echo '<h1>Terminado Test Case</h1>';
}
function startTest($method) {
echo '<h3>Comenzando método ' . $method . '</h3>';
}
function endTest($method) {
echo '<hr />';
}
function testIndex() {
$result = $this->testAction('/articles/index');
debug($result);
}
function testIndexShort() {
$result = $this->testAction('/articles/index/short');
debug($result);
}
function testIndexShortGetRenderedHtml() {
$result = $this->testAction('/articles/index/short',
array('return' => 'render'));
debug(htmlentities($result));
}
function testIndexShortGetViewVars() {
$result = $this->testAction('/articles/index/short',
array('return' => 'vars'));
debug($result);
}
function testIndexFixturized() {
$result = $this->testAction('/articles/index/short',
array('fixturize' => true));
debug($result);
}
function testIndexPostFixturized() {
$data = array('Article' => array('user_id' => 1, 'published'
=> 1, 'slug'=>'new-article', 'title' => 'New Article', 'body' => 'New Body'));
$result = $this->testAction('/articles/index',
array('fixturize' => true, 'data' => $data, 'method' => 'post'));
debug($result);
}
}
?>
El método testAction
La novedad aquí es el método testAction. El primer argumento de este
método es la URL «en formato Cake» de la acción del controlador que se
quiere probar, como en “/articles/index/short”.
El segundo argumento es un array de parámetros, consistente en:
- return
- Indica lo que se va a devolver.
Los valores válidos son:
“vars” - Obtienes las variables de la vista disponibles tras
ejecutar la acción
“view” - Obtienes la vista generada, sin layout
“contents” - Obtienes todo el html de la vista, incluyendo layout
“result” - Obtienes el valor de retorno de la acción como cuando
se usa $this->params[“requested”].
El valor por defecto es “result”.
- fixturize
Ponlo a true si quieres que tus modelos se «auto-simulen» (de modo
que las tablas de la aplicación se copian, junto con los registros,
para que al probar las tablas si cambias datos no afecten a tu
aplicación real.) Si en “fixturize” pones un array de modelos,
entonces sólo esos modelos se auto-simularán mientras que los demás
utilizarán las tablas reales. Si quieres usar tus archivos de
fixtures con testAction() no uses fixturize, y en su lugar usa las
fixtures como harías normalmente.
- method
Ajustalo a “post” o “get” si quieres pasarle datos al controlador
- data
Los datos que se pasarán. Será un array asociativo consistente en
pares de campo => valor. Échale un vistazo a
function testIndexPostFixturized()
en el case test de arriba
para ver cómo emulamos pasar datos de formulario como post para un
nuevo artículo.
Testing Helpers
Since a decent amount of logic resides in Helper classes, it’s important
to make sure those classes are covered by test cases.
Helper testing is a bit similar to the same approach for Components.
Suppose we have a helper called CurrencyRendererHelper located in
app/views/helpers/currency_renderer.php
with its accompanying test
case file located in
app/tests/cases/helpers/currency_renderer.test.php
Creating Helper test, part I
First of all we will define the responsibilities of our
CurrencyRendererHelper. Basically, it will have two methods just for
demonstration purpose:
function usd($amount)
This function will receive the amount to render. It will take 2 decimal
digits filling empty space with zeros and prefix “USD”.
function euro($amount)
This function will do the same as usd() but prefix the output with
“EUR”. Just to make it a bit more complex, we will also wrap the result
in span tags:
<span class="euro"></span>
Let’s create the tests first:
<?php
//Import the helper to be tested.
//If the tested helper were using some other helper, like Html,
//it should be impoorted in this line, and instantialized in startTest().
App::import('Helper', 'CurrencyRenderer');
class CurrencyRendererTest extends CakeTestCase {
private $currencyRenderer = null;
//Here we instantiate our helper, and all other helpers we need.
public function startTest() {
$this->currencyRenderer = new CurrencyRendererHelper();
}
//testing usd() function.
public function testUsd() {
$this->assertEqual('USD 5.30', $this->currencyRenderer->usd(5.30));
//We should always have 2 decimal digits.
$this->assertEqual('USD 1.00', $this->currencyRenderer->usd(1));
$this->assertEqual('USD 2.05', $this->currencyRenderer->usd(2.05));
//Testing the thousands separator
$this->assertEqual('USD 12,000.70', $this->currencyRenderer->usd(12000.70));
}
}
Here, we call usd()
with different parameters and tell the test
suite to check if the returned values are equal to what is expected.
Executing the test now will result in errors (because
currencyRendererHelper doesn’t even exist yet) showing that we have 3
fails.
Once we know what our method should do, we can write the method itself:
<?php
class CurrencyRendererHelper extends AppHelper {
public function usd($amount) {
return 'USD ' . number_format($amount, 2, '.', ',');
}
}
Here we set the decimal places to 2, decimal separator to dot, thousands
separator to comma, and prefix the formatted number with “USD” string.
Save this in app/views/helpers/currency_renderer.php and execute the
test. You should see a green bar and messaging indicating 4 passes.
Probando componentes
Supongamos que queremos hacer test a un componente llamado
TransporterComponent, el cual usa un modelo llamado Transporter para
proporcionar funcionalidad a otros controladores. Utilizaremos cuatro
archivos:
Un componente llamado Transporters que se encuentra en
app/controllers/components/transporter.php
Un modelo llamado Transporte que está en
app/models/transporter.php
Una fixture llamada TransporterTestFixture situada en
app/tests/fixtures/transporter_fixture.php
El código para el test, en app/tests/cases/transporter.test.php
Initializing the component
Ya que CakePHP desaliante importar modelos directamente en los
componentes necesitamos un controlador para
acceder a los datos en el mmodelo.
Si el método startup() del componente tiene este aspecto:
public function startup(&$controller){
$this->Transporter = $controller->Transporter;
}
entonces podemos simplemente crear una clase sencilla:
class FakeTransporterController {}
y asignarle valores dentro de ella como aquí:
$this->TransporterComponentTest = new TransporterComponent();
$controller = new FakeTransporterController();
$controller->Transporter = new TransporterTest();
$this->TransporterComponentTest->startup(&$controller);
Creando un método de prueba
Simplemente crea una clase que extienda CakeTestCase y ¡comienza a
escribir tests!
class TransporterTestCase extends CakeTestCase {
var $fixtures = array('transporter');
function testGetTransporter() {
$this->TransporterComponentTest = new TransporterComponent();
$controller = new FakeTransporterController();
$controller->Transporter = new TransporterTest();
$this->TransporterComponentTest->startup(&$controller);
$result = $this->TransporterComponentTest->getTransporter("12345", "Sweden", "54321", "Sweden");
$this->assertEqual($result, 1, "SP is best for 1xxxx-5xxxx");
$result = $this->TransporterComponentTest->getTransporter("41234", "Sweden", "44321", "Sweden");
$this->assertEqual($result, 2, "WSTS is best for 41xxx-44xxx");
$result = $this->TransporterComponentTest->getTransporter("41001", "Sweden", "41870", "Sweden");
$this->assertEqual($result, 3, "GL is best for 410xx-419xx");
$result = $this->TransporterComponentTest->getTransporter("12345", "Sweden", "54321", "Norway");
$this->assertEqual($result, 0, "Noone can service Norway");
}
}
Web testing - Testeando las vistas
La mayoria, si no es que lo son todos, los proyectos CakePHP son
aplicaciones web. Aunque el testeo unitario es una excelente manera de
testear pequeñas porciones de nuestro código, hay ocaciones en la que
querriamos hacer un testeo a gran escala. La clase CakeWebTestCase
nos brinda una muy buena manera de hacer éste tipo de testing, desde el
punto de vista del usuario.
About CakeWebTestCase
CakeWebTestCase es una extensión directa de SimpleTest WebTestCase,
sin ninguna funcionalidad extra. Toda la funcionalidad encontrada en la
documentación de SimpleTest para Testeo Web (Web
testing)
tambien están disponibles aqui. Esto quiere decir que no se pueden usar
los fixtures, y que todos los casos de testeo involucrados en un ABM
(alta, baja o modificación) a la base de datos modificarán
permanentemente los valores. Los resultados del Test son comparados
frecuentemente con los qe tiene la base de datos, por lo tanto,
asegurarse que la bd tenga los valores que se esperan, es parte del
proceso de construcción del test.
Creando un test
Manteniendo las convenciones de los otros tests, los archivos de testeo
de vistas se deberán crear en la carpeta tests/cases/views. Claro que se
podrian guardar en otra ubicación, pero siempre es bueno seguir las
convenciones. Entonces, crearemos el archivo:
tests/cases/views/complete_web.test.php
Para escribir testeos web, deberás extender la clase CakeWebTestCase
y no CakeTestCase, tal como era en los otros tests:
class CompleteWebTestCase extends CakeWebTestCase
Si necesitas hacer alguna inicialización antes de que comience el test,
crea el constructor:
function CompleteWebTestCase(){
//Do stuff here
}
Cuando escribes los test cases, lo primero que vas a necesitar hacer es
capturar algun tipo de salida o resultado donde ver y analizar. Ésto
puede ser realizado haciendo un request get o post, usando los
métodos get()o post() respectivamente. A ambos métodos se le
pasa como primer parámetro la url, aunque puede ser traida dinámicamente
si asumimos que script de testing está en
http://your.domain/cake/folder/webroot/test.php tipeando:
$this->baseurl = current(split("webroot", $_SERVER['PHP_SELF']));
Entonces podremos hacer gets y posts usando las urls de Cake, por
ejemplo:
$this->get($this->baseurl."/products/index/");
$this->post($this->baseurl."/customers/login", $data);
El segundo parámetro del método post, $data, es un array asociativo
que contiene post data en el formato de Cake:
$data = array(
"data[Customer][mail]" => "[email protected]",
"data[Customer][password]" => "userpass");
Una vez que se hizo el request a la página, se pueden utilizar todos los
mismos asserts que veniamos usando en SimpleTest.
Walking through a page
CakeWebTest also gives you an option to navigate through your page by
clicking links or images, filling forms and clicking buttons. Please
refer to the SimpleTest documentation for more information on that.
Testing plugins
Tests for plugins are created in their own directory inside the plugins
folder.
/app
/plugins
/pizza
/tests
/cases
/fixtures
/groups
They work just like normal tests but you have to remember to use the
naming conventions for plugins when importing classes. This is an
example of a testcase for the PizzaOrder model from the plugins chapter
of this manual. A difference from other tests is in the first line where
“Pizza.PizzaOrder” is imported. You also need to prefix your plugin
fixtures with “plugin.plugin_name.
“.
<?php
App::import('Model', 'Pizza.PizzaOrder');
class PizzaOrderCase extends CakeTestCase {
// Plugin fixtures located in /app/plugins/pizza/tests/fixtures/
var $fixtures = array('plugin.pizza.pizza_order');
var $PizzaOrderTest;
function testSomething() {
// ClassRegistry makes the model use the test database connection
$this->PizzaOrderTest =& ClassRegistry::init('PizzaOrder');
// do some useful test here
$this->assertTrue(is_object($this->PizzaOrderTest));
}
}
?>
If you want to use plugin fixtures in the app tests you can reference
them using “plugin.pluginName.fixtureName” syntax in the $fixtures
array.
That is all there is to it.
Miscellaneous
Customizing the test reporter
The standard test reporter is very minimalistic. If you want more
shiny output to impress someone, fear not, it is actually very easy to
extend. By creating a new reporter and making a request with a matching
output
GET parameter you can get test results with a custom
reporter.
Reporters generate the visible output from the test suite. There are two
built in reporters: Text and Html. By default all web requests use the
Html reporter. You can create your own reporters by creating files in
your app/libs. For example you could create the file
app/libs/test_suite/reporters/my_reporter.php
and in it create the
following:
require_once CAKE_TEST_LIB . 'reporter' . DS . 'cake_base_reporter.php';
class MyReporter extends CakeBaseReporter {
//methods go here.
}
Extending CakeBaseReporter
or one of its subclasses is not required,
but strongly suggested as you may get missing errors otherwise.
CakeBaseReporter
encapsulates a few common test suite features such
as test case timing and code coverage report generation. You can use
your custom reporter by setting the output
query string parameter to
the reporter name minus “reporter”. For the example above you would set
output=my
to use your custom reporter.
Test Reporter methods
Reporters have a number of methods used to generate the various parts of
a Test suite response.
- paintDocumentStart()
Paints the start of the response from the test suite. Used to paint
things like head elements in an html page.
- paintTestMenu()
Paints a menu of available test cases.
- testCaseList()
Retrieves and paints the list of tests cases.
- groupCaseList()
Retrieves and paints the list of group tests.
- paintHeader()
Prints before the test case/group test is started.
- paintPass()
Prints everytime a test case has passed. Use $this->getTestList() to
get an array of information pertaining to the test, and $message to
get the test result. Remember to call parent::paintPass($message).
- paintFail()
Prints everytime a test case has failed. Remember to call
parent::paintFail($message).
- paintSkip()
Prints everytime a test case has been skipped. Remember to call
parent::paintSkip($message).
- paintException()
Prints everytime there is an uncaught exception. Remember to call
parent::paintException($message).
Prints everytime an error is raised. Remember to call
parent::paintError($message).
- paintFooter()
Prints when the test case/group test is over, i.e. when all test
cases has been executed.
- paintDocumentEnd()
Paints the end of the response from the test suite. Used to paint
things like footer elements in an html page.
Grouping tests
If you want several of your test to run at the same time, you can try
creating a test group. Create a file in /app/tests/groups/ and name
it something like your_test_group_name.group.php. In this file,
extend TestSuite and import test as follows:
<?php
class TryGroupTest extends TestSuite {
var $label = 'try';
function tryGroupTest() {
TestManager::addTestCasesFromDirectory($this, APP_TEST_CASES . DS . 'models');
}
}
?>
The code above will group all test cases found in the
/app/tests/cases/models/ folder. To add an individual file, use
TestManager::addTestFile($this, filename).
Running tests in the Command Line
If you have simpletest installed you can run your tests from the command
line of your application.
from app/
Usage:
cake testsuite category test_type file
- category - "app", "core" or name of a plugin
- test_type - "case", "group" or "all"
- test_file - file name with folder prefix and without the (test|group).php suffix
Examples:
cake testsuite app all
cake testsuite core all
cake testsuite app case behaviors/debuggable
cake testsuite app case models/my_model
cake testsuite app case controllers/my_controller
cake testsuite core case file
cake testsuite core case router
cake testsuite core case set
cake testsuite app group mygroup
cake testsuite core group acl
cake testsuite core group socket
cake testsuite bugs case models/bug
// for the plugin 'bugs' and its test case 'models/bug'
cake testsuite bugs group bug
// for the plugin bugs and its test group 'bug'
Code Coverage Analysis:
Append 'cov' to any of the above in order to enable code coverage analysis
As the help menu suggests, you’ll be able to run all, part, or just a
single test case from your app, plugin, or core, right from the command
line.
If you have a model test of test/models/my_model.test.php you’d run
just that test case by running:
cake testsuite app models/my_model
Test Suite changes in 1.3
The TestSuite harness for 1.3 was heavily refactored and partially
rebuilt. The number of constants and global functions have been greatly
reduced. Also the number of classes used by the test suite has been
reduced and refactored. You must update app/webroot/test.php
to
continue using the test suite. We hope that this will be the last time
that a change is required to app/webroot/test.php
.
Removed Constants
CAKE_TEST_OUTPUT
RUN_TEST_LINK
BASE
CAKE_TEST_OUTPUT_TEXT
CAKE_TEST_OUTPUT_HTML
These constants have all been replaced with instance variables on the
reporters and the ability to switch reporters.
Removed functions
These methods and the logic they contained have been
refactored/rewritten into CakeTestSuiteDispatcher
and the relevant
reporter classes. This made the test suite more modular and easier to
extend.
Removed Classes
HtmlTestManager
TextTestManager
CliTestManager
These classes became obsolete as logic was consolidated into the
reporter classes.
Modified methods/classes
The following methods have been changed as noted.
TestManager::getExtension()
is no longer static.
TestManager::runAllTests()
is no longer static.
TestManager::runGroupTest()
is no longer static.
TestManager::runTestCase()
is no longer static.
TestManager::getTestCaseList()
is no longer static.
TestManager::getGroupTestList()
is no longer static.
testsuite Console changes
The output of errors, exceptions, and failures from the testsuite
console tool have been updated to remove redundant information and
increase readability of the messages. If you have other tools built upon
the testsuite console, be sure to update those tools with the new
formatting.
CodeCoverageManager changes
CodeCoverageManager::start()
”s functionality has been moved to
CodeCoverageManager::init()
CodeCoverageManager::start()
now starts coverage generation.
CodeCoverageManager::stop()
pauses collection
CodeCoverageManager::clear()
stops and clears collected coverage
reports.