Skip to content

Commit ea6f635

Browse files
Merge pull request #206 from pact-foundation/chore/use-testcontainers
chore: use testcontainers
2 parents 882f4a2 + 565bc80 commit ea6f635

File tree

8 files changed

+67
-72
lines changed

8 files changed

+67
-72
lines changed

Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ define E2E
3636
pip install -r requirements.txt
3737
pip install -e ../../
3838
./run_pytest.sh
39-
./verify_pact.sh
4039
endef
4140
export E2E
4241

examples/e2e/README.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,31 @@
11
# Introduction
22

3-
This is an e2e example to show the provider verification working for both cli and python api.
3+
This is an e2e example to show the provider verification working for both cli and python api.
4+
5+
Note in this example we are within conftest we are creating a Broker instance. This is purely to help demonstrate using Pact Broker in the code and you are strongly advised to set up a persistent Broker or use Pactflow
46

57
## Setup
68

79
Create your own virtualenv for this. Run
810

911
```bash
1012
pip install -r requirements.txt
11-
pip install ../../
12-
pytest
13+
pip install -e ../../
14+
./run_pytest.sh
1315
```
1416

15-
This should provide you with a relative path to pact install relatively (2 dirs up)
17+
This should provide you with a relative path to pact install relatively (2 dirs up) You can look at the Makefile in the root folder for more details.
18+
1619

17-
Create the local broker (for demo purposes only) Open a separate terminal in the examples/broker folder and run:
20+
# Running
21+
This example runs broker as part of it's tests. However, if you did wish to create the local broker open a separate terminal in the examples/broker folder and run:
1822
```bash
1923
docker-compose up
2024
```
2125

22-
If you can open a browser to http://localhost and see the broker you have succeeded.
26+
If you can open a browser to http://localhost and see the broker you have succeeded. You will have to remove the fixture in conftest.py to get this for the consumer to work, however.
2327

2428
## Consumer
25-
2629
From the root directory run:
2730

2831
```bash
@@ -40,9 +43,7 @@ To get the consumer to publish a pact to broker you will need to run (2 is an ar
4043
pytest tests/consumer/test_user_consumer.py --publish-pact 2
4144
```
4245

