1Test::Database::TutoriaUls(e3r)Contributed Perl DocumentTaetsito:n:Database::Tutorial(3)
2
3
4
6 Test::Database::Tutorial - How to use Test::Database
7
9 The goal of the "Test::Database" module is to provide easy to use test
10 databases for test scripts that need them.
11
12 The problem
13 Until now, when a test script needed a database, it either used SQLite
14 (or some other easy to setup database), or required some environment
15 variables to be present, or used default credentials, or even set up
16 the database by itself.
17
18 Most of those methods have pros and cons:
19
20 · using SQLite
21
22 No setup needed, but the test script can only use SQLite's dialect
23 of SQL. So much for portability across database engines.
24
25 · using environment variables
26
27 The environment variables are different for every module to test,
28 and usually only the main developers/testers know about them. Since
29 most of the CPAN testers probably don't bother setting them up,
30 these modules are most certainly undertested.
31
32 · using default credentials
33
34 Typically using 'root' and '' to connect to the "test" MySQL
35 database, these test script assume a default installation on the
36 host system. These credentials often provide full access to the
37 database engine, which is a security risk in itself (see below).
38
39 · setting up the database by itself
40
41 This method usually uses the default credentials to access an
42 account with enough privileges to create a database. The host
43 system data may be at risk!
44
45 A solution: "Test::Database"
46 Many modules use a database to store their data, and often support
47 several database engines.
48
49 Wouldn't it be nice to be able to test on all the supported databases
50 that are available on the test system? Without breaking (into)
51 anything?
52
53 This is the goal of the "Test::Database" module. It supports:
54
55 · getting DSN information from a list of pre-configured database and
56 engines
57
58 · automatic detection of "file-based" database engines (typically,
59 SQLite).
60
61 The rest of this document describes various use cases for
62 "Test::Database".
63
65 "Test::Database" has a single interface for test authors:
66
67 my @handles = Test::Database->handles( @requests );
68
69 @request is a list of "requests" for databases handles. Requests must
70 declare the DBD they expect, and can optionaly add version-based
71 limitations (only available for drivers supported by "Test::Database").
72
73 The handles returned are objects of the "Test::Database::Handle" class.
74
75 The data contained in the database is never destroyed or cleaned up by
76 "Test::Database", so it's perfectly fine to have a startup script that
77 will setup the necessary tables and test data, several tests scripts
78 that will build and update the data, and a eventually a teardown script
79 that will drop all created tables.
80
81 "Test::Database" can return two types of databases handles:
82
83 · either a handle to a newly created database (created especially at
84 the test script's request)
85
86 · or a handle to an already existing database
87
88 There is no way for the test script to tell the difference.
89
90 In any case, the database is assumed to provide "DROP TABLE" and
91 "CREATE TABLE" rights, and the test script is by definition allowed to
92 do whatever it pleases with the tables that exist in the database.
93
94 Note that "Test::Database" supports any DSN, not just those for which
95 it has a driver. If your module supports Oracle, you can add 'Oracle'
96 to your list of requests, and if the host owner configured a "dsn"
97 pointing at an Oracle database, then it will be available for your
98 tests.
99
100 Specific database support
101 It is possible to request specific versions of a database engine.
102
103 use Test::Database;
104
105 # request database handles for all available databases
106 my @handles = Test::Database->handles();
107
108 # or for only the databases we support
109 my @handles = Test::Database->handles(
110 { dbd => 'SQLite' },
111 { dbd => 'SQLite2' },
112 { dbd => 'mysql', min_version => '4.0' },
113 );
114
115 See Test::Database documentation for details about how to write a
116 request.
117
118 Testing on a development box
119 The first systems on which you are going to test your module are the
120 ones you own. On these system, it's up to you to configure the
121 databases you want to make available.
122
123 A typical ~/.test-database configuration file would look like this:
124
125 dsn = dbi:mysql:database=test
126 username = root
127
128 dsn = dbi:Pg:database=test
129 username = postgres
130
131 dsn = dbi:Oracle:test
132
133 There is no need to add "dsn" sections for file-based drivers (at least
134 the ones that have a corresponding "Test::Database::Driver"), since the
135 module will automatically detect the available ones and create
136 databases as needed.
137
138 To find out which of the DBD that "Test::Database" supports are
139 installed, use the following one-liner:
140
141 $ perl -MTest::Database -le 'print for Test::Database->list_drivers("available")'
142 DBM
143 SQLite
144 mysql
145
146 With no parameter, it will return the list of configured ones:
147
148 $ perl -MTest::Database -le 'print for Test::Database->list_drivers()'
149 DBM
150 SQLite
151
153 The main goal of "Test::Database" from the point of view of a tester
154 is: "configure once, test everything".
155
156 As a CPAN tester, once you have installed "Test::Database", you should
157 edit the local equivalent of ~/.test-database for the user that will be
158 running the CPAN test suites.
159
160 "dsn" versus "driver_dsn"
161 "dsn" sections define the information needed to connect to a single
162 database. Any database listed here can be used by any test script that
163 requests it.
164
165 "driver_dsn" sections define the information needed to connect to a
166 database engine (a "driver") with sufficient rights to run a "CREATE
167 DATABASE" command. This allows "Test::Database" to create the databases
168 on demand, thus ensuring every test suite will get a specific database.
169
170 If you have file-based database engine, there is nothing to setup, as
171 "Test::Database" is able to detect available file-based engines and use
172 them as needed.
173
174 Other database engines like "mysql" and "Pg" require a little more
175 configuration. For example, here's the content of my ~/.test-database
176 configuration file:
177
178 driver_dsn = dbi:mysql:
179 username = root
180
181 driver_dsn = dbi:Pg:
182 username = postgres
183
184 For "Pg", I had to edit the pg_hba.cong file in /etc to make sure
185 anyone would be able to connect as the "postgres" user, for example.
186
187 Several test hosts accessing the same database engine
188 If you have a large scale testing setup, you may want to setup a single
189 MySQL or Postgres instance for all your test hosts, rather than one per
190 test host.
191
192 Databases created by "Test::Database::Driver" (using a configured
193 "driver_dsn" have a name built after the following template:
194 "tdd_driver_login_n", where driver is the DBD name, login is the login
195 of the user running "Test::Database" and n a number that
196
197 If the same database server is used by several host running
198 "Test::Database" from the same user account, there is a race condition
199 during with two different host may try to create the a database with
200 the same name. A simple trick to avoid this is to add a "key" section
201 to the ~/.test-database configuration file.
202
203 If the "key" entry exists, the template used by
204 "Test::Database::Driver" to create new databases is
205 "tdd_driver_login_key_n".
206
207 Cleaning the test drivers
208 When given a "driver_dsn", "Test::Database" will use it to create a
209 database for each test suite that requests one. Some mapping
210 information is created to ensure the same test suite always receives a
211 handle to the same database. (The mapping of test suite to database is
212 based on the current working directory when "Test::Database" is
213 loaded).
214
215 After a while, your database engine may fill up with unused test
216 databases.
217
218 All drivers store their mapping information in the system's temporary
219 directory, so the mapping information is relatively volatile, which
220 implies more unused test databases (at least for non file-based
221 drivers, since the file-based drivers store their database files in the
222 system's temporary directory too).
223
224 The following one-liner will list all the existing databases that were
225 created by "Test::Database" in your configured drivers:
226
227 perl -MTest::Database -le 'print join "\n ", $_->name, $_->databases for Test::Database->drivers'
228
229 Example output:
230
231 CSV
232 tdd_csv_book_0
233 tdd_csv_book_1
234 DBM
235 SQLite
236 tdd_sqlite_book_0
237 tdd_sqlite_book_1
238 SQLite2
239 tdd_sqlite2_book_0
240 mysql
241 tdd_mysql_book_0
242 tdd_mysql_book_1
243
244 The following one-liner will drop them all:
245
246 perl -MTest::Database -le 'for$d(Test::Database->drivers){$d->drop_database($_)for$d->databases}'
247
248 If a "key" has been defined in the configuration, only the databases
249 corresponding to that key will be dropped.
250
252 "Test::Database" currently supports the following DBD drivers: "CSV",
253 "DBM", "mysql", "Pg", "SQLite2", "SQLite".
254
255 Adding a new driver requires writing a corresponding
256 "Test::Database::Driver" subclass, having the same name as the original
257 "DBD" driver.
258
259 An example module is provided in eg/MyDriver.pm, and the other drivers
260 can also be used as an example. See also the WRITING A DRIVER FOR YOUR
261 DATABASE OF CHOICE section in the documentation for
262 "Test::Database::Driver".
263
265 The following ASCII-art graph shows where the "Test::Database::Handle"
266 objects returned by the "handles()" method come from:
267
268 ,-------------, ,-------------, ,--------------,
269 | DSN from | | File-based | | Drivers from |
270 | config file | | drivers | | config file |
271 '-------------' '-------------' '--------------'
272 | | |
273 | | ,-----------, |
274 | '--->| Available |<----'
275 | | drivers |
276 | '-----------'
277 | |
278 | ,-----------, |
279 '------------->| Available |<--'
280 | DSN |
281 '-----------'
282
283 Here are a few details about the "handles()" method works:
284
285 · "Test::Database" maintains a list of "Test::Database::Handle"
286 objects computed from the DSN listed in the configuration.
287
288 The handles matching the request are selected.
289
290 · "Test::Database" also maintains a list of "Test::Database::Driver"
291 objects computed from the list of supported file-based drivers that
292 are locally available and from the list in the configuration file.
293
294 The list of matching drivers is computed from the requests. Each
295 driver is then requested to provide an existing database (using its
296 existing mapping information) or to create one if needed, and
297 returns the corresponding "Test::Database::Handle" objects.
298
299 · Finally, all the collected "Test::Database::Handle" objects are
300 returned.
301
302 So, without any configuration, "Test::Database" will only be able to
303 provide file-based databases. It is also recommended to not put DSN or
304 driver information for the file-based database engines that have a
305 corresponding "Test::Database::Driver" class, since it will cause
306 "handles()" to return several handles for the same database engine.
307
309 Philippe Bruhat (BooK), "<book@cpan.org>"
310
312 Copyright 2009-2010 Philippe Bruhat (BooK), all rights reserved.
313
315 You can redistribute this tutorial and/or modify it under the same
316 terms as Perl itself.
317
318
319
320perl v5.12.3 2011-03-15 Test::Database::Tutorial(3)