Skip to content

Commit 5f972cb

Browse files
committed
initial commit
0 parents  commit 5f972cb

File tree

26 files changed

+897
-0
lines changed

26 files changed

+897
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.idea
2+
/vendor/
3+
/build/
4+
composer.lock
5+
.php_cs.cache
6+
phpunit.xml

.travis.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
language: php
2+
3+
cache:
4+
directories:
5+
- $HOME/.composer/cache
6+
7+
env:
8+
global:
9+
- PHPUNIT_FLAGS='--verbose'
10+
11+
sudo: false
12+
13+
notifications:
14+
email: false
15+
16+
php:
17+
- 7.2
18+
- 7.3
19+
- 7.4
20+
21+
matrix:
22+
fast_finish: true
23+
24+
before_install:
25+
26+
install:
27+
- composer update
28+
29+
script: vendor/bin/phpunit $PHPUNIT_FLAGS

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 hrodic/php-integration-testing
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
# PHP Integration Testing
2+
3+
Integration testing library in PHP for databases and other common infrastructure related tests.
4+
5+
It is developed as a set of extensions for PHPUnit that hooks on different events and executes your fixtures.
6+
7+
Currently you can run custom fixtures on the following PHPUnit hooks:
8+
9+
* BeforeFirstTest
10+
* BeforeTest
11+
* AfterTest
12+
* AfterLastTest
13+
14+
## Road map
15+
16+
* RabbitMQ integration
17+
18+
19+
## Requirements
20+
21+
[PHPUnit](https://phpunit.readthedocs.io/en/9.1)
22+
23+
## Installation
24+
25+
Via composer
26+
27+
```
28+
composer require --dev hrodic/php-integration-testing
29+
```
30+
31+
## Configuration
32+
33+
On PHPUnit configuration XML file you must specify the extension with its configuration.
34+
35+
If you need help with PHPUnit extensions, please refer to the [Official Documentation](https://phpunit.readthedocs.io/en/9.1/configuration.html#the-extensions-element)
36+
37+
As an example, look into phpunit-integration.xml.dist.
38+
39+
40+
### PDO Driver
41+
42+
If you need to test the integration of MySQL or MariaDB, use the PDO driver extension.
43+
44+
```
45+
<extensions>
46+
<extension class="IntegrationTesting\PHPUnit\Runner\Extension\PDODatabaseExtension">
47+
<arguments>
48+
<object class="IntegrationTesting\PHPUnit\Runner\Extension\PDODatabaseExtensionConfig">
49+
<arguments>
50+
<array>
51+
<element key="BEFORE_FIRST_TEST_PDO_FIXTURES_PATH">
52+
<string>tests/fixtures/before-first-test</string>
53+
</element>
54+
<element key="BEFORE_TEST_PDO_FIXTURES_PATH">
55+
<string>tests/fixtures/before-test</string>
56+
</element>
57+
<element key="AFTER_TEST_PDO_FIXTURES_PATH">
58+
<string>tests/fixtures/after-test</string>
59+
</element>
60+
<element key="AFTER_LAST_TEST_PDO_FIXTURES_PATH">
61+
<string>tests/fixtures/after-last-test</string>
62+
</element>
63+
</array>
64+
</arguments>
65+
</object>
66+
<object class="IntegrationTesting\Driver\PDOConnection">
67+
<arguments>
68+
<string>mysql:host=localhost:3306;dbname=test;charset=utf8</string>
69+
<string>test</string>
70+
<string>test</string>
71+
</arguments>
72+
</object>
73+
</arguments>
74+
</extension>
75+
</extensions>
76+
```
77+
78+
The extension class is
79+
```
80+
IntegrationTesting\PHPUnit\Runner\Extension\PDODatabaseExtension
81+
```
82+
83+
which requires a configuration and a PDO connection as arguments via XML config
84+
85+
The configuration class allows you to define in which paths your fixtures will be located
86+
87+
```
88+
IntegrationTesting\PHPUnit\Runner\Extension\PDODatabaseExtensionConfig
89+
```
90+
91+
The config keys to define each hook type are:
92+
93+
* BEFORE_FIRST_TEST_PDO_FIXTURES_PATH
94+
* BEFORE_TEST_PDO_FIXTURES_PATH
95+
* AFTER_TEST_PDO_FIXTURES_PATH
96+
* AFTER_LAST_TEST_PDO_FIXTURES_PATH
97+
98+
The PDOConnection class is just a wrapper of the PDO PHP class.
99+
100+
```
101+
IntegrationTesting\Driver\PDOConnection
102+
```
103+
104+
It requires DSN, username and password of your database.
105+
106+
### RabbitMQ driver
107+
108+
@todo
109+
110+
## Fixture creation
111+
112+
A PDO fixture is just an SQL file.
113+
114+
All the fixtures located in a specific hook category will be executed in order and inside a transaction.
115+
116+
How you create the SQL and the integrity of the database in each stage is up to you. The library does not force you
117+
to follow any convention although is common to setup fixtures at the beginning and clean your mess after each test.
118+
119+
You can create, insert, delete or whatever you configure your user to do. Remember, your testing database must be isolated
120+
from any real database!
121+
122+
All four fixture hook types could be placed in the directory that you prefer.
123+
124+
For BeforeTest and AfterTest hooks, which occur in every specific test, you can also provide specific fixtures to be executed
125+
just after the generic Before and After fixtures by implementing the interfaces WithBeforeTestFixtureName and/or WithAfterTestFixtureName.
126+
127+
```
128+
final class YourIntegrationTest extends TestCase implements WithBeforeTestFixtureName, WithAfterTestFixtureName
129+
{
130+
private const FIXTURE_NAME = 'pdo-integration-test';
131+
132+
public static function getAfterTestFixtureName(): string
133+
{
134+
return self::FIXTURE_NAME;
135+
}
136+
137+
public static function getBeforeTestFixtureName(): string
138+
{
139+
return self::FIXTURE_NAME;
140+
}
141+
142+
public function testYourRepositoryHere(): void
143+
{
144+
// arrange
145+
// act
146+
// assert against real database (your fixtures are already there!)
147+
}
148+
}
149+
```
150+
151+
The Extension will check if the methods are defined, and use them to locate subdirectories inside the main
152+
BEFORE_TEST_PDO_FIXTURES_PATH and AFTER_TEST_PDO_FIXTURES_PATH directories.
153+
154+
### Execution flow
155+
156+
If you take a look onto the tests/fixtures folder, you will see an example on how you can organize your fixtures.
157+
You can have multiple SQL files and the extension will read and execute them in order.
158+
159+
```
160+
├── after-last-test # AFTER_LAST_TEST_PDO_FIXTURES_PATH, executed once, at the end
161+
│   └── 01.sql
162+
├── after-test # AFTER_TEST_PDO_FIXTURES_PATH, executed after each test
163+
│   ├── 01.sql
164+
│   └── pdo-integration-test # executed after each test inside the class that defines this fixture name
165+
│   └── 01.sql
166+
├── before-first-test # BEFORE_FIRST_TEST_PDO_FIXTURES_PATH, executed once, at the beginning
167+
│   └── 01.sql
168+
└── before-test # BEFORE_TEST_PDO_FIXTURES_PATH, executed before each test
169+
├── 01.sql
170+
└── pdo-integration-test # executed before each test inside the class that defines this fixture name
171+
└── 01.sql
172+
```
173+
174+
## Troubleshooting
175+
176+
Integration testing requires some infrastructure to be in place.
177+
178+
This library assumes (you can check docker-compose.yml file for inspiration) that you have an accessible database
179+
or other infrastructure already in place and the database is created.

composer.json

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
{
2+
"name": "hrodic/php-integration-testing",
3+
"description": "Integration testing library for PHP",
4+
"keywords": [
5+
"integration",
6+
"test",
7+
"php"
8+
],
9+
"type": "library",
10+
"license": "MIT",
11+
"authors": [
12+
{
13+
"name": "Rodrigo García",
14+
"email": "[email protected]"
15+
}
16+
],
17+
"support": {
18+
"issues": "https://github.com/hrodic/php-integration-testing/issues"
19+
},
20+
"minimum-stability": "stable",
21+
"prefer-stable": true,
22+
"require": {
23+
"php": "^7.2",
24+
"ext-pdo": "*",
25+
"ext-json": "*"
26+
},
27+
"require-dev": {
28+
"ext-json": "*",
29+
"ext-mbstring": "*",
30+
"ext-pdo_mysql": "*",
31+
"ext-xml": "*",
32+
"phpunit/phpunit": "^9.0",
33+
"friendsofphp/php-cs-fixer": "^2.16",
34+
"squizlabs/php_codesniffer": "^3.5"
35+
},
36+
"suggest": {
37+
"ext-pdo_mysql": "For PDO related integration tests"
38+
},
39+
"autoload": {
40+
"psr-4": {
41+
"IntegrationTesting\\": "src/"
42+
}
43+
},
44+
"autoload-dev": {
45+
"psr-4": {
46+
"IntegrationTesting\\Tests\\Integration\\": "tests/integration",
47+
"IntegrationTesting\\": "tests/unit"
48+
}
49+
},
50+
"config": {
51+
"sort-packages": true,
52+
"optimize-autoloader": true
53+
}
54+
}

docker-compose.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
version: '3.3'
2+
3+
services:
4+
5+
cli:
6+
image: php:7.3-cli
7+
working_dir: /app
8+
entrypoint: /bin/bash -c
9+
command: tail /dev/null
10+
volumes:
11+
- .:/app
12+
stdin_open: true
13+
14+
mariadb:
15+
image: mariadb:10.4
16+
restart: always
17+
environment:
18+
MYSQL_ROOT_PASSWORD: root
19+
MYSQL_DATABASE: test
20+
MYSQL_USER: test
21+
MYSQL_PASSWORD: test
22+
tmpfs:
23+
- /var/lib/mysql
24+
ports:
25+
- 3306:3306
26+
volumes:
27+
- $PWD/docker/mariadb:/docker-entrypoint-initdb.d
28+
29+
rabbitmq:
30+
image: rabbitmq:3.8
31+
restart: always
32+
environment:
33+
- RABBITMQ_VM_MEMORY_HIGH_WATERMARK=0.5
34+
- RABBITMQ_ERLANG_COOKIE=secret
35+
- RABBITMQ_DEFAULT_USER=user
36+
- RABBITMQ_DEFAULT_PASS=password
37+
- RABBITMQ_DEFAULT_VHOST=test
38+
tmpfs:
39+
- /var/lib/rabbitmq
40+
ports:
41+
- 5672:5672
42+
- 15672:15672

docker/mariadb/01-schema.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-- this is mounted on /docker-entrypoint-initdb.d if we need to setup some SQL on MariaDB startup

examples/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Examples
2+
3+
You can check the tests/integration folder to see an example of how create an integration test.

0 commit comments

Comments
 (0)