File: subclass_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 (195 lines) | stat: -rw-r--r-- 9,621 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
<?xml version="1.0" encoding="ISO-8859-1" ?>
<page title="Sous classer un scnario de test unitaire" here="Sous classer un scnario de test unitaire">
    <long_title>Tutorial de test unitaire en PHP - Sous classer un scnario de test</long_title>
    <content>
        <p>
            <a class="target" name="temps"><h2>Une assertion insensible au chronomtre</h2></a>
        </p>
        <p>
            Nous avions laiss notre test d'horloge avec un trou. Si la fonction <code>time()</code> de PHP avanait pendant cette comparaison...
<php><![CDATA[
function testClockTellsTime() {
    $clock = new Clock();
    $this->assertEqual($clock->now(), time(), 'Now is the right time');
}
]]></php>
            ...notre test aurait un cart d'une seconde et entranerait un faux chec. Un comportement erratique de notre suite de test n'est vraiment pas ce que nous souhaitons : nous pourrions la lancer une centaine de fois par jour.
        </p>
        <p>
            Nous pourrions r-crire notre test...
<php><![CDATA[
function testClockTellsTime() {
    $clock = new Clock();<strong>
    $time1 = $clock->now();
    $time2 = time();
    $this->assertTrue(($time1 == $time2) || ($time1 + 1 == $time2), 'Now is the right time');</strong>
}
]]></php>
            Sauf que la conception n'est pas plus claire et que nous devrons le rpter pour chaque test de chronomtrage. Les rptitions sont un ennemi public n1 et donc un trs bon stimulant pour le remaniement de notre code de test.
<php><![CDATA[
class TestOfClock extends UnitTestCase {
    function TestOfClock() {
        $this->UnitTestCase('Clock class test');
    }<strong>
    function assertSameTime($time1, $time2, $message) {
        $this->assertTrue(
                ($time1 == $time2) || ($time1 + 1 == $time2),
                $message);
    }</strong>
    function testClockTellsTime() {
        $clock = new Clock();<strong>
        $this->assertSameTime($clock->now(), time(), 'Now is the right time');</strong>
    }
    function testClockAdvance() {
        $clock = new Clock();
        $clock->advance(10);<strong>
        $this->assertSameTime($clock->now(), time() + 10, 'Advancement');</strong>
    }
}
]]></php>
            Bien entendu  chaque modification je relance les tests pour bien vrifier que nous sommes dans les clous. Remaniement au vert. C'est beaucoup plus sr.
        </p>
        <p>
            <a class="target" name="sous-classe"><h2>Rutiliser notre assertion</h2></a>
        </p>
        <p>
            Peut-tre voulons nous ajouter d'autres tests sensibles au temps. Peut-tre lisons nous des timestamps - en provenance d'une entre dans une base de donnes ou d'ailleurs - qui tiendraient compte d'une simple seconde pour basculer. Pour que ces nouvelles classes de test profitent de notre nouvelle assertion nous avons besoin de la placer dans une &quot;super classe&quot;.
        </p>
        <p>
            Voici notre fichier <em>clock_test.php</em> au complet aprs la promotion de notre mthode <code>assertSameTime()</code> dans sa propre &quot;super classe&quot;...
<php><![CDATA[
<?php
    require_once('../classes/clock.php');
<strong>
    class TimeTestCase extends UnitTestCase {
        function TimeTestCase($test_name) {
            $this->UnitTestCase($test_name);
        }
        function assertSameTime($time1, $time2, $message) {
            $this->assertTrue(
                    ($time1 == $time2) || ($time1 + 1 == $time2),
                    $message);
        }
    }
    
    class TestOfClock extends TimeTestCase {
        function TestOfClock() {
            $this->TimeTestCase('Clock class test');
        }</strong>
        function testClockTellsTime() {
            $clock = new Clock();
            $this->assertSameTime($clock->now(), time(), 'Now is the right time');
        }
        function testClockAdvance() {
            $clock = new Clock();
            $clock->advance(10);
            $this->assertSameTime($clock->now(), time() + 10, 'Advancement');
        }<strong>
    }</strong>
?>
]]></php>
            Dsormais nous bnficions de notre nouvelle assertion  chaque fois que nous hritons de notre propre classe <code>TimeTestCase</code> plutt que de la classe par dfaut <code>UnitTestCase</code>. Nous retrouvons la conception de l'outil JUnit et SimpleTest est un portage en PHP de cette interface. Il s'agit d'un framework de test  partir duquel votre propre systme de test peut s'agrandir.
        </p>
        <p>
            Si nous lanons les tests maintenant une lgre broutille survient...
            <div class="demo">
                <b>Warning</b>:  Missing argument 1 for timetestcase()
                in <b>/home/marcus/projects/lastcraft/tutorial_tests/tests/clock_test.php</b> on line <b>5</b><br />
                <h1>All tests</h1>
                <div style="padding: 8px; margin-top: 1em; background-color: green; color: white;">3/3 test cases complete.
                <strong>6</strong> passes and <strong>0</strong> fails.</div>
            </div>
            La raison est assez dlicate.
        </p>
        <p>
            Notre sous-classe exige un paramtre dans le constructeur qui n'a pas t fourni et pourtant il semblerait que nous l'ayons bel et bien fourni. Quand nous avons hrit de notre nouvelle casse nous lui avons pass notre propre constructeur. C'est juste l...
