EcomDev_PHPUnit Tipp #4

Seit Jahren ist das Test-Framework EcomDev_PHPUnit quasi-Standard für Magento Unit Tests. Die aktuelle Version ist 0.3.7 und der letzte Stand der offiziellen Dokumentation ist Version 0.2.0 – seitdem hat sich viel getan, was man leider im Code und GitHub Issues selbst zusammensuchen muss. Diese Serie soll praktische Tipps zur Verwendung sammeln.

Tipp #4: Benannte Parameter

Der Vorteil von YAML-Dateien für die Konfiguration soll einfache Lesbarkeit sein. Wenn aber ein Data Provider so aussieht, ist es nicht weit her mit der Lesbarkeit:

-
  - 7
  - 1
  -
    5: 7
    6: 9
-
  - 7
  - 1
  -
    5: 8
    6: 10

Technisch das selbe, aber deutlich besser wartbar:

Bundle_X_A1_B2:
  product_id: 7
  qty: 1
  bundle_selections_by_option:
    5: 7
    6: 9
Bundle_X_A2_B2:
  product_id: 7
  qty: 1
  bundle_selections_by_option:
    5: 8
    6: 10

Dass es hier um das in den Warenkorb legen von Bündelprodukten geht, kann man zumindest erahnen und wenn man es weiß, sind die Testdaten einfach zu verstehen, auch ohne in den Quelltext zu sehen.

Ein weiterer positiver Effekt, ist dass PHPUnit bei fehlgeschlagenen Tests nicht mehr TestCase::test() with data set #1 ausgibt, sondern z.B. TestCase::test() with data set "Bundle_X_A1_B2"

EcomDev_PHPUnit Tipp #3

Seit Jahren ist das Test-Framework EcomDev_PHPUnit quasi-Standard für Magento Unit Tests. Die aktuelle Version ist 0.3.7 und der letzte Stand der offiziellen Dokumentation ist Version 0.2.0 – seitdem hat sich viel getan, was man leider im Code und GitHub Issues selbst zusammensuchen muss. Diese Serie soll praktische Tipps zur Verwendung sammeln.

Tipp #3: Gemeinsame Data Provider

Hast Du dich jemals gefragt, warum man für Expectations und Fixtures den Dateinamen spezifizieren kann aber für Data Providers scheinbar auf den Standard “Testname punkt yaml” festgelegt ist? Der einfache Grund ist, dass @dataProvider ein natives Feature von PHPUnit ist und sein Parameter ein Methodenname sein muss.

Also bedeutet @dataProvider dataProvider, dass die Methode EcomDev_PHPUnit_Test_Case::dataProvider() als Data Provider genutzt wird:

    /**
     * Implements default data provider functionality,
     * returns array data loaded from Yaml file with the same name as test method
     *
     * @param string $testName
     * @return array
     */
    public function dataProvider($testName)
    {
        return TestUtil::dataProvider(get_called_class(), $testName);
    }

Aber EcomDev_PHPUnit bietet auch eine Möglichkeit, den Dateinamen für Data Provider explizit anzugeben, was dann z.B. gemeinsame Data Provider ermöglicht:

/**
 * @dataProvider dataProvider
 * @dataProviderFile customFileName.yaml
 */
public function testSomething($something)

EcomDev_PHPUnit Tipp #2

Seit Jahren ist das Test-Framework EcomDev_PHPUnit quasi-Standard für Magento Unit Tests. Die aktuelle Version ist 0.3.7 und der letzte Stand der offiziellen Dokumentation ist Version 0.2.0 – seitdem hat sich viel getan, was man leider im Code und GitHub Issues selbst zusammensuchen muss. Diese Serie soll praktische Tipps zur Verwendung sammeln.

Tipp #2: Expectation Keys

Das ist ein Kurzer: expected('works %s sprintf', 'like').

Welche Expectations geladen werden sollen, hängt üblicherweise von den Testdaten ab, wenn Deine Expectation-Datei also so aussieht:

- product-1-qty-10:
  - answer: 42
- product-2-qty-10:
  - answer: 42

kannst Du sie wie folgt im Test laden:

/**
 * @test
 * @loadExpectation
 * @loadFixture
 * @dataProvider dataProvider
 */
public function testSomething($productId, $qty)
{
  $expectedAnswer = $this->expected('product-%s-qty-%s', $productId, $qty);
}

Admin Session mocken mit EcomDev_PHPUnit in Magento Enterprise

In Integrationstests mit EcomDev_PHPUnit_Test_Case_Controller gibt es eine praktische Helper-Methode adminSession(), um Requests im Magento Backend zu testen. Mit Magento Enterprise kann es da allerdings zu dieser Fehlermeldung kommen:

Exception: Warning: in_array() expects parameter 2 to be array, null given in /home/vagrant/mwdental/www/app/code/core/Enterprise/AdminGws/Model/Role.php on line 83

So gesehen in Magento EE 1.14.1.

Ohne Details zu den Enterprise-Modulen preiszugeben, hier eine Lösung in der der schuldige Observer gemockt wird:

$adminObserverMock = $this->getModelMock(
    'enterprise_admingws/observer',
    array('adminControllerPredispatch'));
$adminObserverMock->expects($this->any())
    ->method('adminControllerPredispatch')
    ->will($this->returnSelf());
$this->replaceByMock('singleton', 'enterprise_admingws/observer',
    $adminObserverMock);
$this->adminSession();