Hlavní menu

Nástroje

SpaceTraffic / PodporaTestů

View (print) - Edit page | Recent changes - Page history

Updated 15 March 2011, 15:37 by Azaroth

SpaceTraffic.PodporaTestů History

Hide minor edits - Show changes to markup

15 March 2011, 15:37 by Azaroth -
Changed lines 22-23 from:

Testovací sady (TestSuites?) budou umístěny přímo v adresáři tests.

to:

Testovací sady (TestSuites) budou umístěny přímo v adresáři tests.

15 March 2011, 15:36 by Azaroth -
Changed lines 9-10 from:
to:

SimpleTest

15 March 2011, 15:34 by Azaroth -
Changed lines 9-10 from:
to:
14 March 2011, 17:20 by Azaroth -
Added lines 1-275:

Podpora testů

Podpora unit testingu není součástí eclipse. Proto je třeba problém řešit samostatně.

Původním záměrem bylo využití PHPUnit?, ale vzhedem ke komplikované instalaci a neexistenci webového rozhraní pro spouštění testů bylo využití tohoto frameworku odloženo.

Nalezené řešení SimpleTest pokrývá většinu potřeb spojených s testováním a i když se nachází v rané verzi, je funkční a lze očekávat jeho zlepšování v budoucnu.

SimpleTest?

Framework poskytuje základní implementaci pro spouštění testů a testových sad. Testy lze spouštět přímo na web serveru, není k tomu potřeba dodatečná konfigurace.

Možný problém může být při spouštění velkého množství testů, které by mohlo překročit limity paměti a délky spuštění php skriptu, ale tento problém není zásadní a jednotliví členové týmu si mohou sami tyto limity na svých počítačích přenastavit.

Základní informace o tom, jak používat testy lze získat v tutorialu.

Spouštění testů

Testy jsou v projektu uloženy v adresáři tests. Struktura uvnitř adresáře by měla odpovídat struktuře app adresáře, tak aby testy byly na stejném místě, jako implementace.

Testovací sady (TestSuites?) budou umístěny přímo v adresáři tests.

Pro spuštění testů je ve www adresáři skript runtests.php. Tento skript je provede nastavení a přípravu pro spuštění testů (spuštění nette a načtení tříd aplikace).

Dále je v adresáři tests skript boottests.php, který startuje nette framework pro potřeby testování (bez spuštění webové aplikace).

Zásady pro vytváření testů

  • Název každé třídy testu bude odpovídat názvu testované třídy s příponou "Test" a bude umístěn v odpovídajícím podadresáři adresáře tests.
  • Názvev testovací metody začíná slovem test, následuje název testované metody (nebo název testované funkcionality). Pokud je stejná metoda testována více metodami, je tento název doplněn o znak _ a následován názvem testu.
  • Jednotlivé testy testují pouze konkrétní situaci. Není cílem otestovat veškeré chování metody v jedné testovací metodě.
  • Každá testovací metoda obsahuje dokumentační komentář, který obsahuje:
    • Co metoda testuje
    • O co se metoda pokouší (Tries: ...)
    • Očekávané chování (Expects: ...)
    • Případné další komentáře, upřesňující fungování testu v případě, kdy je to pro pochopení potřeba.
  • Pokud je k testování třeba speciální třída, tato třída bude definována ve stejném souboru jako test a její název bude začínat názvem testovací třídy ve které je použita, následovaným znakem _ a názvem testovacího objektu(např: SomeClassTest?_TestObject).

Ukázka testu:

<?php
/**
 * Test of ObjectTools class.
 */
