Fix XML in documentation, and in the bin/scons-doc.py script that generates
[scons.git] / doc / python10 / process.xml
1 <para>
2
3   The &SCons; project has paid particular attention from day one to the
4   development process. One of the first internal documents produced was
5   a set of Developer's Guidelines to provide a loose framework for what
6   we were trying to accomplish and how we would go about accomplishing
7   it. These Guidelines cover things like:
8
9 </para>
10
11 <itemizedlist>
12
13   <listitem>
14     <para>
15
16       &SCons; will be written to Python version 1.5.2 (to ensure
17       usability by a wide install base).
18
19     </para>
20   </listitem>
21
22   <listitem>
23     <para>
24
25       How &SCons; is be tested: which infrastructure modules to use,
26       what platforms to test on, etc.
27
28     </para>
29   </listitem>
30
31   <listitem>
32     <para>
33
34       Expectations for developers (subscribe to the mailing list,
35       encouraged to register at SourceForge).
36
37     </para>
38   </listitem>
39
40   <listitem>
41     <para>
42
43       Brief outline of how to use the change management systems (Aegis and
44       CVS) for &SCons; development;.
45
46     </para>
47   </listitem>
48
49 </itemizedlist>
50
51 <para>
52
53   Establishing these guidelines up front had two purposes: 1)
54   Demonstrate the seriousness of the project to anyone wondering about
55   joining the effort; 2) Give potential developers an idea up front as
56   to whether their development style would mesh with the rest of the
57   project.
58
59 </para>
60
61 <section>
62   <title>Aegis</title>
63
64   <para>
65
66     One of the most important aspects of the &SCons; development process
67     is the use of Peter Miller's Aegis change management system. I
68     had been using Aegis for personal projects for several years, and
69     found its development methodology vastly improved the quality of my
70     programming. I was consequently committed to using it for &SCons;
71     development.
72
73   </para>
74
75   <para>
76
77     Aegis provides a number of things, including:
78
79   </para>
80
81   <itemizedlist>
82
83     <listitem>
84       <para>
85
86         A flexible source code control and branching model.
87
88       </para>
89     </listitem>
90
91     <listitem>
92       <para>
93
94         A defined process with separate development, review and
95         integration steps.
96
97       </para>
98     </listitem>
99
100     <listitem>
101       <para>
102
103         A distributed development model based on distribution of atomic
104         change sets.
105
106       </para>
107     </listitem>
108
109   </itemizedlist>
110
111   <para>
112
113     The single most important reason for using Aegis, however, is its
114     management of automated tests as part of the development process.
115
116   </para>
117
118 </section>
119
120 <section>
121   <title>Testing, Testing, Testing</title>
122
123   <para>
124
125     The &SCons; project has made extensive use of automated tests from day
126     one, taking inspiration mostly from Aegis, partly from the eXtreme
127     Programming model, and with a little home-brew scripting for glue.
128
129   </para>
130
131   <section>
132     <title>Testing Criteria</title>
133
134     <para>
135
136       The underlying criteria for testing changes to the &SCons; code
137       are taken from Aegis:
138
139     </para>
140
141     <itemizedlist>
142
143       <listitem>
144         <para>
145
146           Every change must have one or more new or modified tests
147           checked in along with the code.
148
149         </para>
150       </listitem>
151
152       <listitem>
153         <para>
154
155           The new code being checked in must pass all of the new and/or
156           modified tests.
157
158         </para>
159       </listitem>
160
161       <listitem>
162         <para>
163
164           The <emphasis>old</emphasis>, already checked-in code in must
165           <emphasis>fail</emphasis> all of the new and/or modified
166           tests.
167
168         </para>
169       </listitem>
170
171       <listitem>
172         <para>
173
174           The new code being checked in must pass all unmodified,
175           already checked-in tests.
176
177         </para>
178       </listitem>
179
180     </itemizedlist>
181
182     <para>
183
184       In practice, these restrictions can be overridden as necessary--for
185       example, when changing comments or documentation.
186
187     </para>
188
189     <para>
190
191       The criterion that surprises many people is having the old code
192       fail the tests in the change. This makes sure that the new tests
193       or modified tests really do exercise the bug fix or feature being
194       added by the change.
195
196     </para>
197
198     <para>
199
200       Together, these criteria ensure that every newly checked-in
201       version &SCons; conforms to defined behavior, as defined by
202       the tests. Whenever a bug is found, its fix is checked in with
203       a new or modified test that guarantees the bug will not recur
204       in the future. We have already built up a regression test base
205       of almost 90 tests that cover the vast majority of &SCons;'
206       functionality.
207
208     </para>
209
210   </section>
211
212   <section>
213     <title>Testing Infrastructure</title>
214
215     <para>
216
217       Testing standards are no good if they're too much of a burden for
218       developers, who will at best work around or ignore the testing
219       requirements, or at worst stop contributing code and go join a
220       project that's more fun. To this end, good testing infrastructure
221       that makes it easy to write tests is crucial.
222
223     </para>
224
225     <para>
226
227       &SCons; development uses two development methodologies, one for
228       the individual modules in the build engine, and the other for
229       end-to-end tests of the &SCons; script.
230
231     </para>
232
233     <para>
234
235       For the build engine modules, we use PyUnit. Every change to a
236       build engine module must have a change to its corresponding unit
237       tests, which live side-by-side in a separate file that imports
238       module. As we build up a large body of unit tests, this ensures
239       that the build engine will perform correctly whenever someone uses
240       it in some application other than the &SCons; script itself.
241
242     </para>
243
244     <para>
245
246       For end-to-end script tests, we have developed two modules to make
247       writing tests easy. The first, <filename>TestCmd.py</filename>,
248       is a generic module for
249       testing commands or scripts (in any language, not just Python).
250
251       The second module, <filename>TestScons.py</filename>,
252       is a subclass of the generic
253       <filename>TestCmd.py</filename> module.
254       <filename>TestScons.py</filename>
255       takes care of initialization and
256       displaying error conditions
257       specific to testing &SCons;.
258
259     </para>
260
261     <para>
262       
263       In practice, simple tests only
264       need to initialize a test object, use the object to write some
265       input files, run &SCons;, and then check whatever criteria
266       determine whether the test passed or failed. A complete test of
267       the &Program; method, for example, looks like this:
268
269     </para>
270
271     <programlisting>
272       test = TestSCons.TestSCons()
273
274       test.write('SConstruct',
275       """env = Environment()
276       env.Program(target = 'foo', source = 'foo.c')
277       """)
278
279       test.write('foo.c',
280       """
281       int
282       main(int argc, char *argv[])
283       {
284           argv[argc++] = "-"; /* dummy use of args */
285           printf("foo.c successfully compiled\\n");
286           exit (0);
287       }
288       """)
289
290       test.run(arguments = 'foo') # runs SCons
291
292       test.run(program = test.workpath('foo'))
293
294       test.fail_test(test.stdout() != "foo.c successfully compiled\n")
295
296       test.pass_test()
297     </programlisting>
298
299   </section>
300
301 </section>
302
303 <section>
304   <title>SourceForge</title>
305
306   <para>
307
308     Registration of the &SCons; project was approved at SourceForge on
309     29 June 2001.  Within a week, the initial code base was checked in,
310     mailing lists were created, and the web site was set up. We started
311     making use of the task-list manager to track what we had to finish
312     for initial release.
313
314   </para>
315
316   <para>
317
318     The obvious complication was how to use
319     structured testing methodology of Aegis when SourceForge uses
320     CVS for source control. Not using the SourceForge CVS tree would
321     have had two significant disadvantages: one, missing out on the
322     archiving and central location in the event of disaster; two, people
323     coming to the SourceForge project page wouldn't be able to browse
324     the source.  The latter was particularly important in
325     the early stages of development, in order to avoid any impression
326     that this was Yet Another Project that starts with a bang and then
327     dwindles as the initial enthusiasm starts to wear off.
328
329   </para>
330
331   <para>
332
333     The solution was to use the SourceForge CVS repository for read-only
334     access to the source. &SCons; developers are welcome to use CVS for
335     their development, but the changes are <emphasis>not</emphasis>
336     committed to the SourceForge repository. Instead, patches are sent
337     to the integrator for processing through Aegis. When the change
338     has been integrated into the Aegis repository, a home-brew
339     script translates the Aegis change into a virtual shell script
340     of commands that copy the necessary files from Aegis and check them
341     in to CVS at SourceForge.
342
343   </para>
344
345   <para>
346
347     (In practice, write access is not actually disabled for registered
348     developers, but if they do make any changes directly at SourceForge,
349     they can be overwritten at the next Aegis update.)
350
351   </para>
352
353 </section>