File: improving_design_tutorial.xml

package info (click to toggle)
postfixadmin 2.3.5-2%2Bdeb7u1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 6,200 kB
  • sloc: php: 25,767; xml: 14,485; perl: 964; sh: 664; python: 169; makefile: 84
file content (137 lines) | stat: -rw-r--r-- 8,039 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?xml version="1.0" encoding="ISO-8859-1" ?>
<page title="Du haut vers le bas et pilot par les tests" here="Du haut vers le bas et pilot par les tests">
    <long_title>
        tutoriel de test unitaire en PHP - Conception du haut vers le bas, tester d'abord avec des objets fantaisie
    </long_title>
    <content>
        <p>
            <a class="target" name="fantaisie"><h2>Commencer par la fantaisie, passer au code ensuite</h2></a>
        </p>
        <p>
            J'ai menti.
        </p>
        <p>
            Je n'ai pas cr de test pour le scripteur, uniquement l'interface <code>FileWriter</code> que j'ai affich plus tt. En fait je vais encore m'loigner d'un article fini et prsumer l'existence un scripteur abstrait dans <em>classes/writer.php</em>...
<php><![CDATA[
<?php
    class <strong>Writer</strong> {
        
        function <strong>Writer()</strong> {
        }
        
        function write($message) {
        }
    }
?>
]]></php>
            Les changements correspondant au niveau du test sont...
