1111# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212# See the License for the specific language governing permissions and
1313# limitations under the License.
14- from dataclasses import dataclass
15- from pathlib import Path
16- from typing import Any
14+ from typing import TYPE_CHECKING , Any
1715
1816from DataDriver import DataDriver # type: ignore
19- from DataDriver .AbstractReaderClass import AbstractReaderClass # type: ignore
20- from DataDriver .ReaderConfig import TestCaseData # type: ignore
21- from hypothesis import HealthCheck , Phase , Verbosity , given , settings
22- from hypothesis import strategies as st
2317from robot .api import logger
2418from robot .api .deco import keyword
2519from robot .result .model import TestCase as ResultTestCase # type: ignore
2620from robot .result .model import TestSuite as ResultTestSuite # type: ignore
2721from robot .running .model import TestCase , TestSuite # type: ignore
2822from robotlibcore import DynamicCore # type: ignore
29- from schemathesis import Case , openapi
23+ from schemathesis import Case
3024from schemathesis .core import NotSet
31- from schemathesis .core .result import Ok
3225from schemathesis .core .transport import Response
3326
34- __version__ = "0.53.0"
27+ from . schemathesisreader import Options , SchemathesisReader
3528
29+ if TYPE_CHECKING :
30+ from pathlib import Path
3631
37- @dataclass
38- class Options :
39- max_examples : int
40- headers : dict [str , Any ] | None = None
41- path : "Path|None" = None
42- url : "str|None" = None
43-
44-
45- class SchemathesisReader (AbstractReaderClass ):
46- options : "Options|None" = None
47-
48- def get_data_from_source (self ) -> list [TestCaseData ]:
49- if not self .options :
50- raise ValueError ("Options must be set before calling get_data_from_source." )
51- url = self .options .url
52- path = self .options .path
53- if path and not Path (path ).is_file ():
54- raise ValueError (f"Provided path '{ path } ' is not a valid file." )
55- if path :
56- schema = openapi .from_path (path )
57- elif url :
58- headers = self .options .headers or {}
59- schema = openapi .from_url (url , headers = headers )
60- else :
61- raise ValueError ("Either 'url' or 'path' must be provided to SchemathesisLibrary." )
62- all_cases : list [TestCaseData ] = []
63- for op in schema .get_all_operations ():
64- if isinstance (op , Ok ):
65- # NOTE: (dd): `as_strategy` also accepts GenerationMode
66- # It could be used to produce positive / negative tests
67- strategy = op .ok ().as_strategy ().map (from_case ) # type: ignore
68- add_examples (strategy , all_cases , self .options .max_examples ) # type: ignore
69- return all_cases
70-
71-
72- def from_case (case : Case ) -> TestCaseData :
73- return TestCaseData (
74- test_case_name = f"{ case .operation .label } - { case .id } " ,
75- arguments = {"${case}" : case },
76- )
32+ __version__ = "0.53.0"
7733
7834
7935class SchemathesisLibrary (DynamicCore ):
@@ -121,17 +77,21 @@ def __init__(
12177 max_examples : int = 5 ,
12278 path : "Path|None" = None ,
12379 url : "str|None" = None ,
80+ auth : str | None = None ,
12481 ) -> None :
12582 """The SchemathesisLibrary can be initialized with the following arguments:
12683
12784 | =Argument= | =Description= |
128- | `headers` | Optional HTTP headers to be used schema is downloaded from `url`. |
85+ | `headers` | Optional HTTP headers to be used when schema is downloaded from `url`. |
12986 | `max_examples` | Maximum number of examples to generate for each operation. Default is 5. |
13087 | `path` | Path to the OpenAPI schema file. Using either `path` or `url` is mandatory. |
13188 | `url` | URL where the OpenAPI schema can be downloaded. |
89+ | `auth` | Optional authentication class to be used passed for Schemathesis authentication when test cases are executed. |
13290 """
13391 self .ROBOT_LIBRARY_LISTENER = self
134- SchemathesisReader .options = Options (headers = headers , max_examples = max_examples , path = path , url = url )
92+ SchemathesisReader .options = Options (
93+ headers = headers , max_examples = max_examples , path = path , url = url , auth = auth
94+ )
13595 self .data_driver = DataDriver (reader_class = SchemathesisReader )
13696 DynamicCore .__init__ (self , [])
13797
@@ -146,9 +106,8 @@ def call_and_validate(
146106 self ,
147107 case : Case ,
148108 * ,
149- auth : "Any|None" = None ,
150- base_url : "str|None" = None ,
151- headers : "dict[str, Any]|None" = None ,
109+ base_url : str | None = None ,
110+ headers : dict [str , Any ] | None = None ,
152111 ) -> Response :
153112 """Call and validate a Schemathesis case.
154113
@@ -157,7 +116,7 @@ def call_and_validate(
157116 """
158117 self .info (f"Case: { case .path } | { case .method } | { case .path_parameters } " )
159118 self ._log_case (case , headers )
160- response = case .call_and_validate (base_url = base_url , headers = headers , auth = auth )
119+ response = case .call_and_validate (base_url = base_url , headers = headers )
161120 self ._log_request (response )
162121 self .debug (f"Response: { response .headers } | { response .status_code } | { response .text } " )
163122 return response
@@ -167,9 +126,8 @@ def call(
167126 self ,
168127 case : Case ,
169128 * ,
170- auth : "Any|None" = None ,
171- base_url : "str|None" = None ,
172- headers : "dict[str, Any]|None" = None ,
129+ base_url : str | None = None ,
130+ headers : dict [str , Any ] | None = None ,
173131 ) -> Response :
174132 """Call a Schemathesis case without validation.
175133
@@ -182,7 +140,7 @@ def call(
182140 """
183141 self .info (f"Calling case: { case .path } | { case .method } | { case .path_parameters } " )
184142 self ._log_case (case )
185- response = case .call (base_url = base_url , headers = headers , auth = auth )
143+ response = case .call (base_url = base_url , headers = headers )
186144 self ._log_request (response )
187145 return response
188146
@@ -222,19 +180,3 @@ def _log_request(self, resposen: Response) -> None:
222180 f"Request: { resposen .request .method } { resposen .request .url } "
223181 f"headers: { resposen .request .headers !r} body: { resposen .request .body !r} "
224182 )
225-
226-
227- def add_examples (strategy : st .SearchStrategy , container : list [TestCaseData ], max_examples : int ) -> None :
228- @given (strategy )
229- @settings (
230- database = None ,
231- max_examples = max_examples ,
232- deadline = None ,
233- verbosity = Verbosity .quiet ,
234- phases = (Phase .generate ,),
235- suppress_health_check = list (HealthCheck ),
236- )
237- def example_generating_inner_function (ex : Any ) -> None :
238- container .append (ex )
239-
240- example_generating_inner_function ()
0 commit comments