43-
And then you can run:
46+
This example is using the python verifier code. There is an example script of how you could run the verifier cli which would be invoked like:
4447
```bash
4548
./verify_pact.sh 2
46-
```
47-
48-
To verify the pact
49+
```

examples/e2e/requirements.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
Flask==1.1.1
22
pytest==5.4.1
3-
requests==2.23.0
3+
requests==2.23.0
4+
testcontainers==3.3.0

examples/e2e/run_pytest.sh

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,19 @@
11
#!/bin/bash
22
set -o pipefail
33

4+
FLASK_APP=pact_provider.py python -m flask run -p 5001 & &>/dev/null
45

5-
6-
FLASK_APP=pact_provider.py python -m flask run -p 1235 & &>/dev/null
7-
8-
# python pact_provider.py & &>/dev/null
96
FLASK_PID=$!
107

11-
function teardown {
12-
echo "Tearing down Flask server ${FLASK_PID}"
13-
14-
kill -9 $FLASK_PID
15-
}
8+
teardown() {
9+
echo "Tearing down Flask server ${FLASK_PID}";
10+
kill -9 $FLASK_PID;
11+
};
1612
trap teardown EXIT
1713

1814
sleep 3
1915

20-
pytest
16+
pytest --publish-pact 1
2117

22-
teardown()
18+
teardown
2319

examples/e2e/tests/conftest.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11

2+
from testcontainers.compose import DockerCompose
3+
4+
import pytest
5+
26
def pytest_addoption(parser):
37
parser.addoption(
48
"--publish-pact", type=str, action="store",
@@ -9,3 +13,27 @@ def pytest_addoption(parser):
913
"--provider-url", type=str, action="store",
1014
help="The url to our provider."
1115
)
16+
17+
# This fixture is to simulate a managed Pact Broker or Pactflow account
18+
# Do not do this yourself but setup one of the above
19+
# https://github.com/pact-foundation/pact_broker
20+
@pytest.fixture(scope='session', autouse=True)
21+
def broker(request):
22+
version = request.config.getoption('--publish-pact')
23+
publish = True if version else False
24+
25+
# yield
26+
if not publish:
27+
yield
28+
return
29+
30+
print('Starting broker')
31+
with DockerCompose("../broker",
32+
compose_file_name=["docker-compose.yml"],
33+
pull=True) as compose:
34+
35+
stdout, stderr = compose.get_logs()
36+
if stderr:
37+
print("Errors\\n:{}".format(stderr))
38+
print(stdout)
39+
yield

examples/e2e/tests/consumer/test_user_consumer.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import logging
44
import os
5-
import atexit
65

76
import pytest
87
from pact import Consumer, Like, Provider, Term, Format
@@ -31,7 +30,7 @@ def consumer():
3130
)
3231

3332

34-
@pytest.fixture(scope='session')
33+
@pytest.fixture(scope='class')
3534
def pact(request):
3635
version = request.config.getoption('--publish-pact')
3736
publish = True if version else False
@@ -43,13 +42,12 @@ def pact(request):
4342

4443
print('start service')
4544
pact.start_service()
46-
atexit.register(pact.stop_service)
4745

4846
yield pact
4947
print('stop service')
5048
pact.stop_service()
5149

52-
def test_get_user_non_admin(pact, consumer):
50+
def test_get_user_non_admin(broker, pact, consumer):
5351
expected = {
5452
'name': 'UserA',
5553
'id': Format().uuid,
@@ -72,7 +70,7 @@ def test_get_user_non_admin(pact, consumer):
7270
assert user.name == 'UserA'
7371

7472

75-
def test_get_non_existing_user(pact, consumer):
73+
def test_get_non_existing_user(broker, pact, consumer):
7674
(pact
7775
.given('UserA does not exist')
7876
.upon_receiving('a request for UserA')
@@ -82,4 +80,4 @@ def test_get_non_existing_user(pact, consumer):
8280
with pact:
8381
user = consumer.get_user('UserA')
8482
assert user is None
85-
# pact.verify()
83+
pact.verify()

examples/e2e/tests/consumer/userserviceclient-userservice.json

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6,43 +6,6 @@
66
"name": "UserService"
77
},
88
"interactions": [
9-
{
10-
"description": "a request for UserA",
11-
"providerState": "UserA exists and is not an administrator",
12-
"request": {
13-
"method": "get",
14-
"path": "/users/UserA"
15-
},
16-
"response": {
17-
"status": 200,
18-
"headers": {
19-
},
20-
"body": {
21-
"name": "UserA",
22-
"id": "fc763eba-0905-41c5-a27f-3934ab26786c",
23-
"created_on": "2016-12-15T20:16:01",
24-
"ip_address": "127.0.0.1",
25-
"admin": false
26-
},
27-
"matchingRules": {
28-
"$.body": {
29-
"match": "type"
30-
},
31-
"$.body.id": {
32-
"match": "regex",
33-
"regex": "[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}"
34-
},
35-
"$.body.created_on": {
36-
"match": "regex",
37-
"regex": "\\d+-\\d+-\\d+T\\d+:\\d+:\\d+"
38-
},
39-
"$.body.ip_address": {
40-
"match": "regex",
41-
"regex": "(\\d{1,3}\\.)+\\d{1,3}"
42-
}
43-
}
44-
}
45-
},
469
{
4710
"description": "a request for UserA",
4811
"providerState": "UserA does not exist",

examples/e2e/tests/provider/test_provider.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import os
55

66
from pact import Verifier
7+
import pytest
78

89
log = logging.getLogger(__name__)
910
logging.basicConfig(level=logging.INFO)
@@ -19,17 +20,25 @@
1920
PACT_BROKER_PASSWORD = "pactbroker"
2021

2122
PACT_MOCK_HOST = 'localhost'
22-
PACT_MOCK_PORT = 1235
23+
PACT_MOCK_PORT = 5001
2324
PACT_URL = "http://{}:{}".format(PACT_MOCK_HOST, PACT_MOCK_PORT)
2425
PACT_DIR = os.path.dirname(os.path.realpath(__file__))
2526

27+
@pytest.fixture
28+
def default_opts():
29+
return {
30+
'broker_username': PACT_BROKER_USERNAME,
31+
'broker_password': PACT_BROKER_PASSWORD,
32+
'broker_url': PACT_BROKER_URL
33+
}
2634

27-
def test_get_user_non_admin():
35+
36+
def test_get_user_non_admin(default_opts):
2837
verifier = Verifier(provider='UserService',
2938
provider_base_url=PACT_URL)
3039

31-
output, logs = verifier.verify_pacts('./userserviceclient-userservice.json',
32-
verbose=False,
33-
provider_states_setup_url="{}/_pact/provider_states".format(PACT_URL))
40+
output, logs = verifier.verify_with_broker(**default_opts,
41+
verbose=True,
42+
provider_states_setup_url="{}/_pact/provider_states".format(PACT_URL))
3443

3544
assert (output == 0)

0 commit comments

Comments
 (0)