<php><![CDATA[
<?php
    require_once('../classes/log.php');
    require_once('../classes/clock.php');
    require_once('../classes/writer.php');
    Mock::generate('Clock');<strong>
    Mock::generate('Writer');</strong>

    class TestOfLogging extends UnitTestCase {
        function TestOfLogging() {
            $this->UnitTestCase('Log class test');
        }
        function testWriting() {
            $clock = &new MockClock($this);
            $clock->setReturnValue('now', 'Timestamp');
            $writer = &new <strong>MockWriter($this)</strong>;
            $writer->expectOnce('write', array('[Timestamp] Test line'));
            $log = &new Log($writer);
            $log->message('Test line', &$clock);
            $writer->tally();
        }
    }
?>
]]></php>
            Afin d'utiliser la classe de log, nous aurions besoin de coder un scripteur de fichier - ou un autre type de scripteur - mais pour le moment nous ne faisons que des tests et nous n'en avons pas encore besoin. En d'autres termes, en utilisant des objets fantaisie nous pouvons dcaler la cration d'un objet de niveau plus bas jusqu'au moment opportun. Non seulement nous pouvons faire la conception du haut vers le bas, mais en plus nous pouvons aussi tester du haut vers le bas.
        </p>
        <p>
            <a class="target" name="bridge"><h2>S'approcher du bridge - pont</h2></a>
        </p>
        <p>
            Imaginez pour un moment que nous ayons commenc la classe de log  partir d'une autre direction. Simulez avoir crit juste assez du <code>Log</code> pour avoir raliser le besoin d'un <code>Writer</code>. Comme l'aurions-nous inclus ?
        </p>
        <p>
            Bon, l'hritage du scripteur ne nous aurait pas permis de le simuler du point de vue des tests. De celui de la conception nous aurions t restreint  un unique scripteur sans hritage multiple.
        </p>
        <p>
            Crer un scripteur interne, plutt qu'en le passant au constructeur, en choisissant un nom de classe, est possible, mais nous aurions moins de contrle sur l'initialisation de l'objet fantaisie. Du point de vue de la conception il aurait t presque impossible de passer des paramtres au scripteur dans tous les formats possibles et envisageables. Vous auriez d restreindre le scripteur  un hash ou  une chane complique dcrivant tous les dtails de la cible. Au mieux compliqu sans raison.
        </p>
        <p>
            Utiliser une mthode fabrique pour crer le scripteur intrieurement serait possible, mais a voudrait dire le sous classer pour les tests de manire  remplacer la mthode fabrique par une autre mthode renvoyant un leurre. Plus de boulot du point de vue des tests, quoique toujours possible. Du point de vue de la conception, a voudrait dire crer une nouvelle sous-classe de log pour chaque type de scripteur. Cela s'appelle une hirarchie de classe parallle et fait bien entendu  de la duplication. Beurk.
        </p>
        <p>
            A l'autre extrme, passer ou crer le scripteur  chaque message aurait t rptitif et aurait rduit le code de la classe <code>Log</code>  une unique mthode, un signe certain que toute la classe est devenue redondante.
        </p>
        <p>
            Cette tension entre la facilit du test et le refus de la rptition nous a permis de trouver une conception  la fois flexible et propre. Vous vous souvenez de notre bref envie de l'hritage multiple ? Nous l'avons remplac par du polymorphisme (plein de scripteurs) et spar la hirarchie du journal de celle de l'criture. Nous relions les deux par agrgation  travers le plus simple <code>Log</code>. Cette astuce est en fait un design pattern (modle de conception) appel &quot;Pont&quot; ou &quot;Bridge&quot;.
        </p>
        <p>
            Donc nous avons t pouss par le code de test (nous n'avons presque rien crit d'autre) vers un design pattern. Pensez-y une seconde. Les tests amliorent la qualit du code,  coup sr dans mon cas, mais il y a quelque chose de bien plus profond et plus puissant.
        </p>
        <p>
            Les tests ont amlior la conception.
        </p>
        <p>
            <a class="target" name="conception"><h2>Simuler la conception</h2></a>
        </p>
        <p>
            Crer un objet fantaisie est aussi simple que de crer l'interface  l'crit. Si vous utilisez de l'UML ou d'autres outils pour gnrer ces interfaces alors vous avez un chemin encore plus flexible pour gnrer rapidement vos objets de test. Mme sans, vous pouvez passer du dessin sur tableau blanc,  l'criture de l'objet fantaisie, puis  la gnration de l'interface qui nous renvoie de nouveau au tableau blanc, le tout trs simplement. Comme le remaniement, la conception, le code et les tests s'unifient.
        </p>
        <p>
            Parce que les objets fantaisie travaillent du haut vers le bas, ils peuvent tre amens dans la conception plus rapidement qu'un remaniement classique qui demande quant  lui du code fonctionnel avant de pourvoir s'installer. a veut dire que le code de test interagit plus vite avec la conception : par consquent la qualit de la conception augmente elle aussi plus vite.
        </p>
        <p>
            Un testeur unitaire est un outil de code. Un testeur unitaire avec objet fantaisie est un outil de conception.
        </p>
    </content>
    <internal>
        <link>
            <a href="#fantaisie">Simuler maintenant</a>, coder plus tard.
        </link>
        <link>
            Nous drivons vers le <a href="#bridge">design pattern bridge</a>.
        </link>
        <link>
            <a href="#conception">Conception et test</a> main dans la main.
        </link>
    </internal>
    <external>
        <link>
            Ce tutorial suit <a href="boundary_classes_tutorial.php">les classes frontire</a>.
        </link>
        <link>
            Vous aurez besoin du <a href="simple_test.php">framework de test SimpleTest</a> pour essayer ces exemples.
        </link>
        <link>
            Pour des discussions plus fournis sur les objets fantaisie, voyez le <a href="http://www.xpdeveloper.org/xpdwiki/Wiki.jsp?page=MockObjects">Wiki des Extreme Tuesday</a> ou le <a href="http://c2.com/cgi/wiki?MockObject">Wiki C2</a> (en anglais tous les deux).
        </link>
    </external>
    <meta>
        <keywords>
            dveloppement logiciel,
            tutoriel de programmation php,
            scnarios de test en php,
            outils de dveloppement logiciel,
            tutorial php,
            scripts php gratuits,
            architecture,
            exemple php,
            exemple d'objet fantaisie,
            test style junit,
            architecture logicielle pour des tests,
            framework de test en php,
            test unitaire,
            objet fantaisie en php
            test php,
            suite de test php
        </keywords>
    </meta>
</page>