specmatic 0.4.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of specmatic might be problematic. Click here for more details.
- {specmatic-0.4.0/specmatic.egg-info → specmatic-0.5.0}/PKG-INFO +25 -16
- {specmatic-0.4.0 → specmatic-0.5.0}/README.md +24 -15
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/core/decorators.py +18 -8
- specmatic-0.5.0/specmatic/core/specmatic.py +27 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/core/specmatic_stub.py +19 -7
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/server/wsgi_server.py +10 -2
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/version.py +1 -1
- {specmatic-0.4.0 → specmatic-0.5.0/specmatic.egg-info}/PKG-INFO +25 -16
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic.egg-info/SOURCES.txt +1 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/test/api/__init__.py +2 -2
- {specmatic-0.4.0 → specmatic-0.5.0}/test/db/Orders.py +3 -3
- {specmatic-0.4.0 → specmatic-0.5.0}/test/db/Products.py +3 -2
- {specmatic-0.4.0 → specmatic-0.5.0}/test/test_contract.py +3 -2
- {specmatic-0.4.0 → specmatic-0.5.0}/test/test_contract_using_api.py +6 -6
- specmatic-0.5.0/test/test_contract_using_api_implicit.py +32 -0
- specmatic-0.4.0/specmatic/core/specmatic.py +0 -25
- {specmatic-0.4.0 → specmatic-0.5.0}/MANIFEST.in +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/setup.cfg +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/setup.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/__init__.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/core/__init__.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/core/specmatic.jar +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/core/specmatic_test.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/generators/__init__.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/generators/pytest_generator.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/generators/test_generator_base.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/generators/unittest_generator.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/server/__init__.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/server/wsgi_server_thread.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic/utils.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic.egg-info/dependency_links.txt +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic.egg-info/requires.txt +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/specmatic.egg-info/top_level.txt +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/test/__init__.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/test/api/models.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/test/api/routes.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/test/db/__init__.py +0 -0
- {specmatic-0.4.0 → specmatic-0.5.0}/test/test_contract_with_local_specs.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: specmatic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: A Python module for using the Specmatic Library.
|
|
5
5
|
Home-page: https://github.com/znsio/specmatic-python-extensions
|
|
6
6
|
Author: Specmatic Builders
|
|
@@ -35,10 +35,10 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
35
35
|
[Click here](https://specmatic.in/documentation/contract_tests.html) to learn more about Specmatic test mode.
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
- If you want to stub out a service dependency, add the **specmatic_stub** decorator
|
|
38
|
+
- If you want to stub out a service dependency, add the **specmatic_stub** decorator below the **start_app** decorator.
|
|
39
39
|
``````
|
|
40
40
|
@specmatic_contract_test(PROJECT_ROOT, host, port)
|
|
41
|
-
@
|
|
41
|
+
@start_app(app, host, port)
|
|
42
42
|
@specmatic_stub(PROJECT_ROOT, stub_host, stub_port, [expectation_json_file])
|
|
43
43
|
class TestApiContract:
|
|
44
44
|
pass
|
|
@@ -58,15 +58,15 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
58
58
|
pass
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
stub = Specmatic.
|
|
62
|
-
stub.start()
|
|
61
|
+
stub = Specmatic.start_stub(PROJECT_ROOT, stub_host, stub_port)
|
|
63
62
|
stub.set_expectations([expectation_json_file])
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Specmatic.run_tests(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
64
|
+
app_server = WSGIServer(app, app_host, app_port)
|
|
65
|
+
app_server.start()
|
|
68
66
|
|
|
69
|
-
|
|
67
|
+
Specmatic.test(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
68
|
+
|
|
69
|
+
app_server.stop()
|
|
70
70
|
stub.stop()
|
|
71
71
|
|
|
72
72
|
if __name__ == '__main__':
|
|
@@ -75,14 +75,23 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
75
75
|
|
|
76
76
|
The above code can be broken down into three parts
|
|
77
77
|
- **Stub setup:**
|
|
78
|
-
Use the ``````Specmatic.
|
|
79
|
-
You can
|
|
78
|
+
Use the ``````Specmatic.start_stub()`````` method to create an start a stub instance.
|
|
79
|
+
You can explicitly supply the host/port to run.
|
|
80
|
+
If no host/port is supplied, the stub will be started on http://127.0.0.1:9000
|
|
81
|
+
You can set expectations on the stub by calling the ``````set_expectations()`````` method and passing a list of expectation json files.
|
|
82
|
+
The stub has attributes: ``````stub.host`````` and ``````stub.port`````` to tell us where it's running on.
|
|
83
|
+
|
|
80
84
|
- **App Setup:**
|
|
81
|
-
Create an instance of the ``````WSGIServer`````` class by passing it an instance of a WSGIApplication like a flask app and the host and port to run on.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
Create an instance of the ``````WSGIServer`````` class by passing it an instance of a WSGIApplication like a flask app and the host and port to run on.
|
|
86
|
+
If no host/port is supplied, then the app server will be started on a random freely available port.
|
|
87
|
+
The app_server also has attributes: ``````app_server.host`````` and ``````app_server.port`````` to tell us where it's running on.
|
|
88
|
+
|
|
89
|
+
- **Run Tests:**
|
|
90
|
+
Call ``````Specmatic.test()`````` by passing it your root directory, an empty Test class and the host/port on which your app server is running.
|
|
91
|
+
- Here are some examples to demonstrate how the library can be used in different ways for WSGI apps:
|
|
92
|
+
``````test\test_contract.py`````` : Running specmatic test, stub and a flask app using decorators.
|
|
93
|
+
``````test\test_contract_using_api.py`````` : Running specmatic test, stub and a flask app using the api by explicitly defining all the hosts and ports.
|
|
94
|
+
``````test\test_contract_using_api_implicit.py`````` : Running specmatic test, stub and a flask app using the api without setting explicit ports anywhere .
|
|
86
95
|
|
|
87
96
|
|
|
88
97
|
|
|
@@ -26,10 +26,10 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
26
26
|
[Click here](https://specmatic.in/documentation/contract_tests.html) to learn more about Specmatic test mode.
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
- If you want to stub out a service dependency, add the **specmatic_stub** decorator
|
|
29
|
+
- If you want to stub out a service dependency, add the **specmatic_stub** decorator below the **start_app** decorator.
|
|
30
30
|
``````
|
|
31
31
|
@specmatic_contract_test(PROJECT_ROOT, host, port)
|
|
32
|
-
@
|
|
32
|
+
@start_app(app, host, port)
|
|
33
33
|
@specmatic_stub(PROJECT_ROOT, stub_host, stub_port, [expectation_json_file])
|
|
34
34
|
class TestApiContract:
|
|
35
35
|
pass
|
|
@@ -49,15 +49,15 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
49
49
|
pass
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
stub = Specmatic.
|
|
53
|
-
stub.start()
|
|
52
|
+
stub = Specmatic.start_stub(PROJECT_ROOT, stub_host, stub_port)
|
|
54
53
|
stub.set_expectations([expectation_json_file])
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Specmatic.run_tests(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
55
|
+
app_server = WSGIServer(app, app_host, app_port)
|
|
56
|
+
app_server.start()
|
|
59
57
|
|
|
60
|
-
|
|
58
|
+
Specmatic.test(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
59
|
+
|
|
60
|
+
app_server.stop()
|
|
61
61
|
stub.stop()
|
|
62
62
|
|
|
63
63
|
if __name__ == '__main__':
|
|
@@ -66,14 +66,23 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
66
66
|
|
|
67
67
|
The above code can be broken down into three parts
|
|
68
68
|
- **Stub setup:**
|
|
69
|
-
Use the ``````Specmatic.
|
|
70
|
-
You can
|
|
69
|
+
Use the ``````Specmatic.start_stub()`````` method to create an start a stub instance.
|
|
70
|
+
You can explicitly supply the host/port to run.
|
|
71
|
+
If no host/port is supplied, the stub will be started on http://127.0.0.1:9000
|
|
72
|
+
You can set expectations on the stub by calling the ``````set_expectations()`````` method and passing a list of expectation json files.
|
|
73
|
+
The stub has attributes: ``````stub.host`````` and ``````stub.port`````` to tell us where it's running on.
|
|
74
|
+
|
|
71
75
|
- **App Setup:**
|
|
72
|
-
Create an instance of the ``````WSGIServer`````` class by passing it an instance of a WSGIApplication like a flask app and the host and port to run on.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
Create an instance of the ``````WSGIServer`````` class by passing it an instance of a WSGIApplication like a flask app and the host and port to run on.
|
|
77
|
+
If no host/port is supplied, then the app server will be started on a random freely available port.
|
|
78
|
+
The app_server also has attributes: ``````app_server.host`````` and ``````app_server.port`````` to tell us where it's running on.
|
|
79
|
+
|
|
80
|
+
- **Run Tests:**
|
|
81
|
+
Call ``````Specmatic.test()`````` by passing it your root directory, an empty Test class and the host/port on which your app server is running.
|
|
82
|
+
- Here are some examples to demonstrate how the library can be used in different ways for WSGI apps:
|
|
83
|
+
``````test\test_contract.py`````` : Running specmatic test, stub and a flask app using decorators.
|
|
84
|
+
``````test\test_contract_using_api.py`````` : Running specmatic test, stub and a flask app using the api by explicitly defining all the hosts and ports.
|
|
85
|
+
``````test\test_contract_using_api_implicit.py`````` : Running specmatic test, stub and a flask app using the api without setting explicit ports anywhere .
|
|
77
86
|
|
|
78
87
|
|
|
79
88
|
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
import os
|
|
2
|
+
|
|
2
3
|
from specmatic.server.wsgi_server import WSGIServer
|
|
3
4
|
from specmatic.core.specmatic import Specmatic
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
def specmatic_stub(project_root: str, host: str, port: int,
|
|
7
|
+
def specmatic_stub(project_root: str, host: str = '127.0.0.1', port: int = 0, expectations=None, contract_file='',
|
|
8
|
+
specmatic_json_file: str = ''):
|
|
7
9
|
def decorator(cls):
|
|
8
10
|
try:
|
|
9
|
-
stub = Specmatic.
|
|
10
|
-
stub.start()
|
|
11
|
+
stub = Specmatic.start_stub(project_root, host, port, specmatic_json_file, contract_file)
|
|
11
12
|
cls.stub = stub
|
|
12
|
-
stub.set_expectations(
|
|
13
|
+
stub.set_expectations(expectations)
|
|
13
14
|
except Exception as e:
|
|
14
15
|
if hasattr(cls, 'stub'):
|
|
15
16
|
cls.stub.stop()
|
|
@@ -22,10 +23,19 @@ def specmatic_stub(project_root: str, host: str, port: int, expectation_json_fil
|
|
|
22
23
|
return decorator
|
|
23
24
|
|
|
24
25
|
|
|
25
|
-
def specmatic_contract_test(project_root: str, host: str, port: int, contract_file='',
|
|
26
|
+
def specmatic_contract_test(project_root: str, host: str = '127.0.0,1', port: int = 0, contract_file='',
|
|
27
|
+
specmatic_json_file: str = ''):
|
|
26
28
|
def decorator(cls):
|
|
27
29
|
try:
|
|
28
|
-
|
|
30
|
+
test_host = host
|
|
31
|
+
test_port = port
|
|
32
|
+
if test_port == 0:
|
|
33
|
+
if hasattr(cls, 'app'):
|
|
34
|
+
app = cls.app
|
|
35
|
+
test_host = app.host
|
|
36
|
+
test_port = app.port
|
|
37
|
+
|
|
38
|
+
Specmatic.test(project_root, cls, test_host, test_port, specmatic_json_file, contract_file)
|
|
29
39
|
return cls
|
|
30
40
|
except Exception as e:
|
|
31
41
|
if hasattr(cls, 'stub'):
|
|
@@ -43,7 +53,7 @@ def specmatic_contract_test(project_root: str, host: str, port: int, contract_fi
|
|
|
43
53
|
return decorator
|
|
44
54
|
|
|
45
55
|
|
|
46
|
-
def start_app(app, host: str, port: int):
|
|
56
|
+
def start_app(app, host: str = '127.0.0.1', port: int = 0):
|
|
47
57
|
def decorator(cls):
|
|
48
58
|
try:
|
|
49
59
|
wsgi_app = WSGIServer(app, host, port)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from specmatic.generators.pytest_generator import PyTestGenerator
|
|
2
|
+
from specmatic.generators.unittest_generator import UnitTestGenerator
|
|
3
|
+
from specmatic.core.specmatic_test import SpecmaticTest
|
|
4
|
+
from specmatic.core.specmatic_stub import SpecmaticStub
|
|
5
|
+
from specmatic.utils import get_junit_report_file_path
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Specmatic:
|
|
9
|
+
|
|
10
|
+
@classmethod
|
|
11
|
+
def start_stub(cls, project_root: str, host: str = '127.0.0.1', port: int = 0, specmatic_json_file_path: str = '',
|
|
12
|
+
contract_file_path: str = ''):
|
|
13
|
+
stub = None
|
|
14
|
+
try:
|
|
15
|
+
stub = SpecmaticStub(project_root, host, port, specmatic_json_file_path, contract_file_path)
|
|
16
|
+
return stub
|
|
17
|
+
except Exception as e:
|
|
18
|
+
stub.stop()
|
|
19
|
+
print(f"Error: {e}")
|
|
20
|
+
raise e
|
|
21
|
+
|
|
22
|
+
@classmethod
|
|
23
|
+
def test(cls, project_root: str, test_class, host: str, port: int, specmatic_json_file_path: str = '',
|
|
24
|
+
contract_file_path: str = ''):
|
|
25
|
+
SpecmaticTest(project_root, host, port, contract_file_path, specmatic_json_file_path).run()
|
|
26
|
+
PyTestGenerator(test_class, get_junit_report_file_path()).generate()
|
|
27
|
+
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
import json
|
|
2
2
|
import os
|
|
3
|
+
import re
|
|
3
4
|
import subprocess
|
|
4
5
|
import threading
|
|
5
6
|
import traceback
|
|
6
7
|
from queue import Queue
|
|
7
8
|
|
|
8
9
|
import requests
|
|
10
|
+
from urllib.parse import urlparse
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class SpecmaticStub:
|
|
12
14
|
|
|
13
|
-
def __init__(self, project_root:str, host: str, port: int, specmatic_json_file_path: str
|
|
15
|
+
def __init__(self, project_root: str, host: str = '127.0.0.1', port: int = 0, specmatic_json_file_path: str = '',
|
|
16
|
+
contract_file_path: str = ''):
|
|
14
17
|
self.__stub_started_event = None
|
|
15
18
|
self.__process = None
|
|
16
19
|
self.project_root = project_root
|
|
@@ -18,11 +21,11 @@ class SpecmaticStub:
|
|
|
18
21
|
self.port = port
|
|
19
22
|
self.specmatic_json_file_path = specmatic_json_file_path
|
|
20
23
|
self.contract_file_path = contract_file_path
|
|
21
|
-
self.
|
|
22
|
-
self.__stub_running_success_message = f'Stub server is running on http://{self.host}:{self.port}'
|
|
24
|
+
self.__stub_running_success_message = 'Stub server is running on '
|
|
23
25
|
self.__error_queue = Queue()
|
|
26
|
+
self.__start()
|
|
24
27
|
|
|
25
|
-
def
|
|
28
|
+
def __start(self):
|
|
26
29
|
try:
|
|
27
30
|
self.__stub_started_event = threading.Event()
|
|
28
31
|
self.__start_specmatic_stub_in_subprocess()
|
|
@@ -47,7 +50,7 @@ class SpecmaticStub:
|
|
|
47
50
|
headers = {
|
|
48
51
|
"Content-Type": "application/json"
|
|
49
52
|
}
|
|
50
|
-
response = requests.post(self.
|
|
53
|
+
response = requests.post(self.__get_expectations_api_url(), json=json_string, headers=headers)
|
|
51
54
|
if response.status_code != 200:
|
|
52
55
|
self.stop()
|
|
53
56
|
raise Exception(f"{response.content} received for expectation json file: {json_string}")
|
|
@@ -57,9 +60,13 @@ class SpecmaticStub:
|
|
|
57
60
|
print(f"Error: {e}")
|
|
58
61
|
raise e
|
|
59
62
|
|
|
63
|
+
def __get_expectations_api_url(self):
|
|
64
|
+
return f'http://{self.host}:{self.port}/_specmatic/expectations'
|
|
65
|
+
|
|
60
66
|
def __start_specmatic_stub_in_subprocess(self):
|
|
61
67
|
stub_command = self.__create_stub_process_command()
|
|
62
|
-
|
|
68
|
+
if self.host != '' and self.port != 0:
|
|
69
|
+
print(f"\n Starting specmatic stub server on {self.host}:{self.port}")
|
|
63
70
|
self.__process = subprocess.Popen(stub_command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
|
64
71
|
|
|
65
72
|
def __start_reading_stub_output(self):
|
|
@@ -75,6 +82,8 @@ class SpecmaticStub:
|
|
|
75
82
|
def __read_process_output(self):
|
|
76
83
|
def signal_event_if_stub_has_started(line):
|
|
77
84
|
if self.__stub_running_success_message in line:
|
|
85
|
+
if self.port == 0:
|
|
86
|
+
self.port = line.split(self.host + ':')[1].split('.')[0]
|
|
78
87
|
self.__stub_started_event.set()
|
|
79
88
|
|
|
80
89
|
def read_and_print_output_line_by_line():
|
|
@@ -108,6 +117,9 @@ class SpecmaticStub:
|
|
|
108
117
|
cmd.append("--config=" + self.project_root + "/specmatic.json")
|
|
109
118
|
cmd += [
|
|
110
119
|
'--host=' + self.host,
|
|
111
|
-
"--port=" + str(self.port)
|
|
112
120
|
]
|
|
121
|
+
if self.port != 0:
|
|
122
|
+
cmd += [
|
|
123
|
+
"--port=" + str(self.port)
|
|
124
|
+
]
|
|
113
125
|
return cmd
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import socket
|
|
1
2
|
import threading
|
|
2
3
|
|
|
3
4
|
from specmatic.server.wsgi_server_thread import WSGIServerThread
|
|
@@ -6,10 +7,17 @@ from specmatic.server.wsgi_server_thread import WSGIServerThread
|
|
|
6
7
|
class WSGIServer:
|
|
7
8
|
server: WSGIServerThread = None
|
|
8
9
|
|
|
9
|
-
def __init__(self, app, host: str, port: int):
|
|
10
|
+
def __init__(self, app, host: str = '127.0.0.1', port: int = 0):
|
|
10
11
|
self.app = app
|
|
11
12
|
self.host = host
|
|
12
|
-
self.port = port
|
|
13
|
+
self.port = self.__find_available_port() if port == 0 else port
|
|
14
|
+
|
|
15
|
+
def __find_available_port(self):
|
|
16
|
+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
17
|
+
sock.bind(('localhost', 0))
|
|
18
|
+
port = sock.getsockname()[1]
|
|
19
|
+
sock.close()
|
|
20
|
+
return port
|
|
13
21
|
|
|
14
22
|
def start(self):
|
|
15
23
|
self.server = WSGIServerThread(self.app, self.host, self.port)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = '0.
|
|
1
|
+
__version__ = '0.5.0'
|
|
2
2
|
__specmatic_version__ = '0.67.0'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: specmatic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: A Python module for using the Specmatic Library.
|
|
5
5
|
Home-page: https://github.com/znsio/specmatic-python-extensions
|
|
6
6
|
Author: Specmatic Builders
|
|
@@ -35,10 +35,10 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
35
35
|
[Click here](https://specmatic.in/documentation/contract_tests.html) to learn more about Specmatic test mode.
|
|
36
36
|
|
|
37
37
|
|
|
38
|
-
- If you want to stub out a service dependency, add the **specmatic_stub** decorator
|
|
38
|
+
- If you want to stub out a service dependency, add the **specmatic_stub** decorator below the **start_app** decorator.
|
|
39
39
|
``````
|
|
40
40
|
@specmatic_contract_test(PROJECT_ROOT, host, port)
|
|
41
|
-
@
|
|
41
|
+
@start_app(app, host, port)
|
|
42
42
|
@specmatic_stub(PROJECT_ROOT, stub_host, stub_port, [expectation_json_file])
|
|
43
43
|
class TestApiContract:
|
|
44
44
|
pass
|
|
@@ -58,15 +58,15 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
58
58
|
pass
|
|
59
59
|
|
|
60
60
|
|
|
61
|
-
stub = Specmatic.
|
|
62
|
-
stub.start()
|
|
61
|
+
stub = Specmatic.start_stub(PROJECT_ROOT, stub_host, stub_port)
|
|
63
62
|
stub.set_expectations([expectation_json_file])
|
|
64
63
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
Specmatic.run_tests(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
64
|
+
app_server = WSGIServer(app, app_host, app_port)
|
|
65
|
+
app_server.start()
|
|
68
66
|
|
|
69
|
-
|
|
67
|
+
Specmatic.test(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
68
|
+
|
|
69
|
+
app_server.stop()
|
|
70
70
|
stub.stop()
|
|
71
71
|
|
|
72
72
|
if __name__ == '__main__':
|
|
@@ -75,14 +75,23 @@ Specmatic is a contract driven development tool that allows us to turn OpenAPI c
|
|
|
75
75
|
|
|
76
76
|
The above code can be broken down into three parts
|
|
77
77
|
- **Stub setup:**
|
|
78
|
-
Use the ``````Specmatic.
|
|
79
|
-
You can
|
|
78
|
+
Use the ``````Specmatic.start_stub()`````` method to create an start a stub instance.
|
|
79
|
+
You can explicitly supply the host/port to run.
|
|
80
|
+
If no host/port is supplied, the stub will be started on http://127.0.0.1:9000
|
|
81
|
+
You can set expectations on the stub by calling the ``````set_expectations()`````` method and passing a list of expectation json files.
|
|
82
|
+
The stub has attributes: ``````stub.host`````` and ``````stub.port`````` to tell us where it's running on.
|
|
83
|
+
|
|
80
84
|
- **App Setup:**
|
|
81
|
-
Create an instance of the ``````WSGIServer`````` class by passing it an instance of a WSGIApplication like a flask app and the host and port to run on.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
85
|
+
Create an instance of the ``````WSGIServer`````` class by passing it an instance of a WSGIApplication like a flask app and the host and port to run on.
|
|
86
|
+
If no host/port is supplied, then the app server will be started on a random freely available port.
|
|
87
|
+
The app_server also has attributes: ``````app_server.host`````` and ``````app_server.port`````` to tell us where it's running on.
|
|
88
|
+
|
|
89
|
+
- **Run Tests:**
|
|
90
|
+
Call ``````Specmatic.test()`````` by passing it your root directory, an empty Test class and the host/port on which your app server is running.
|
|
91
|
+
- Here are some examples to demonstrate how the library can be used in different ways for WSGI apps:
|
|
92
|
+
``````test\test_contract.py`````` : Running specmatic test, stub and a flask app using decorators.
|
|
93
|
+
``````test\test_contract_using_api.py`````` : Running specmatic test, stub and a flask app using the api by explicitly defining all the hosts and ports.
|
|
94
|
+
``````test\test_contract_using_api_implicit.py`````` : Running specmatic test, stub and a flask app using the api without setting explicit ports anywhere .
|
|
86
95
|
|
|
87
96
|
|
|
88
97
|
|
|
@@ -5,7 +5,7 @@ from dotenv import load_dotenv
|
|
|
5
5
|
|
|
6
6
|
load_dotenv()
|
|
7
7
|
app = Flask(__name__)
|
|
8
|
-
app.config["ORDER_API_HOST"] = os.getenv("
|
|
9
|
-
app.config["ORDER_API_PORT"] = os.getenv("
|
|
8
|
+
app.config["ORDER_API_HOST"] = os.getenv("ORDER_API_HOST")
|
|
9
|
+
app.config["ORDER_API_PORT"] = os.getenv("ORDER_API_PORT")
|
|
10
10
|
|
|
11
11
|
from test.api.routes import *
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import json
|
|
2
|
-
|
|
3
1
|
import requests
|
|
4
2
|
from test.api import app
|
|
5
3
|
|
|
4
|
+
|
|
6
5
|
class Orders:
|
|
7
|
-
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.orders_api = f'http://{app.config["ORDER_API_HOST"]}:{app.config["ORDER_API_PORT"]}/orders'
|
|
8
8
|
|
|
9
9
|
def create(self, order):
|
|
10
10
|
# Set the headers to specify that we're sending JSON data
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import requests
|
|
2
1
|
from test.api import app
|
|
2
|
+
import requests
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class Products:
|
|
6
|
-
|
|
6
|
+
def __init__(self):
|
|
7
|
+
self.products_api = f'http://{app.config["ORDER_API_HOST"]}:{app.config["ORDER_API_PORT"]}/products'
|
|
7
8
|
|
|
8
9
|
def search(self, product_type: str):
|
|
9
10
|
try:
|
|
@@ -9,11 +9,12 @@ app_port = 5000
|
|
|
9
9
|
stub_host = "127.0.0.1"
|
|
10
10
|
stub_port = 8080
|
|
11
11
|
PROJECT_ROOT = get_project_root()
|
|
12
|
+
APP_ROOT = PROJECT_ROOT + '/test'
|
|
12
13
|
expectation_json_file = PROJECT_ROOT + '/test/data/expectation.json'
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
@specmatic_contract_test(PROJECT_ROOT
|
|
16
|
-
@start_app(app
|
|
16
|
+
@specmatic_contract_test(PROJECT_ROOT)
|
|
17
|
+
@start_app(app)
|
|
17
18
|
@specmatic_stub(PROJECT_ROOT, stub_host, stub_port, [expectation_json_file])
|
|
18
19
|
class TestContract:
|
|
19
20
|
pass
|
|
@@ -16,15 +16,15 @@ class TestContract:
|
|
|
16
16
|
pass
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
stub = Specmatic.
|
|
20
|
-
stub.start()
|
|
19
|
+
stub = Specmatic.start_stub(PROJECT_ROOT, stub_host, stub_port)
|
|
21
20
|
stub.set_expectations([expectation_json_file])
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
Specmatic.run_tests(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
22
|
+
app_server = WSGIServer(app, app_host, app_port)
|
|
23
|
+
app_server.start()
|
|
26
24
|
|
|
27
|
-
|
|
25
|
+
Specmatic.test(PROJECT_ROOT, TestContract, app_host, app_port)
|
|
26
|
+
|
|
27
|
+
app_server.stop()
|
|
28
28
|
stub.stop()
|
|
29
29
|
|
|
30
30
|
if __name__ == '__main__':
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from specmatic.core.specmatic import Specmatic
|
|
3
|
+
from specmatic.server.wsgi_server import WSGIServer
|
|
4
|
+
from specmatic.utils import get_project_root
|
|
5
|
+
from test.api import app
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
stub_host = "127.0.0.1"
|
|
9
|
+
stub_port = 8080
|
|
10
|
+
PROJECT_ROOT = get_project_root()
|
|
11
|
+
expectation_json_file = PROJECT_ROOT + '/test/data/expectation.json'
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestContract:
|
|
15
|
+
pass
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
stub = Specmatic.start_stub(PROJECT_ROOT)
|
|
19
|
+
stub.set_expectations([expectation_json_file])
|
|
20
|
+
|
|
21
|
+
app.config['ORDER_API_HOST'] = stub.host
|
|
22
|
+
app.config['ORDER_API_PORT'] = stub.port
|
|
23
|
+
app_server = WSGIServer(app)
|
|
24
|
+
app_server.start()
|
|
25
|
+
|
|
26
|
+
Specmatic.test(PROJECT_ROOT, TestContract, app_server.host, app_server.port)
|
|
27
|
+
|
|
28
|
+
app_server.stop()
|
|
29
|
+
stub.stop()
|
|
30
|
+
|
|
31
|
+
if __name__ == '__main__':
|
|
32
|
+
pytest.main()
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
from specmatic.generators.pytest_generator import PyTestGenerator
|
|
2
|
-
from specmatic.generators.unittest_generator import UnitTestGenerator
|
|
3
|
-
from specmatic.core.specmatic_test import SpecmaticTest
|
|
4
|
-
from specmatic.core.specmatic_stub import SpecmaticStub
|
|
5
|
-
from specmatic.utils import get_junit_report_file_path
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Specmatic:
|
|
9
|
-
|
|
10
|
-
@classmethod
|
|
11
|
-
def create_stub(cls, project_root: str, host: str, port: int, specmatic_json_file_path: str = '',
|
|
12
|
-
contract_file_path: str = ''):
|
|
13
|
-
return SpecmaticStub(project_root, host, port, specmatic_json_file_path, contract_file_path)
|
|
14
|
-
|
|
15
|
-
@classmethod
|
|
16
|
-
def run_tests(cls, project_root: str, test_class, host: str, port: int, specmatic_json_file_path: str = '',
|
|
17
|
-
contract_file_path: str = ''):
|
|
18
|
-
SpecmaticTest(project_root, host, port, contract_file_path, specmatic_json_file_path).run()
|
|
19
|
-
PyTestGenerator(test_class, get_junit_report_file_path()).generate()
|
|
20
|
-
|
|
21
|
-
@classmethod
|
|
22
|
-
def run_unit_tests(cls, project_root: str, test_class, host: str, port: int, specmatic_json_file_path: str = '',
|
|
23
|
-
contract_file_path: str = ''):
|
|
24
|
-
SpecmaticTest(project_root, host, port, contract_file_path, specmatic_json_file_path).run()
|
|
25
|
-
UnitTestGenerator(test_class, get_junit_report_file_path()).generate()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|