Testing

Wie testet ihr eure PHP scripte?

Ich habe vor ~10 Jahren jede Menge PHP Skripte geschrieben ohne auch nur an testing zu denken. Wenn ich diese heute lese stehen mir die Haare zu berge. Wenn ich diese nun anfasse möchte ich nicht den gleichen Fehler wieder machen. Daher frage ich mich was die best practices für testing von IPS scripten sind.

Ich kann mir momentan folgendes Vorstellen

Tests ausführen

[ul]
[li]Einzeln/Manuell: Ähnlich wie bei Python’s name == ‚self‘ könnte ich $_IPS[‚SENDER‘] auswerten und falls das script über den editor (nicht über ein event) ausgelöst wurde , meinen test code ausführen (Systemvariablen — IP-Symcon :: Automatisierungssoftware)
[/li][li]Automatisch/Extern: Meine scripts irgendwie mit PhpUnit integrieren (Getting Started with Version 7 of PHPUnit – The PHP Testing Framework)
[/li][/ul]

Mocking: Irgendwie muss ich es schaffen die IPS funktionen (GetValue, SetValue, …) dazu zu bringen zurückzugeben was ich möchte.

[ul]
[li] Wrapping: Ähnlich wie beim testen von singletons könnte ich alle zugriffe auf die IPS funktionen in eine eigne Klasse wrappen. Alle meine Skripte müssten dann diese Klasse benutzen um auf IPS funktionen zuzugreifen. Wärend des tests könnte ich die Klasse dann gegen eine andere Klasse austauschen, die das gleiche Interface bietet. Ich will aber nicht unbedingt alle meine Klassen umstellen
[/li][li] Replacement: Lange kein PHP gemacht. Kann ich eine global definierte Funktion einfach überschreiben?
[/li][li] External definition: Wenn ich meine Skripte im Kontext von PHP unit ausführe dürften die IPS funktionen so oder so nicht existieren. Damit müsste ich sie einfach definieren können und hätte somit volle kontrolle darüber was sie zurück geben.
[/li][/ul]

Soweit meine Gedanken zu dem Thema. Nun würde mich interessieren wie ihr das so macht :slight_smile:

Bei PHP Modulen kann man automatisches Testen einbauen, wie diese z.B. mit Stubs in Alexa Modul und Ähnlichen benutzt werden.

Bei Skripten selber ist das eine gute Frage.

Vielleicht kann dazu ja mal paresy oder Dr. Niels ein Tutorial schreiben ;).

Wie Fonzo schon sagte, haben wir ein kleines Testing Framework (bzw. eher passende Stubs), damit du Teile von IP-Symcon unter PHPUnit emulieren kannst. Schau dir mal unsere Repos und Tests für Alexa, Assistant und mein HomeKit Modul an. Das kannst du sicherlich auch auf „simple“ Skripte ummünzen.

paresy

Danke euch, das war in der Tat hilfreich :slight_smile:


phpab -o src/autoload.ips.php -i '*.ips.php'  /var/lib/symcon/scripts/


<?php
use PHPUnit\Framework\TestCase;

final class VariableTest extends TestCase
{
  public function setUp() {
    IPS\VariableManager::createVariable(1, 1);
    SetValueInteger(1, 1337);

    parent::setUp();
  }

  public function testVariable() {
    $this->assertEquals(GetValueInteger(1), 1337);
  }
}


./phpunit --bootstrap src/bootstrap.php tst

Das ist nur ein Test ob es wirklich geht, für den Test meiner wirklichen Klassen konnte ich schön von den DataProvider und Mocking features von PHPUnit profitieren. Gefällt mir sehr gut :slight_smile:

  • das bootstrap script:

<?php
include_once 'SymconStubs/GlobalStubs.php';
include_once 'SymconStubs/KernelStubs.php';
include_once 'SymconStubs/ModuleStubs.php';
include 'src/autoload.ips.php';

define("IPS_BOOL", 0);
define("IPS_INT", 1);
define("IPS_FLOAT", 2);
define("IPS_STRING", 3);