Question

Je suis surtout convaincu des avantages des tests unitaires, et je voudrais commencer à appliquer le concept à un grand code existant écrit en PHP. Moins de 10% de ce code est orienté objet.

J'ai regardé plusieurs cadres de tests unitaires (PHPUnit, SimpleTest et HPTP). Cependant, je ne l'ai pas trouvé des exemples pour ces qui testent le code de procédure. Quel est le meilleur cadre pour ma situation et quels sont les exemples de PHP tests unitaires en utilisant le code non POO?

Était-ce utile?

La solution

Vous pouvez test unitaire PHP procédure, aucun problème. Et vous n'êtes certainement pas de chance si votre code est mélangé avec HTML.

Au niveau de test d'application ou d'acceptation, votre PHP procédure dépend probablement de la valeur des superglobales ($_POST, $_GET, $_COOKIE, etc.) pour déterminer le comportement, et se termine en incluant un fichier de modèle et crachant la sortie.

Pour faire des tests de niveau d'application, il vous suffit de définir les valeurs superglobales; lancer un tampon de sortie (pour garder un tas de HTML d'inonder votre écran); appeler la page; affirmer contre substance à l'intérieur du tampon; et le tampon de la corbeille à la fin.   Donc, vous pourriez faire quelque chose comme ceci:

public function setUp()
{
    if (isset($_POST['foo'])) {
        unset($_POST['foo']);
    }
}

public function testSomeKindOfAcceptanceTest()
{
    $_POST['foo'] = 'bar';
    ob_start();
    include('fileToTest.php');
    $output = ob_get_flush();
    $this->assertContains($someExpectedString, $output);
}

Même pour « cadres » énormes avec beaucoup de comprend, ce genre de test vous dira si vous avez des caractéristiques au niveau des applications de travail ou non. Cela va être vraiment important que vous commencez à améliorer votre code, parce que même si vous êtes convaincu que le connecteur de base de données fonctionne toujours et semble mieux qu'avant, vous aurez envie de cliquer sur un bouton et voir que, oui, vous pouvez toujours login et logout dans la base de données.

Aux niveaux inférieurs, il existe des variations mineures selon la portée variable et si les fonctions fonctionnent par des effets secondaires (retour vrai ou faux), ou retourner directement le résultat.

sont des variables passées autour explicitement, en tant que paramètres ou des tableaux de paramètres entre les fonctions? Ou sont variables définies dans de nombreux endroits différents et passés implicitement globals? Si c'est le (bon) cas explicite, vous unité peut tester une fonction par (1) y compris le fichier contenant la fonction, (2) l'alimentation des valeurs de test de fonction directement, et (3) capturant la sortie et faire valoir contre elle. Si vous utilisez globals, il vous suffit d'être très prudent (comme ci-dessus, dans l'exemple $ _POST) à soigneusement null toutes les GLOBALS entre les tests. Il est également particulièrement utile pour garder les tests très petits (5-10 lignes, 1-2 affirme) lorsqu'il s'agit d'une fonction qui pousse et tire beaucoup de GLOBALS.

Une autre question fondamentale est de savoir si les fonctions fonctionnent en retournant la sortie, ou en modifiant les paramètres passés en, retournant true / false au lieu. Dans le premier cas, le test est plus facile, mais encore une fois, il est possible dans les deux cas:

// assuming you required the file of interest at the top of the test file
public function testShouldConcatenateTwoStringsAndReturnResult()
{
  $stringOne = 'foo';
  $stringTwo = 'bar';
  $expectedOutput = 'foobar';
  $output = myCustomCatFunction($stringOne, $stringTwo);
  $this->assertEquals($expectedOutput, $output);
}

Dans le mauvais cas où votre code fonctionne par des effets secondaires et retourne vrai ou faux, vous pouvez toujours tester assez facilement:

/* suppose your cat function stupidly 
 * overwrites the first parameter
 * with the result of concatenation, 
 * as an admittedly contrived example 
 */
public function testShouldConcatenateTwoStringsAndReturnTrue()
    {
      $stringOne = 'foo';
      $stringTwo = 'bar';
      $expectedOutput = 'foobar';
      $output = myCustomCatFunction($stringOne, $stringTwo);
      $this->assertTrue($output);
      $this->Equals($expectedOutput, $stringOne);
    }

Hope this helps.

Autres conseils

Quels sont les tests unitaires bien faire, et ce que vous devez les utiliser pour, est quand vous avez un morceau de code que vous donnez un certain nombre d'entrées, et vous vous attendez à obtenir un certain nombre de sorties arrière. L'idée étant, lorsque vous ajoutez des fonctionnalités plus tard, vous pouvez exécuter vos tests et assurez-vous qu'il est encore d'effectuer l'ancienne fonctionnalité de la même manière.

Donc, si vous avez un code base de la procédure, vous pouvez accomplir cela appeler vos fonctions dans les méthodes d'essai

require 'my-libraries.php';
class SomeTest extends SomeBaseTestFromSomeFramework {
    public function testSetup() {
        $this->assertTrue(true);
    }

    public function testMyFunction() {
        $output = my_function('foo',3);

        $this->assertEquals('expected output',$output);
    }
}

Cette astuce avec des bases de code PHP est souvent le code de votre bibliothèque va interférer avec le fonctionnement de votre cadre de test, comme base de code et les cadres de test aura beaucoup de code lié à la mise en place d'un environnement d'application dans un navigateur Web ( session, les variables globales partagées, etc.). Attendez-vous à passer quelque temps arriver à un point où vous pouvez inclure votre code de bibliothèque et exécuter un test simple de la saleté (la fonction testSetup ci-dessus).

Si votre code ne fonctionne pas, et est juste une série de fichiers PHP que les pages HTML de sortie, vous êtes un peu de chance. Votre code ne peut être séparé en unités distinctes, ce qui signifie des tests unitaires ne va pas être d'une grande utilité pour vous. Vous seriez mieux passer votre temps au niveau « tests d'acceptation » avec des produits comme Sélénium et Watir . Ceux-ci vous permettra automatisée d'un navigateur, puis vérifier les pages de contenu des emplacements comme spécifiques / sous formes.

Vous pouvez essayer d'inclure votre code non-oop dans une classe de test en utilisant

require_once 'your_non_oop_file.php' # Contains fct_to_test()

Et avec PHPUnit vous définissez votre fonction de test:

testfct_to_test() {
   assertEquals( result_expected, fct_to_test(), 'Fail with fct_to_test' );
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top