<php><![CDATA[
function TestOfClock() {
    $this->TimeTestCase('Clock class test');
}
]]></php>
            En fait nous avons raison, l n'est pas le problme.
        </p>
        <p>
            Vous vous souvenez de quand nous avons construit le test de groupe <em>all_tests.php</em> en utilisant la mthode <code>addTestFile()</code>. Cette mthode recherche les classes de scnario de test, les instancie si elles sont nouvelles puis excute tous nos tests. Ce qui s'est pass ? Elle a aussi trouv notre extension de scnario de test. C'est sans consquence puisque qu'il n'y a pas de mthode de test  l'intrieur - comprendre pas de mthode commenant par &quot;test&quot;. Aucun test supplmentaire n'est excut.
        </p>
        <p>
            Le problme vient du fait qu'il instancie la classe et le fait sans le paramtre <code>$test_name</code> qui dclenche l'avertissement. Ce paramtre n'est gnralement ncessaire ni pour un scnario de test, ni pour son assertion. Pour que notre scnario de test tendu corresponde  l'interface de <code>UnitTestCase</code>, nous avons besoin de le rendre optionnel...
<php><![CDATA[
class TimeTestCase extends UnitTestCase {
    function TimeTestCase(<strong>$test_name = false</strong>) {
        $this->UnitTestCase($test_name);
    }
    function assertSameTime($time1, $time2, <strong>$message = false</strong>) {<strong>
        if (! $message) {
            $message = "Time [$time1] should match time [$time2]";
        }</strong>
        $this->assertTrue(
                ($time1 == $time2) || ($time1 + 1 == $time2),
                $message);
    }
}
]]></php>
            Bien sr, que cette classe soit instancie sans raison par la suite de test devrait continuer  vous ennuyer. Voici une modification pour l'empcher de s'excuter...
<php><![CDATA[
<strong>SimpleTestOptions::ignore('TimeTestCase');</strong>
class TimeTestCase extends UnitTestCase {
    function TimeTestCase($test_name = false) {
        $this->UnitTestCase($test_name);
    }
    function assertSameTime($time1, $time2, $message = '') {
        if (!$message) {
            $message = "Time [$time1] should match time [$time2]";
        }
        $this->assertTrue(
                ($time1 == $time2) || ($time1 + 1 == $time2),
                $message);
    }
}
]]></php>
            Cette ligne ne fait que demander  SimpleTest d'ignorer cette classe lors de la construction des suites de test. Elle peut tre ajoute n'importe o dans le fichier de scnario de test.
        </p>
        <p>
            Les six succs ont l'air bien mais ne disent pas  un observateur peu attentif ce qui a t test. Pour cela il faut regarder dans le code. Si cela vous parat trop de boulot et que vous prfreriez lire ces informations directement alors vous devriez aller lire comment <a local="display_subclass_tutorial">afficher les succs</a>.
        </p>
    </content>
    <internal>
        <link>
            Une <a href="#temps">assertion insensible au chronomtre</a> qui permet de gagner une seconde.
        </link>
        <link>
            <a href="#sous-classe">Sous classer un scnario de test</a> afin de rutiliser la mthode de test.
        </link>
    </internal>
    <external>
        <link>
            Section prcdente : <a local="gain_control_tutorial">contrler les variables de test</a>.
        </link>
        <link>
            Section suivante : <a local="display_subclass_tutorial">changer l'affichage des tests</a>.
        </link>
        <link>
            Vous aurez besoin du <a href="simple_test.php">testeur unitaire SimpleTest</a> pour les exemples.
        </link>
    </external>
    <meta>
        <keywords>
            dveloppement logiciel,
            programmation php,
            outils de dveloppement logiciel,
            tutorial php,
            scripts php gratuits,
            organisation de tests unitaires,
            cration de sous-classe,
            conseil de test,
            astuce de dveloppement,
            exemple de code php,
            objets fantaisie,
            junit,
            test php,
            outil de test unitaire,
            suite de test php
        </keywords>
    </meta>
</page>