You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tests should not affect each other. That's a rule of thumb. When tests interact with a database,
4
4
they may change the data inside it, which would eventually lead to data inconsistency.
@@ -17,16 +17,14 @@ you should use a special test database for testing. **Do not ever run tests on d
17
17
18
18
Codeception has a `Db` module, which takes on most of the tasks of database interaction.
19
19
20
-
{% highlight yaml %}
21
-
20
+
```yaml
22
21
modules:
23
22
config:
24
23
Db:
25
24
dsn: 'PDO DSN HERE'
26
25
user: 'root'
27
26
password:
28
-
29
-
{% endhighlight %}
27
+
```
30
28
31
29
<div class="alert alert-notice">
32
30
Use <a href="https://codeception.com/docs/06-ModulesAndHelpers#Dynamic-Configuration-With-Params">module parameters</a>
@@ -36,8 +34,7 @@ to set the database credentials from environment variables or from application c
36
34
Db module can cleanup database between tests by loading a database dump. This can be done by parsing SQL file and
37
35
executing its commands using current connection
38
36
39
-
{% highlight yaml %}
40
-
37
+
```yaml
41
38
modules:
42
39
config:
43
40
Db:
@@ -48,14 +45,12 @@ modules:
48
45
cleanup: true # reload dump between tests
49
46
populate: true # load dump before all tests
50
47
51
-
52
-
{% endhighlight %}
48
+
```
53
49
54
50
Alternatively an external tool (like mysql client, or pg_restore) can be used. This approach is faster and won't produce parsing errors while loading a dump.
55
51
Use `populator` config option to specify the command. For MySQL it can look like this:
Laravel5 module provides the method `have` which uses the [factory](https://laravel.com/docs/5.8/database-testing#generating-factories) method to generate models with fake data.
157
+
Laravel5 module provides the method `have` which uses the [factory](https://laravel.com/docs/9.x/database-testing#creating-models-using-factories) method to generate models with fake data.
174
158
175
159
If you want to use ORM for integration testing only, you should enable the framework module with only the `ORM` part enabled:
176
160
177
-
{% highlight yaml %}
178
-
161
+
```yaml
179
162
modules:
180
163
enabled:
181
-
- Laravel5:
164
+
- Laravel:
182
165
- part: ORM
166
+
```
183
167
184
-
{% endhighlight %}
185
-
186
-
{% highlight yaml %}
168
+
Similarly for Yii2 framework:
187
169
170
+
```yaml
188
171
modules:
189
172
enabled:
190
173
- Yii2:
191
174
- part: ORM
192
-
193
-
{% endhighlight %}
175
+
```
194
176
195
177
This way no web actions will be added to `$I` object.
196
178
@@ -199,44 +181,30 @@ Please note that inside acceptance tests, web applications work inside a webserv
199
181
by rolling back transactions. You will need to disable cleaning up,
200
182
and use the `Db` module to clean the database up between tests. Here is a sample config:
201
183
202
-
{% highlight yaml %}
203
-
184
+
```yaml
204
185
modules:
205
186
enabled:
206
187
- WebDriver:
207
188
url: http://localhost
208
189
browser: firefox
209
-
- Laravel5:
190
+
- Laravel:
210
191
cleanup: false
211
192
- Db
212
-
213
-
{% endhighlight %}
193
+
```
214
194
215
195
### Doctrine
216
196
217
197
Doctrine is also a popular ORM, unlike some others it implements the DataMapper pattern and is not bound to any framework.
218
198
The [Doctrine2](https://codeception.com/docs/modules/Doctrine2) module requires an `EntityManager` instance to work with.
219
199
It can be obtained from a Symfony framework or Zend Framework (configured with Doctrine):
220
200
221
-
{% highlight yaml %}
222
-
201
+
```yaml
223
202
modules:
224
203
enabled:
225
204
- Symfony
226
205
- Doctrine2:
227
206
depends: Symfony
228
-
229
-
{% endhighlight %}
230
-
231
-
{% highlight yaml %}
232
-
233
-
modules:
234
-
enabled:
235
-
- ZF2
236
-
- Doctrine2:
237
-
depends: ZF2
238
-
239
-
{% endhighlight %}
207
+
```
240
208
241
209
If no framework is used with Doctrine you should provide the `connection_callback` option
242
210
with a valid callback to a function which returns an `EntityManager` instance.
@@ -259,41 +227,34 @@ and are provided by the [DataFactory](https://codeception.com/docs/modules/DataF
259
227
260
228
Once configured, it can create records with ease:
261
229
262
-
{% highlight php %}
263
-
264
-
<?php
230
+
```php
265
231
// creates a new user
266
-
$user_id = $I->have('App\Model\User');
232
+
$user_id = $I->have(\App\Model\User::class);
267
233
// creates 3 posts
268
-
$I->haveMultiple('App\Model\Post', 3);
269
-
270
-
{% endhighlight %}
234
+
$I->haveMultiple(\App\Model\Post::class, 3);
235
+
```
271
236
272
237
Created records will be deleted at the end of a test.
273
238
The DataFactory module only works with ORM, so it requires one of the ORM modules to be enabled:
274
239
275
-
{% highlight yaml %}
276
-
240
+
```yaml
277
241
modules:
278
242
enabled:
279
243
- Yii2:
280
244
configFile: path/to/config.php
281
245
- DataFactory:
282
246
depends: Yii2
247
+
```
283
248
284
-
{% endhighlight %}
285
-
286
-
{% highlight yaml %}
287
-
249
+
```yaml
288
250
modules:
289
251
enabled:
290
252
- Symfony
291
253
- Doctrine2:
292
254
depends: Symfony
293
255
- DataFactory:
294
256
depends: Doctrine2
295
-
296
-
{% endhighlight %}
257
+
```
297
258
298
259
DataFactory provides a powerful solution for managing data in integration/functional/acceptance tests.
299
260
Read the [full reference](https://codeception.com/docs/modules/DataFactory) to learn how to set this module up.
@@ -309,24 +270,24 @@ This principle is so general that it can work for testing APIs, items on a web p
309
270
Let's check that list of categories on a page is the same it was before.
310
271
Create a snapshot class:
311
272
312
-
{% highlight php %}
313
-
vendor/bin/codecept g:snapshot Categories
314
-
315
-
{% endhighlight %}
273
+
```php
274
+
php vendor/bin/codecept g:snapshot Categories
275
+
```
316
276
317
277
Inject an actor class via constructor and implement `fetchData` method which should return a data set from a test.
318
278
319
-
{% highlight php %}
320
-
279
+
```php
321
280
<?php
322
-
namespace Snapshot;
281
+
282
+
namespace Tests\Support\Snapshot;
283
+
284
+
use Tests\Support\AcceptanceTester;
323
285
324
286
class Categories extends \Codeception\Snapshot
325
287
{
326
-
/** @var \AcceptanceTester */
327
-
protected $i;
288
+
protected AcceptanceTester $i;
328
289
329
-
public function __construct(\AcceptanceTester $I)
290
+
public function __construct(AcceptanceTester $I)
330
291
{
331
292
$this->i = $I;
332
293
}
@@ -337,60 +298,51 @@ class Categories extends \Codeception\Snapshot
337
298
return $this->i->grabMultiple('a.category');
338
299
}
339
300
}
340
-
341
-
{% endhighlight %}
301
+
```
342
302
343
303
Inside a test you can inject the snapshot class and call `assert` method on it:
344
304
345
-
{% highlight php %}
346
-
347
-
<?php
348
-
public function testCategoriesAreTheSame(\AcceptanceTester $I, \Snapshot\Categories $snapshot)
305
+
```php
306
+
public function testCategoriesAreTheSame(AcceptanceTester $I, \Tests\Snapshot\Categories $snapshot)
349
307
{
350
308
$I->amOnPage('/categories');
351
309
// if previously saved array of users does not match current set, test will fail
352
310
// to update data in snapshot run test with --debug flag
353
311
$snapshot->assert();
354
312
}
355
-
356
-
{% endhighlight %}
313
+
```
357
314
358
315
On the first run, data will be obtained via `fetchData` method and saved to `tests/_data` directory in json format.
359
316
On next execution the obtained data will be compared with previously saved snapshot.
360
317
361
-
> To update a snapshot with a new data run tests in `--debug` mode.
318
+
> To update a snapshot with new data, run tests in `--debug` mode.
362
319
363
320
By default Snapshot uses `assertEquals` assertion, however this can be customized by overriding `assertData` method.
364
321
365
-
### Failed assertion output
322
+
### Failed Assertion Output
366
323
367
324
The assertion performed by `assertData` will not display the typical diff output from `assertEquals` or any customized failed assertion.
368
325
To have the diff displayed when running tests, you can call the snapshot method `shouldShowDiffOnFail`:
369
326
370
-
{% highlight php %}
371
-
372
-
<?php
373
-
public function testCategoriesAreTheSame(\AcceptanceTester $I, \Snapshot\Categories $snapshot)
327
+
```php
328
+
public function testCategoriesAreTheSame(AcceptanceTester $I, \Tests\Snapshot\Categories $snapshot)
374
329
{
375
330
$I->amOnPage('/categories');
376
331
// I want to see the diff in case the snapshot data changes
377
332
$snapshot->shouldShowDiffOnFail();
378
333
$snapshot->assert();
379
334
}
380
-
381
-
{% endhighlight %}
335
+
```
382
336
383
337
If ever needed, the diff output can also be omitted by calling `shouldShowDiffOnFail(false)`.
384
338
385
-
### Working with different data formats
339
+
### Change Storage Format
386
340
387
341
By default, all snapshot files are stored in json format, so if you have to work with different formats, neither the diff output or the snapshot file data will be helpful.
388
342
To fix this, you can call the snapshot method `shouldSaveAsJson(false)` and set the file extension by calling `setSnapshotFileExtension()`:
389
343
390
-
{% highlight php %}
391
-
392
-
<?php
393
-
public function testCategoriesAreTheSame(\AcceptanceTester $I, \Snapshot\Categories $snapshot)
344
+
```php
345
+
public function testCategoriesAreTheSame(AcceptanceTester $I, \Tests\Snapshot\Categories $snapshot)
394
346
{
395
347
// I fetch an HTML page
396
348
$I->amOnPage('/categories.html');
@@ -399,16 +351,8 @@ public function testCategoriesAreTheSame(\AcceptanceTester $I, \Snapshot\Categor
399
351
$snapshot->setSnapshotFileExtension('html');
400
352
$snapshot->assert();
401
353
}
402
-
403
-
{% endhighlight %}
354
+
```
404
355
405
356
The snapshot file will be stored without encoding it to json format, and with the `.html` extension.
406
357
407
358
> Beware that this option will not perform any changes in the data returned by `fetchData`, and store it as it is.
408
-
409
-
## Conclusion
410
-
411
-
Codeception also assists the developer when dealing with data. Tools for database population
412
-
and cleaning up are bundled within the `Db` module. If you use ORM, you can use one of the provided framework modules
413
-
to operate with database through a data abstraction layer, and use the DataFactory module to generate new records with ease.
0 commit comments