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
Copy file name to clipboardExpand all lines: README.md
+35-18Lines changed: 35 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,47 +3,59 @@
3
3
Test-DB-Acle
4
4
============
5
5
6
-
Pronounced test debacle. I guess you can leave out the -db- part if you want a slightly shorter word and feel so inclined.
6
+
Pronounced test debacle... I guess you can leave out the -db- part if you want a slightly shorter word and feel so inclined.
7
7
8
-
What is Test-DB-Acle? A short mission statement.
8
+
What is Test-DB-Acle?
9
9
------------------------------------------------
10
10
11
11
Test-DB-Acle is a PHP library to facilitate writing easy and concise tests for the database layer.
12
12
13
-
It is my belief that writing tests should be as easy as possible for the developer, and they should also be as easy to read as possible for other developers to pick up (Ah, so easy to give advice..!)
13
+
It is my belief that writing tests should be as easy as possible for the developer, and they should also be as easy to read as possible for other developers to pick up.
14
14
15
15
This means any test data in the test should be relevant to the test scenario only. Most database tables however have non-null columns that require you to enter dummy data that is just introducing cognitive noise to the test.
16
16
17
-
Test-Db-Acle aims to take this burden away from the developer. This testing framework does not make any assumptions on how your database layer classes work, if they use an ORM like Doctrine, stored procedures or straight SQL.
18
-
19
-
The principle is always the same, at some point the code interacts with the data in the DB tables, and we do need to test this.
17
+
Test-Db-Acle aims to take this burden away from the developer. The testing framework does not make any assumptions on how your database layer classes work, if they use an ORM like Doctrine, stored procedures or straight SQL, the principle is always the same, at some point the code interacts with the data in the DB tables, and we do need to test this.
20
18
19
+
Features
20
+
-------------------
21
+
* Installation via composer
22
+
* disables foreign key checks in database
23
+
* automatically deals with non-null columns
24
+
* automatically trims date/time columns in mysql when asserting values are in db tables - useful for inserted timestamps (in Sqlite these columns have to be specified)
25
+
* pretty much all components can be exchanged and replaced by custom varieties
26
+
* supports Mysql and Sqlite at present
27
+
* Is framework agnostic, it makes no assumption if ORMs are used for example and should be easily adaptable for other unit test frameworks.
21
28
22
-
Supported Databases
23
29
-------------------
24
30
25
-
Supported databases are, at present, MySql and by extension MariaDB.
26
-
I can see Postgres, Sqllite or even Oracle support possible in the future.
31
+
Supported databases are, at present, MySql (and by extension MariaDB) and Sqlite.
32
+
33
+
The architecture should allow further databases to be added.
27
34
28
35
Supported Test Frameworks
29
36
-------------------------
30
37
31
-
This library can be used with PHPUnit as well as other frameworks such as Simpletest (The one that started me on my TDD journey).
38
+
This library can be used out-of-the-box with PHPUnit. It should be fairly easy to use it with other test frameworks by using the traits provided and having the 'assertEquals' method delegate to the equivalent method (for example, I remember it being 'assertEqual' in SimpleTest)
32
39
33
-
I have provided a simple TestDbAcle\PhpUnit\AbstractTestCase, an appropriate Simpletest one would need to be created, but should be as simple as exchanging the parent class.
40
+
I have provided a simple TestDbAcle\PhpUnit\AbstractTestCase as well as \TestDbAcle\PhpUnit\Traits\DatabaseHelperTrait if you are using PHP 5.4 and don't mind using traits.
34
41
35
42
Introduction and (very) quick example
36
43
-------------------------------------
37
44
38
45
Ok, to be really fair, testing the database layer is expensive and slooooows down tests, and wherever possible any dependencies on the database should be mocked. But sometimes we just have to do this, hopefully in a well-structured application this can be kept to a minimum.
39
46
40
-
I was frustrated with the existing tools available. Many had dependencies on particular XUnit frameworks, or I was not able to use them together with different test base classes as they were difficult to integrate, and all of them were waaaay to verbose and cumbersome to use.
47
+
There are many tools and approaches available (for example DBUnit or using factory methods in your unit tests) to help with database testing, each with their own strengths, this approach works for me because:
48
+
* I don't have to worry about null columns or foreign key constraints
49
+
* I provide a minimal data set for my tests
50
+
* I can see the test data in a grid-like format above the tests and again when asserting the data in the db.
41
51
42
52
So I set up my own solution.
43
53
44
54
###So how does it work and what does it look like? Show me an example!###
45
55
46
-
The idea is to use a "pipe-separated-values" (imaginatively called PSV by me) text string to set up test fixtures like this:
56
+
The idea is to use a "pipe-separated-values" text string, let's call it PSV - as in CSV, but with pipes - to set up test fixtures like this:
57
+
58
+
(The format of the PSV is very similar to the format used by the excellent Behat BDD framework (https://github.com/Behat/Behat))
47
59
48
60
```php
49
61
$dbTablesToSetup="
@@ -59,14 +71,18 @@ id |name
59
71
60 |Baz
60
72
61
73
";
74
+
//use this if you do not want to use the provided traits or abstract test cases
//use this if you extended your test case from \TestDbAcle\PhpUnit\AbstractTestCase or are using the \TestDbAcle\PhpUnit\Traits\DatabaseHelperTrait:
78
+
$this->setupTables($dbTablesToSetup);
64
79
65
80
```
66
81
67
-
Where the framework itself knows which columns are not NULL-able in the table and inserts default values... In fact, the table *table_name* has 30 columns all of which are non-null....
68
82
69
-
Also, there are various foreign key constraints going on in the background. Test-Db-Acle temporarily disables foreign key checks, so we do not have to worry about this, or in which order we insert the test data.
83
+
The framework itself knows which columns are not NULL-able in the table and inserts default values... In fact, let's assume that the table *table_name* has 30 columns all of which are non-null....
84
+
85
+
Also, there might be various foreign key constraints going on in the background. Test-Db-Acle temporarily disables foreign key checks, so we do not have to worry about this, or in which order we insert the test data.
70
86
71
87
###What about an actual test.....?###
72
88
@@ -124,11 +140,11 @@ class ExampleTest extends \TestDbAcle\PhpUnit\AbstractTestCase
124
140
}
125
141
}
126
142
```
127
-
Ok, obviously \Services\AddressService does not exist here (Obviously, it is test-first, right?). The example is quite simple.
143
+
Ok, obviously \Services\AddressService does not exist here (hey, it is test-first, right?) and the example is quite simple.
128
144
129
145
In real life, I would put the getPdo method into a common base test class for the project and it might be obtained quite differently than here. But, well, this *is* an example.
130
146
131
-
As you can see, setupTables can set up several tables at once and assertTableStateContains can verify the state of various tables at the same time, too.
147
+
As you can see, setupTables can set up several tables at once and assertTableStateContains can verify the state of various tables at the same time, too.
132
148
133
149
Similarly to how setupTables can setup tables that have many more columns than those specified, assertTableStateContains only compares and asserts the values of the columns specified too.
134
150
@@ -155,7 +171,7 @@ You can also use https://packagist.org/packages/test-db-acle/test-db-acle if you
155
171
156
172
Contributing
157
173
-------------------------------
158
-
Contributions are more than welcome...!
174
+
Contributions (and criticisms) are more than welcome...!
159
175
160
176
###How to run the Test-Db-Acle tests###
161
177
To run the tests, you will need to create an empty database on a MySql sever of your choice, copy tests/Functional/config.php.dist to tests/Functional/config.php and populate with your database details.
@@ -166,3 +182,4 @@ More Documentation
166
182
-[PSV Syntax](docs/PsvParser.md)
167
183
-[AbstractTestCase](docs/AbstractTestCase.md)
168
184
-[Extending and customizing TestDbAcle](docs/Customizing.md)
Copy file name to clipboardExpand all lines: docs/Customizing.md
+7-5Lines changed: 7 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,15 +5,17 @@ All aspects of TestDbAcle can be customised, it uses a very simple ServiceLocato
5
5
The TestDbAcle class is used as a simple facade that provides access to common functionality and all the components involved.
6
6
It is configured in AbstractTestCase::createDatabaseTestHelper and can be customised there.
7
7
8
-
It is possible to override AbstractTestCase::createDatabaseTestHelper and provide to the TestDbAcle::create factory methods as a second arument a service locator configuration.
9
-
(NB: This service locator is a very simplified version of one inspired by the Zend Framework 2.)
8
+
It is possible to override AbstractTestCase::createDatabaseTestHelper and to provide to the TestDbAcle::create factory method as a second arument a service locator configuration to override the defaults.
9
+
As an optional third parameter a Configuration class can be specified additionally (\FactoriesInterfaceTestDbAcle\Config\FactoriesInterface) where all the default core factories are taken from.
10
+
See \TestDbAcle\Config\DefaultFactories for an example.
10
11
11
-
The custom configuration is merged with the one provided as the second argument so it is easy to selectively override any part without affecting others.
12
+
13
+
The custom configuration (2nd argument) is merged with the default configuration so it is relatively easy to selectively exchange any part without affecting others.
12
14
13
15
The values of the configuration array can either be a string, in which case the class just gets instantiated, or a simple factory that gets the service locator
14
-
as only argument.
16
+
as the only argument.
15
17
16
-
The default configuration is as follows, this can be used as an example for the service locator usage:
Copy file name to clipboardExpand all lines: docs/PsvParser.md
+18-1Lines changed: 18 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,7 +80,7 @@ Whilst it is advisable for readability to line columns up, it is not required fo
80
80
Is equivalent to the above.
81
81
82
82
###With table names and expressions###
83
-
This is used in: *TestDbAcle\PhpUnit\AbstractTestCase::setupTables*
83
+
There is a kind of meta-language in the table names, used in: *TestDbAcle\PhpUnit\AbstractTestCase::setupTables* asnd *TestDbAcle\PhpUnit\AbstractTestCase::assertTableStateContains*
84
84
85
85
[user]
86
86
id |first_name |last_name
@@ -104,3 +104,20 @@ It is possible to instead to replace rows:
104
104
20 |stu |Smith |value 2
105
105
106
106
This will not clear the user table but replace any rows with *first_name=john* and *last_name=miller* with the respective specified row.
107
+
108
+
In Mysql, datetime columns will be automatically truncated in *assertTableStateContains*, for Sqlite, it is possible to indicate which date columns to truncate:
0 commit comments