class ObjectToolsTest extends UnitTestCase
{
	/**
	 * Test of ObjectTools::fillObject()
	 * Tries: Fill subset of properties of test object instance.
	 * Expects: corresponding test object instance properties will be set according to array values.
	 */
	function testFillObject_FillSubset()
	{
		$values = array("a" => "test", "b" => 1000, "veryLongNameProperty" =>array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();
		ObjectTools::fillObject($testObject, $values, "a", "b");

		$this->assertEqual($testObject->getA(), "test");
		$this->assertEqual($testObject->getB(), 1000);
		$this->assertEqual($testObject->getC(), 5);
		$this->assertNull($testObject->getVeryLongNameProperty());
	}

	/**
	 * Test of ObjectTools::fillObject().
	 * Tries: Fill all properties of test object instance.
	 * Expects: All specified test object properties will be set according to array values.
	 */
	function testFillObject_FillAll()
	{
		$values = array("a" => "test", "b" => 1000, "veryLongNameProperty" =>array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();
		ObjectTools::fillObject($testObject, $values, "a", "b", "veryLongNameProperty");

		$this->assertEqual($testObject->getA(), "test");
		$this->assertEqual($testObject->getB(), 1000);
		$this->assertEqual($testObject->getC(), 5);

		$contentOfVeryLongNameProperty = $testObject->getVeryLongNameProperty();
		$this->assertIsA($contentOfVeryLongNameProperty, "array");
		$this->assertEqual($contentOfVeryLongNameProperty[0], 1);
		$this->assertEqual($contentOfVeryLongNameProperty[1], 2);
		$this->assertEqual($contentOfVeryLongNameProperty[2], 3);
	}

	/**
	 * Test of ObjectTools::fillObject()
	 * Tries: Fill all properties of test object instance in different order than order of values in dataArray.
	 * Expects: All specified test object properties will be set according to array values.
	 */
	function testFillObject_FillAllRandomOrder()
	{
		$values = array("a" => "test", "b" => 1000, "veryLongNameProperty" =>array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();
		ObjectTools::fillObject($testObject, $values, "b", "veryLongNameProperty", "a");

		$this->assertEqual($testObject->getA(), "test");
		$this->assertEqual($testObject->getB(), 1000);
		$this->assertEqual($testObject->getC(), 5);

		$contentOfVeryLongNameProperty = $testObject->getVeryLongNameProperty();
		$this->assertIsA($contentOfVeryLongNameProperty, "array");
		$this->assertEqual($contentOfVeryLongNameProperty[0], 1);
		$this->assertEqual($contentOfVeryLongNameProperty[1], 2);
		$this->assertEqual($contentOfVeryLongNameProperty[2], 3);
	}

	/**
	 * Test of ObjectTools::fillObject().
	 * Tries: Call function with invalid property name.
	 * Expects: error that property name is not valid.
	 */
	function testFillObject_InvalidProperty()
	{
		$values = array("a" => "test", "b" => 1000, "veryLongNameProperty" =>array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();

		$this->expectError();

		ObjectTools::fillObject($testObject, $values, "a", "b", "invalid");
	}

	/**
	 * Test of ObjectTools::fillObject().
	 * Tries: Call function with valid property names, but more than there are values in data array.
	 * Expects: error that there are no value in array.
	 */
	function testFillObject_TooManyProperties()
	{
		$values = array("a" => "test", "veryLongNameProperty" =>array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();

		$this->expectError();

		ObjectTools::fillObject($testObject, $values, "a", "b", "veryLongNameProperty");
	}

	/**
	 * Test of ObjectTools::fillObject().
	 * Tries: Call function with empty property list.
	 * Expects: No change in test object.
	 */
	function testFillObject_NoPropertySpecified()
	{
		$values = array("a" => "test", "b" => 1000, "veryLongNameProperty" =>array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();

		ObjectTools::fillObject($testObject, $values, array());

		$this->assertEqual($testObject->getA(), 5);
		$this->assertEqual($testObject->getB(), 5);
		$this->assertEqual($testObject->getC(), 5);
		$this->assertNull($testObject->getVeryLongNameProperty());
	}

	/**
	 * Test of ObjectTools::fillObject().
	 * Tries: Call function with value array as not associative array.
	 * Expects: Filling of object with values in specified order.
	 */
	function testFillObject_ValueArrayNotAnAssociativeArray()
	{
		$values = array("test", 1000, array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();

		ObjectTools::fillObject($testObject, $values, "a","b", "veryLongNameProperty");

		$this->assertEqual($testObject->getA(), "test");
		$this->assertEqual($testObject->getB(), 1000);
		$this->assertEqual($testObject->getC(), 5);

		$contentOfVeryLongNameProperty = $testObject->getVeryLongNameProperty();
		$this->assertIsA($contentOfVeryLongNameProperty, "array");
		$this->assertEqual($contentOfVeryLongNameProperty[0], 1);
		$this->assertEqual($contentOfVeryLongNameProperty[1], 2);
		$this->assertEqual($contentOfVeryLongNameProperty[2], 3);
	}

	/**
	 * Test of ObjectTools::fillObject().
	 * Tries: Call function with empty value array and no property specified.
	 * Expects: No change in test object.
	 */
	function testFillObject_ValueArrayEmpty()
	{
		$testObject = new ObjectToolsTest_TestObject();

		ObjectTools::fillObject($testObject, array(), array());

		$this->assertEqual($testObject->getA(), 5);
		$this->assertEqual($testObject->getB(), 5);
		$this->assertEqual($testObject->getC(), 5);
		$this->assertNull($testObject->getVeryLongNameProperty());
	}

	/**
	 * Test of ObjectTools::fillObject().
	 * Tries: Call function with no value for property.
	 * Expects: Error that value not found in array.
	 */
	function testFillObject_ValueNotInArray()
	{
		$values = array("a" => "test", "veryLongNameProperty" =>array(1,2,3));

		$testObject = new ObjectToolsTest_TestObject();

		$this->expectError();

		ObjectTools::fillObject($testObject, $values, "a","b");
		$this->assertEqual($testObject->getB(), 5);
	}
}

/**
 * Used as testing object for ObjectToolsTest.
 * It contains properties with getters and setters.
 * @author Azaroth
 */
class ObjectToolsTest_TestObject
{
	private $a = 5;
	private $b = 5;
	private $c = 5;
	private $veryLongNameProperty = null;

	public function getA()
	{
		return $this->a;
	}
	public function setA($value)
	{
		$this->a = $value;
	}

	public function getB()
	{
		return $this->b;
	}
	public function setB($value)
	{
		$this->b = $value;
	}

	public function getC()
	{
		return $this->c;
	}
	public function setC($value)
	{
		$this->c = $value;
	}

	public function getVeryLongNameProperty()
	{
		return $this->veryLongNameProperty;
	}
	public function setVeryLongNameProperty(array $value)
	{
		$this->veryLongNameProperty = $value;
	}
}