specmatic 0.8.2__tar.gz → 0.9.1__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.8.2/specmatic.egg-info → specmatic-0.9.1}/PKG-INFO +14 -25
- {specmatic-0.8.2 → specmatic-0.9.1}/README.md +13 -24
- specmatic-0.9.1/specmatic/core/specmatic.py +138 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/servers/asgi_app_server.py +3 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/version.py +1 -1
- {specmatic-0.8.2 → specmatic-0.9.1/specmatic.egg-info}/PKG-INFO +14 -25
- specmatic-0.8.2/specmatic/core/specmatic.py +0 -85
- {specmatic-0.8.2 → specmatic-0.9.1}/MANIFEST.in +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/setup.cfg +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/setup.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/__init__.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/core/__init__.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/core/decorators.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/core/specmatic.jar +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/core/specmatic_base.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/core/specmatic_stub.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/core/specmatic_test.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/generators/__init__.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/generators/pytest_generator.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/generators/test_generator_base.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/generators/unittest_generator.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/servers/__init__.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/servers/app_server.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/servers/wsgi_app_server.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/servers/wsgi_server_thread.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic/utils.py +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic.egg-info/SOURCES.txt +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic.egg-info/dependency_links.txt +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic.egg-info/requires.txt +0 -0
- {specmatic-0.8.2 → specmatic-0.9.1}/specmatic.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: specmatic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.1
|
|
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
|
|
@@ -41,28 +41,24 @@ The open api specification can be present either locally or in a [Central Contra
|
|
|
41
41
|
## WSGI Apps
|
|
42
42
|
|
|
43
43
|
#### To run contract tests with a stub for a wsgi app (like Flask):
|
|
44
|
-
|
|
45
|
-
``````app_server = WSGIAppServer(app, app_host, app_port)``````
|
|
46
|
-
- Note:
|
|
47
|
-
- The host and port are optional. If they are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
48
|
-
- You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
|
|
49
|
-
- To run tests using a stub for your dependencies:
|
|
44
|
+
|
|
50
45
|
``````
|
|
51
46
|
class TestContract:
|
|
52
47
|
pass
|
|
53
48
|
|
|
54
49
|
|
|
55
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
56
50
|
Specmatic() \
|
|
57
51
|
.with_project_root(PROJECT_ROOT) \
|
|
58
|
-
.
|
|
59
|
-
.app
|
|
52
|
+
.with_stub(stub_host, stub_port, [expectation_json_file]) \
|
|
53
|
+
.with_wsgi_app(app, app_host, app_port) \
|
|
60
54
|
.test(TestContract) \
|
|
61
55
|
.run()
|
|
62
56
|
``````
|
|
63
57
|
|
|
64
58
|
- In this, we are passing:
|
|
65
|
-
- an instance of
|
|
59
|
+
- an instance of your asgi app like flask
|
|
60
|
+
- app_host and app_port. If they are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
61
|
+
- You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
|
|
66
62
|
- an empty test class.
|
|
67
63
|
- stub_host, stub_port, optional list of json files to set expectations on the stub.
|
|
68
64
|
The stub_host, stub_port will be used to run the specmatic stub server.
|
|
@@ -79,11 +75,9 @@ Specmatic() \
|
|
|
79
75
|
class TestContract:
|
|
80
76
|
pass
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
84
78
|
Specmatic() \
|
|
85
79
|
.with_project_root(PROJECT_ROOT) \
|
|
86
|
-
.app
|
|
80
|
+
.with_wsgi_app(app, app_host, app_port) \
|
|
87
81
|
.test(TestContract) \
|
|
88
82
|
.run()
|
|
89
83
|
``````
|
|
@@ -91,20 +85,16 @@ Specmatic() \
|
|
|
91
85
|
## ASGI Apps
|
|
92
86
|
|
|
93
87
|
#### To run contract tests with a stub for an asgi app (like sanic):
|
|
94
|
-
-
|
|
95
|
-
``````app_server = ASGIAppServer('main:app', app_host, app_port)``````
|
|
96
|
-
If host and port are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
97
|
-
- You can now use the ``````ASGIAppServer`````` object to run tests just like we do it for WSGI apps:
|
|
88
|
+
- If you are using an asgi app like sanic, fastapi, use the ``````with_asgi_app`````` function and pass it a string in the 'module:app' format.
|
|
98
89
|
``````
|
|
99
90
|
class TestContract:
|
|
100
91
|
pass
|
|
101
92
|
|
|
102
93
|
|
|
103
|
-
app_server = ASGIAppServer('main:app', app_host, app_port)
|
|
104
94
|
Specmatic() \
|
|
105
95
|
.with_project_root(PROJECT_ROOT) \
|
|
106
|
-
.
|
|
107
|
-
.app
|
|
96
|
+
.with_stub(stub_host, stub_port, [expectation_json_file]) \
|
|
97
|
+
.with_asgi_app('main:app', app_host, app_port) \
|
|
108
98
|
.test(TestContract) \
|
|
109
99
|
.run()
|
|
110
100
|
``````
|
|
@@ -116,18 +106,17 @@ class TestContract:
|
|
|
116
106
|
pass
|
|
117
107
|
|
|
118
108
|
|
|
119
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
120
109
|
Specmatic() \
|
|
121
110
|
.with_project_root(PROJECT_ROOT) \
|
|
122
|
-
.
|
|
123
|
-
.app
|
|
111
|
+
.with_stub(stub_host, stub_port, [expectation_json_file], ['--strict']) \
|
|
112
|
+
.with_wsgi_app(app, port=app_port) \
|
|
124
113
|
.test(TestContract, args=['--testBaseURL=http://localhost:5000']) \
|
|
125
114
|
.run()
|
|
126
115
|
``````
|
|
127
116
|
|
|
128
117
|
## Common Issues
|
|
129
118
|
- **'Error loading ASGI app'**
|
|
130
|
-
This error occurs
|
|
119
|
+
This error occurs when an incorrect app module string is passed to the ``````with_asgi_app`````` function.
|
|
131
120
|
|
|
132
121
|
#### Solutions:
|
|
133
122
|
- Try to identify the correct module in which your app variable is instantiated/imported.
|
|
@@ -32,28 +32,24 @@ The open api specification can be present either locally or in a [Central Contra
|
|
|
32
32
|
## WSGI Apps
|
|
33
33
|
|
|
34
34
|
#### To run contract tests with a stub for a wsgi app (like Flask):
|
|
35
|
-
|
|
36
|
-
``````app_server = WSGIAppServer(app, app_host, app_port)``````
|
|
37
|
-
- Note:
|
|
38
|
-
- The host and port are optional. If they are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
39
|
-
- You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
|
|
40
|
-
- To run tests using a stub for your dependencies:
|
|
35
|
+
|
|
41
36
|
``````
|
|
42
37
|
class TestContract:
|
|
43
38
|
pass
|
|
44
39
|
|
|
45
40
|
|
|
46
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
47
41
|
Specmatic() \
|
|
48
42
|
.with_project_root(PROJECT_ROOT) \
|
|
49
|
-
.
|
|
50
|
-
.app
|
|
43
|
+
.with_stub(stub_host, stub_port, [expectation_json_file]) \
|
|
44
|
+
.with_wsgi_app(app, app_host, app_port) \
|
|
51
45
|
.test(TestContract) \
|
|
52
46
|
.run()
|
|
53
47
|
``````
|
|
54
48
|
|
|
55
49
|
- In this, we are passing:
|
|
56
|
-
- an instance of
|
|
50
|
+
- an instance of your asgi app like flask
|
|
51
|
+
- app_host and app_port. If they are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
52
|
+
- You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
|
|
57
53
|
- an empty test class.
|
|
58
54
|
- stub_host, stub_port, optional list of json files to set expectations on the stub.
|
|
59
55
|
The stub_host, stub_port will be used to run the specmatic stub server.
|
|
@@ -70,11 +66,9 @@ Specmatic() \
|
|
|
70
66
|
class TestContract:
|
|
71
67
|
pass
|
|
72
68
|
|
|
73
|
-
|
|
74
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
75
69
|
Specmatic() \
|
|
76
70
|
.with_project_root(PROJECT_ROOT) \
|
|
77
|
-
.app
|
|
71
|
+
.with_wsgi_app(app, app_host, app_port) \
|
|
78
72
|
.test(TestContract) \
|
|
79
73
|
.run()
|
|
80
74
|
``````
|
|
@@ -82,20 +76,16 @@ Specmatic() \
|
|
|
82
76
|
## ASGI Apps
|
|
83
77
|
|
|
84
78
|
#### To run contract tests with a stub for an asgi app (like sanic):
|
|
85
|
-
-
|
|
86
|
-
``````app_server = ASGIAppServer('main:app', app_host, app_port)``````
|
|
87
|
-
If host and port are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
88
|
-
- You can now use the ``````ASGIAppServer`````` object to run tests just like we do it for WSGI apps:
|
|
79
|
+
- If you are using an asgi app like sanic, fastapi, use the ``````with_asgi_app`````` function and pass it a string in the 'module:app' format.
|
|
89
80
|
``````
|
|
90
81
|
class TestContract:
|
|
91
82
|
pass
|
|
92
83
|
|
|
93
84
|
|
|
94
|
-
app_server = ASGIAppServer('main:app', app_host, app_port)
|
|
95
85
|
Specmatic() \
|
|
96
86
|
.with_project_root(PROJECT_ROOT) \
|
|
97
|
-
.
|
|
98
|
-
.app
|
|
87
|
+
.with_stub(stub_host, stub_port, [expectation_json_file]) \
|
|
88
|
+
.with_asgi_app('main:app', app_host, app_port) \
|
|
99
89
|
.test(TestContract) \
|
|
100
90
|
.run()
|
|
101
91
|
``````
|
|
@@ -107,18 +97,17 @@ class TestContract:
|
|
|
107
97
|
pass
|
|
108
98
|
|
|
109
99
|
|
|
110
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
111
100
|
Specmatic() \
|
|
112
101
|
.with_project_root(PROJECT_ROOT) \
|
|
113
|
-
.
|
|
114
|
-
.app
|
|
102
|
+
.with_stub(stub_host, stub_port, [expectation_json_file], ['--strict']) \
|
|
103
|
+
.with_wsgi_app(app, port=app_port) \
|
|
115
104
|
.test(TestContract, args=['--testBaseURL=http://localhost:5000']) \
|
|
116
105
|
.run()
|
|
117
106
|
``````
|
|
118
107
|
|
|
119
108
|
## Common Issues
|
|
120
109
|
- **'Error loading ASGI app'**
|
|
121
|
-
This error occurs
|
|
110
|
+
This error occurs when an incorrect app module string is passed to the ``````with_asgi_app`````` function.
|
|
122
111
|
|
|
123
112
|
#### Solutions:
|
|
124
113
|
- Try to identify the correct module in which your app variable is instantiated/imported.
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from specmatic.core.specmatic_stub import SpecmaticStub
|
|
4
|
+
from specmatic.core.specmatic_test import SpecmaticTest
|
|
5
|
+
from specmatic.generators.pytest_generator import PyTestGenerator
|
|
6
|
+
from specmatic.generators.unittest_generator import UnitTestGenerator
|
|
7
|
+
from specmatic.servers.app_server import AppServer
|
|
8
|
+
from specmatic.servers.asgi_app_server import ASGIAppServer
|
|
9
|
+
from specmatic.servers.wsgi_app_server import WSGIAppServer
|
|
10
|
+
from specmatic.utils import get_junit_report_file_path
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class Specmatic:
|
|
14
|
+
def __init__(self):
|
|
15
|
+
self.app = None
|
|
16
|
+
self.app_module = ''
|
|
17
|
+
self.app_host = '127.0.0.1'
|
|
18
|
+
self.app_port = 0
|
|
19
|
+
self.reset_app_config_func = None
|
|
20
|
+
self.set_app_config_func = None
|
|
21
|
+
self.app_server = None
|
|
22
|
+
|
|
23
|
+
self.stub_host = None
|
|
24
|
+
self.stub_port = None
|
|
25
|
+
self.expectations = None
|
|
26
|
+
self.stub_args = None
|
|
27
|
+
self.stub = None
|
|
28
|
+
|
|
29
|
+
self.test_class = None
|
|
30
|
+
self.test_host = None
|
|
31
|
+
self.test_port = None
|
|
32
|
+
self.test_args = None
|
|
33
|
+
|
|
34
|
+
self.project_root = ''
|
|
35
|
+
self.specmatic_json_file_path = ''
|
|
36
|
+
|
|
37
|
+
self.run_stub = False
|
|
38
|
+
self.run_app = False
|
|
39
|
+
self.run_tests = False
|
|
40
|
+
|
|
41
|
+
def with_project_root(self, project_root):
|
|
42
|
+
self.project_root = project_root
|
|
43
|
+
return self
|
|
44
|
+
|
|
45
|
+
def with_specmatic_json_file_path(self, specmatic_json_file_path):
|
|
46
|
+
self.specmatic_json_file_path = specmatic_json_file_path
|
|
47
|
+
return self
|
|
48
|
+
|
|
49
|
+
def with_stub(self, stub_host: str = '127.0.0.1', stub_port: int = 0, expectations=None, args=None):
|
|
50
|
+
self.stub_host = stub_host
|
|
51
|
+
self.stub_port = stub_port
|
|
52
|
+
self.run_stub = True
|
|
53
|
+
self.expectations = expectations
|
|
54
|
+
self.stub_args = args
|
|
55
|
+
return self
|
|
56
|
+
|
|
57
|
+
def app(self, app_server: AppServer):
|
|
58
|
+
self.app_server = app_server
|
|
59
|
+
self.run_app = True
|
|
60
|
+
return self
|
|
61
|
+
|
|
62
|
+
def with_wsgi_app(self, app, host: str = '127.0.0.1', port: int = 0, set_app_config_func=None,
|
|
63
|
+
reset_app_config_func=None):
|
|
64
|
+
self.app = app
|
|
65
|
+
self.app_host = host
|
|
66
|
+
self.app_port = port
|
|
67
|
+
self.set_app_config_func = set_app_config_func
|
|
68
|
+
self.reset_app_config_func = reset_app_config_func
|
|
69
|
+
self.run_app = True
|
|
70
|
+
return self
|
|
71
|
+
|
|
72
|
+
def with_asgi_app(self, app_module: str, host: str = '127.0.0.1', port: int = 0, set_app_config_func=None,
|
|
73
|
+
reset_app_config_func=None):
|
|
74
|
+
self.app_module = app_module
|
|
75
|
+
self.app_host = host
|
|
76
|
+
self.app_port = port
|
|
77
|
+
self.set_app_config_func = set_app_config_func
|
|
78
|
+
self.reset_app_config_func = reset_app_config_func
|
|
79
|
+
self.run_app = True
|
|
80
|
+
return self
|
|
81
|
+
|
|
82
|
+
def test(self, test_class, test_host: str = '127.0.0.1', test_port: int = 0, args=None):
|
|
83
|
+
self.test_class = test_class
|
|
84
|
+
self.test_host = test_host
|
|
85
|
+
self.test_port = test_port
|
|
86
|
+
self.test_args = args
|
|
87
|
+
self.run_tests = True
|
|
88
|
+
return self
|
|
89
|
+
|
|
90
|
+
def __init_app_server(self):
|
|
91
|
+
if self.run_app:
|
|
92
|
+
if self.app is None and self.app_module == '':
|
|
93
|
+
raise Exception('Please specify either an app or an app_module.')
|
|
94
|
+
if self.app is not None and self.app_module != '':
|
|
95
|
+
raise Exception('Please specify only one of app or app_module, and not both.')
|
|
96
|
+
if self.app is not None:
|
|
97
|
+
self.app_server = WSGIAppServer(self.app, self.app_host, self.app_port, self.set_app_config_func,
|
|
98
|
+
self.reset_app_config_func)
|
|
99
|
+
else:
|
|
100
|
+
self.app_server = ASGIAppServer(self.app_module, self.app_host, self.app_port, self.set_app_config_func,
|
|
101
|
+
self.reset_app_config_func)
|
|
102
|
+
|
|
103
|
+
def __start_stub(self):
|
|
104
|
+
if self.run_stub:
|
|
105
|
+
self.stub = SpecmaticStub(self.stub_host, self.stub_port, self.project_root, self.specmatic_json_file_path,
|
|
106
|
+
self.stub_args)
|
|
107
|
+
self.stub.set_expectations(self.expectations)
|
|
108
|
+
self.app_server.set_app_config(self.stub.host, self.stub.port)
|
|
109
|
+
|
|
110
|
+
def __execute_tests(self):
|
|
111
|
+
if self.run_tests:
|
|
112
|
+
if self.app_server is not None:
|
|
113
|
+
self.app_server.start()
|
|
114
|
+
self.test_host = self.app_server.host
|
|
115
|
+
self.test_port = self.app_server.port
|
|
116
|
+
SpecmaticTest(self.test_host, self.test_port, self.project_root,
|
|
117
|
+
self.specmatic_json_file_path, self.test_args).run()
|
|
118
|
+
if issubclass(self.test_class, unittest.TestCase):
|
|
119
|
+
print("Injecting unittest methods")
|
|
120
|
+
UnitTestGenerator(self.test_class, get_junit_report_file_path()).generate()
|
|
121
|
+
else:
|
|
122
|
+
print("Injecting pytest methods")
|
|
123
|
+
PyTestGenerator(self.test_class, get_junit_report_file_path()).generate()
|
|
124
|
+
|
|
125
|
+
def run(self):
|
|
126
|
+
try:
|
|
127
|
+
self.__init_app_server()
|
|
128
|
+
self.__start_stub()
|
|
129
|
+
self.__execute_tests()
|
|
130
|
+
except Exception as e:
|
|
131
|
+
print(f"Error: {e}")
|
|
132
|
+
raise e
|
|
133
|
+
finally:
|
|
134
|
+
if self.app_server is not None:
|
|
135
|
+
self.app_server.stop()
|
|
136
|
+
self.app_server.reset_app_config()
|
|
137
|
+
if self.stub is not None:
|
|
138
|
+
self.stub.stop()
|
|
@@ -43,6 +43,9 @@ class ASGIAppServer(AppServer):
|
|
|
43
43
|
def __read_process_output(self):
|
|
44
44
|
try:
|
|
45
45
|
for line in iter(self.__process.stdout.readline, ''):
|
|
46
|
+
if self.__process.poll() is not None:
|
|
47
|
+
line = line.decode()
|
|
48
|
+
raise Exception('App process terminated due to an error ' + line)
|
|
46
49
|
if line:
|
|
47
50
|
line = line.decode().rstrip()
|
|
48
51
|
print(line)
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = '0.
|
|
1
|
+
__version__ = '0.9.1'
|
|
2
2
|
__specmatic_version__ = '0.68.0'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: specmatic
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.9.1
|
|
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
|
|
@@ -41,28 +41,24 @@ The open api specification can be present either locally or in a [Central Contra
|
|
|
41
41
|
## WSGI Apps
|
|
42
42
|
|
|
43
43
|
#### To run contract tests with a stub for a wsgi app (like Flask):
|
|
44
|
-
|
|
45
|
-
``````app_server = WSGIAppServer(app, app_host, app_port)``````
|
|
46
|
-
- Note:
|
|
47
|
-
- The host and port are optional. If they are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
48
|
-
- You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
|
|
49
|
-
- To run tests using a stub for your dependencies:
|
|
44
|
+
|
|
50
45
|
``````
|
|
51
46
|
class TestContract:
|
|
52
47
|
pass
|
|
53
48
|
|
|
54
49
|
|
|
55
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
56
50
|
Specmatic() \
|
|
57
51
|
.with_project_root(PROJECT_ROOT) \
|
|
58
|
-
.
|
|
59
|
-
.app
|
|
52
|
+
.with_stub(stub_host, stub_port, [expectation_json_file]) \
|
|
53
|
+
.with_wsgi_app(app, app_host, app_port) \
|
|
60
54
|
.test(TestContract) \
|
|
61
55
|
.run()
|
|
62
56
|
``````
|
|
63
57
|
|
|
64
58
|
- In this, we are passing:
|
|
65
|
-
- an instance of
|
|
59
|
+
- an instance of your asgi app like flask
|
|
60
|
+
- app_host and app_port. If they are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
61
|
+
- You would need a [specmatic.json](https://specmatic.in/documentation/specmatic_json.html) file to be present in the root directory of your project.
|
|
66
62
|
- an empty test class.
|
|
67
63
|
- stub_host, stub_port, optional list of json files to set expectations on the stub.
|
|
68
64
|
The stub_host, stub_port will be used to run the specmatic stub server.
|
|
@@ -79,11 +75,9 @@ Specmatic() \
|
|
|
79
75
|
class TestContract:
|
|
80
76
|
pass
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
84
78
|
Specmatic() \
|
|
85
79
|
.with_project_root(PROJECT_ROOT) \
|
|
86
|
-
.app
|
|
80
|
+
.with_wsgi_app(app, app_host, app_port) \
|
|
87
81
|
.test(TestContract) \
|
|
88
82
|
.run()
|
|
89
83
|
``````
|
|
@@ -91,20 +85,16 @@ Specmatic() \
|
|
|
91
85
|
## ASGI Apps
|
|
92
86
|
|
|
93
87
|
#### To run contract tests with a stub for an asgi app (like sanic):
|
|
94
|
-
-
|
|
95
|
-
``````app_server = ASGIAppServer('main:app', app_host, app_port)``````
|
|
96
|
-
If host and port are not specified, the app will be started on a random available port on 127.0.0.1.
|
|
97
|
-
- You can now use the ``````ASGIAppServer`````` object to run tests just like we do it for WSGI apps:
|
|
88
|
+
- If you are using an asgi app like sanic, fastapi, use the ``````with_asgi_app`````` function and pass it a string in the 'module:app' format.
|
|
98
89
|
``````
|
|
99
90
|
class TestContract:
|
|
100
91
|
pass
|
|
101
92
|
|
|
102
93
|
|
|
103
|
-
app_server = ASGIAppServer('main:app', app_host, app_port)
|
|
104
94
|
Specmatic() \
|
|
105
95
|
.with_project_root(PROJECT_ROOT) \
|
|
106
|
-
.
|
|
107
|
-
.app
|
|
96
|
+
.with_stub(stub_host, stub_port, [expectation_json_file]) \
|
|
97
|
+
.with_asgi_app('main:app', app_host, app_port) \
|
|
108
98
|
.test(TestContract) \
|
|
109
99
|
.run()
|
|
110
100
|
``````
|
|
@@ -116,18 +106,17 @@ class TestContract:
|
|
|
116
106
|
pass
|
|
117
107
|
|
|
118
108
|
|
|
119
|
-
app_server = WSGIAppServer(app, app_host, app_port)
|
|
120
109
|
Specmatic() \
|
|
121
110
|
.with_project_root(PROJECT_ROOT) \
|
|
122
|
-
.
|
|
123
|
-
.app
|
|
111
|
+
.with_stub(stub_host, stub_port, [expectation_json_file], ['--strict']) \
|
|
112
|
+
.with_wsgi_app(app, port=app_port) \
|
|
124
113
|
.test(TestContract, args=['--testBaseURL=http://localhost:5000']) \
|
|
125
114
|
.run()
|
|
126
115
|
``````
|
|
127
116
|
|
|
128
117
|
## Common Issues
|
|
129
118
|
- **'Error loading ASGI app'**
|
|
130
|
-
This error occurs
|
|
119
|
+
This error occurs when an incorrect app module string is passed to the ``````with_asgi_app`````` function.
|
|
131
120
|
|
|
132
121
|
#### Solutions:
|
|
133
122
|
- Try to identify the correct module in which your app variable is instantiated/imported.
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
|
|
3
|
-
from specmatic.core.specmatic_stub import SpecmaticStub
|
|
4
|
-
from specmatic.core.specmatic_test import SpecmaticTest
|
|
5
|
-
from specmatic.generators.pytest_generator import PyTestGenerator
|
|
6
|
-
from specmatic.generators.unittest_generator import UnitTestGenerator
|
|
7
|
-
from specmatic.servers.app_server import AppServer
|
|
8
|
-
from specmatic.utils import get_junit_report_file_path
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
class Specmatic:
|
|
12
|
-
def __init__(self):
|
|
13
|
-
self.test_args = None
|
|
14
|
-
self.stub_args = None
|
|
15
|
-
self.test_class = None
|
|
16
|
-
self.test_port = None
|
|
17
|
-
self.test_host = None
|
|
18
|
-
self.app_server = None
|
|
19
|
-
self.expectations = None
|
|
20
|
-
self.stub_port = None
|
|
21
|
-
self.stub_host = None
|
|
22
|
-
self.run_stub = False
|
|
23
|
-
self.run_app = False
|
|
24
|
-
self.run_tests = False
|
|
25
|
-
self.project_root = ''
|
|
26
|
-
self.specmatic_json_file_path = ''
|
|
27
|
-
|
|
28
|
-
def with_project_root(self, project_root):
|
|
29
|
-
self.project_root = project_root
|
|
30
|
-
return self
|
|
31
|
-
|
|
32
|
-
def with_specmatic_json_file_path(self, specmatic_json_file_path):
|
|
33
|
-
self.specmatic_json_file_path = specmatic_json_file_path
|
|
34
|
-
return self
|
|
35
|
-
|
|
36
|
-
def stub(self, stub_host: str = '127.0.0.1', stub_port: int = 0, expectations=None, args=None):
|
|
37
|
-
self.stub_host = stub_host
|
|
38
|
-
self.stub_port = stub_port
|
|
39
|
-
self.run_stub = True
|
|
40
|
-
self.expectations = expectations
|
|
41
|
-
self.stub_args = args
|
|
42
|
-
return self
|
|
43
|
-
|
|
44
|
-
def app(self, app_server: AppServer):
|
|
45
|
-
self.app_server = app_server
|
|
46
|
-
self.run_app = True
|
|
47
|
-
return self
|
|
48
|
-
|
|
49
|
-
def test(self, test_class, test_host: str = '127.0.0.1', test_port: int = 0, args=None):
|
|
50
|
-
self.test_class = test_class
|
|
51
|
-
self.test_host = test_host
|
|
52
|
-
self.test_port = test_port
|
|
53
|
-
self.test_args = args
|
|
54
|
-
self.run_tests = True
|
|
55
|
-
return self
|
|
56
|
-
|
|
57
|
-
def run(self):
|
|
58
|
-
stub = None
|
|
59
|
-
try:
|
|
60
|
-
if self.run_stub:
|
|
61
|
-
stub = SpecmaticStub(self.stub_host, self.stub_port, self.project_root, self.specmatic_json_file_path, self.stub_args)
|
|
62
|
-
stub.set_expectations(self.expectations)
|
|
63
|
-
self.app_server.set_app_config(stub.host, stub.port)
|
|
64
|
-
if self.run_app:
|
|
65
|
-
self.app_server.start()
|
|
66
|
-
self.test_host = self.app_server.host
|
|
67
|
-
self.test_port = self.app_server.port
|
|
68
|
-
if self.run_tests:
|
|
69
|
-
SpecmaticTest(self.test_host, self.test_port, self.project_root,
|
|
70
|
-
self.specmatic_json_file_path, self.test_args).run()
|
|
71
|
-
if issubclass(self.test_class, unittest.TestCase):
|
|
72
|
-
print("Injecting unittest methods")
|
|
73
|
-
UnitTestGenerator(self.test_class, get_junit_report_file_path()).generate()
|
|
74
|
-
else:
|
|
75
|
-
print("Injecting pytest methods")
|
|
76
|
-
PyTestGenerator(self.test_class, get_junit_report_file_path()).generate()
|
|
77
|
-
except Exception as e:
|
|
78
|
-
print(f"Error: {e}")
|
|
79
|
-
raise e
|
|
80
|
-
finally:
|
|
81
|
-
if self.app_server is not None:
|
|
82
|
-
self.app_server.stop()
|
|
83
|
-
self.app_server.reset_app_config()
|
|
84
|
-
if stub is not None:
|
|
85
|
-
stub.stop()
|
|
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
|
|
File without changes
|