diff --git a/README.md b/README.md index 6191017..4a1baa9 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ In case of API, the IDTA specifications define service specifications and profil | Name | Profile Identifier | Description | Support in test-engine | | :--- | :--- | :--- | :--- | | AAS Repository Read Profile | https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002 | Only read operations for the AAS Repository Service | ✅ | +| AAS Read Profile | https://admin-shell.io/aas/API/3/0/AssetAdministrationShellServiceSpecification/SSP-002 | Only read operations for the AAS Service | ✅ | | Submodel Repository Read Profile | https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-002 | Only read operations for the Submodel Repository Service | ✅ | | Submodel Read Profile | https://admin-shell.io/aas/API/3/0/SubmodelServiceSpecification/SSP-002 | Only read operations for the Submodel Repository Service | ✅ | | AAS Registry Read Profile | https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRegistryServiceSpecification/SSP-002 | Only read operations for AAS Registry Service | (✔️) | diff --git a/aas_test_engines/test_cases/v3_0/api.py b/aas_test_engines/test_cases/v3_0/api.py index a3d4650..02ebeab 100644 --- a/aas_test_engines/test_cases/v3_0/api.py +++ b/aas_test_engines/test_cases/v3_0/api.py @@ -646,7 +646,8 @@ def test_filter_by_asset_id(self): encoded_asset_id = base64.b64encode(json.dumps(self.asset_id).encode()).decode() request = generate_one_valid(self.operation, self.sample_cache, {'assetIds': encoded_asset_id}) data = _invoke_and_decode(request, self.conf, True) - _assert(len(data["result"]) != 0, "Returns non-empty list") + if data: + _assert(len(data["result"]) != 0, "Returns non-empty list") @operation("GetAllAssetAdministrationShells") @@ -674,46 +675,67 @@ def test_filter_by_idshort(self): # AssetAdministrationShell Interface ##################################### -# /shells/ -# /aas - -@operation("GetAssetAdministrationShellById") -class GetAasById(ApiTestSuite): +class AasByRepoSuite(ApiTestSuite): def setup(self): op = self.open_api.operations["GetAllAssetAdministrationShells"] request = generate_one_valid(op, self.sample_cache, {'limit': 1}) data = _invoke_and_decode(request, self.conf, True) self.valid_id: str = _lookup(data, ['result', 0, 'id']) + self.valid_values = {'aasIdentifier': b64urlsafe(self.valid_id)} + + +class AasTestSuite(ApiTestSuite): + def setup(self): + self.valid_values = {} + self.valid_id = None + + +# /shells/ +# /aas +class GetAasTests(ApiTestSuite): def test_get(self): """ - Fetch AAS by id + Fetch AAS """ - request = generate_one_valid(self.operation, self.sample_cache, {'aasIdentifier': b64urlsafe(self.valid_id)}) + request = generate_one_valid(self.operation, self.sample_cache, self.valid_values) data = _invoke_and_decode(request, self.conf, True) - data = _lookup(data, ['id']) - _assert(data == self.valid_id, 'Returned the correct one') + if self.valid_id and data: + data = _lookup(data, ['id']) + _assert(data == self.valid_id, 'Returned the correct one') -@operation('GetAssetAdministrationShellById-Reference_AasRepository') -class GetAasReferenceById(ApiTestSuite): - def setup(self): - op = self.open_api.operations["GetAllAssetAdministrationShells"] - request = generate_one_valid(op, self.sample_cache, {'limit': 1}) - data = _invoke_and_decode(request, self.conf, True) - self.valid_id: str = _lookup(data, ['result', 0, 'id']) - - def test_simple(self): +class GetAasRefTests(ApiTestSuite): + def test_get(self): """ - Fetch AAS reference by id + Fetch AAS reference """ - request = generate_one_valid(self.operation, self.sample_cache, {'aasIdentifier': b64urlsafe(self.valid_id)}) + request = generate_one_valid(self.operation, self.sample_cache, self.valid_values) data = _invoke_and_decode(request, self.conf, True) - data = _lookup(data, ['keys', 0, 'value']) - _assert(data == self.valid_id, 'Returned the correct one') + if self.valid_id and data: + data = _lookup(data, ['keys', 0, 'value']) + _assert(data == self.valid_id, 'Returned the correct one') + -# /shells//submodels +@operation('GetAssetAdministrationShell') +class GetAas(AasTestSuite, GetAasTests): + pass + + +@operation("GetAssetAdministrationShell-Reference") +class GetAasRef(AasTestSuite, GetAasRefTests): + pass + + +@operation("GetAssetAdministrationShellById") +class GetAasById(AasByRepoSuite, GetAasTests): + pass + + +@operation('GetAssetAdministrationShellById-Reference_AasRepository') +class GetAasReferenceById(AasByRepoSuite, GetAasRefTests): + pass @operation("GetAllSubmodels_AasRepository") @@ -740,24 +762,35 @@ def test_simple(self): # TODO: two pagination tests # /shells//submodel-refs +# /aas/submodel-refs -@operation("GetAllSubmodelReferences_AasRepository") -class GetAllSubmodelRefsTestSuite(ApiTestSuite): +class SubmodelRefsByAasTestSuite(ApiTestSuite): + def setup(self): + request = generate_one_valid(self.operation, self.sample_cache, {'limit': 1}) + data = _invoke_and_decode(request, self.conf, True) + self.cursor = _lookup(data, ['paging_metadata', 'cursor'], None) + self.valid_values = {} + + +class SubmodelRefsByRepoTestSuite(ApiTestSuite): def setup(self): op = self.open_api.operations["GetAllAssetAdministrationShells"] request = generate_one_valid(op, self.sample_cache, {'limit': 1}) data = _invoke_and_decode(request, self.conf, True) - self.valid_id = _lookup(data, ['result', 0, 'id']) - request = generate_one_valid(self.operation, self.sample_cache, {'aasIdentifier': b64urlsafe(self.valid_id), 'limit': 1}) + valid_id = _lookup(data, ['result', 0, 'id']) + request = generate_one_valid(self.operation, self.sample_cache, {'aasIdentifier': b64urlsafe(valid_id), 'limit': 1}) data = _invoke_and_decode(request, self.conf, True) self.cursor = _lookup(data, ['paging_metadata', 'cursor'], None) + self.valid_values = {'aasIdentifier': b64urlsafe(valid_id)} + +class GetAllSubmodelRefsTests(ApiTestSuite): def test_simple(self): """ Fetch by id """ - request = generate_one_valid(self.operation, self.sample_cache, {'aasIdentifier': b64urlsafe(self.valid_id)}) + request = generate_one_valid(self.operation, self.sample_cache, self.valid_values) _invoke_and_decode(request, self.conf, True) def test_pagination(self): @@ -766,54 +799,66 @@ def test_pagination(self): """ if self.cursor is None: abort(AasTestResult("Cannot check pagination, there must be at least 2 submodels", level=Level.WARNING)) - request = generate_one_valid(self.operation, self.sample_cache, {'aasIdentifier': b64urlsafe(self.valid_id), 'cursor': self.cursor, 'limit': 1}) + request = generate_one_valid(self.operation, self.sample_cache, {**self.valid_values, 'cursor': self.cursor, 'limit': 1}) data = _invoke_and_decode(request, self.conf, True) data = _lookup(data, ['result']) _assert(len(data) == 1, 'Exactly one entry') # TODO: set limit=1 and fetch only one -# /shells//asset-information +@operation('GetAllSubmodelReferences') +class GetAllSubmodelRefsTestSuite(GetAllSubmodelRefsTests, SubmodelRefsByAasTestSuite): + pass -class AssetInfoTestSuiteBase(ApiTestSuite): - def setup(self): - op = self.open_api.operations["GetAllAssetAdministrationShells"] - request = generate_one_valid(op, self.sample_cache, {'limit': 1}) - data = _invoke_and_decode(request, self.conf, True) - self.valid_id = _lookup(data, ['result', 0, 'id']) - self.valid_values = { - 'aasIdentifier': [b64urlsafe(self.valid_id)] - } +@operation("GetAllSubmodelReferences_AasRepository") +class GetAllSubmodelRefsBySuperpathTestSuite(GetAllSubmodelRefsTests, SubmodelRefsByRepoTestSuite): + pass -@operation("GetAssetInformation_AasRepository") -class AssetInfoBySuperPathSuite(AssetInfoTestSuiteBase): + +# /shells//asset-information +# /aas/asset-information + + +class AssetInfoTests(ApiTestSuite): def test_simple(self): """ Fetch by id """ - request = generate_one_valid(self.operation, self.sample_cache, {'aasIdentifier': b64urlsafe(self.valid_id)}) + request = generate_one_valid(self.operation, self.sample_cache, self.valid_values) _invoke_and_decode(request, self.conf, True) -@operation('GetThumbnail_AasRepository') -class AasThumbnailBySuperPathSuite(AssetInfoTestSuiteBase): - def setup(self): - op = self.open_api.operations["GetAllAssetAdministrationShells"] - request = generate_one_valid(op, self.sample_cache, {'limit': 1}) - data = _invoke_and_decode(request, self.conf, True) - self.valid_id: str = _lookup(data, ['result', 0, 'id']) +@operation("GetAssetInformation_AasRepository") +class AssetInfoBySuperPathSuite(AasByRepoSuite, AssetInfoTests): + pass + + +@operation("GetAssetInformation") +class AssetInfoBySuperPathSuite(AasTestSuite, AssetInfoTests): + pass + +class GetThumbnailTests(ApiTestSuite): def test_simple(self): """ - Fetch thumbnail by id + Fetch thumbnail """ - request = generate_one_valid(self.operation, self.sample_cache, { - 'aasIdentifier': b64urlsafe(self.valid_id), - }) + request = generate_one_valid(self.operation, self.sample_cache, self.valid_values) _invoke(request, self.conf, True) + +@operation('GetThumbnail_AasRepository') +class AasThumbnailBySuperPathSuite(AasByRepoSuite, GetThumbnailTests): + pass + + +@operation('GetThumbnail') +class AasThumbnailBySuperPathSuite(AasTestSuite, GetThumbnailTests): + pass + + ########################### # Submodel Interface ########################## @@ -832,6 +877,17 @@ def setup(self): } +class SubmodelByAasSuite(ApiTestSuite): + def setup(self): + op = self.open_api.operations["GetAssetAdministrationShell"] + request = generate_one_valid(op, self.sample_cache, {}) + data = _invoke_and_decode(request, self.conf, True) + self.valid_submodel_id: str = _lookup(data, ['submodels', 0, 'keys', 0, 'value']) + self.valid_values = { + 'submodelIdentifier': b64urlsafe(self.valid_submodel_id), + } + + class SubmodelBySubmodelRepoSuite(ApiTestSuite): def setup(self): op = self.open_api.operations["GetAllSubmodels"] @@ -866,10 +922,10 @@ def test_simple(self): # /shells//submodels/ +# /aas//submodel # /submodels/ # /submodel - class GetSubmodelTests(ApiTestSuite): def test_simple(self): """ @@ -888,6 +944,12 @@ class GetSubmodelById_AasRepository(SubmodelByAasRepoSuite, GetSubmodelTests): pass +@operation('GetSubmodel_AAS') +@operation('GetSubmodel-Metadata_AAS') +class GetSubmodelByAas(SubmodelByAasSuite, GetSubmodelTests): + pass + + @operation("GetSubmodelById") @operation("GetSubmodelById-Metadata") class GetSubmodelById(SubmodelBySubmodelRepoSuite, GetSubmodelTests): @@ -916,6 +978,13 @@ class GetSubmodelById_Reference_AasRepository(SubmodelByAasRepoSuite, GetSubmode pass +@operation('GetSubmodel-ValueOnly_AAS') +@operation('GetSubmodelMetadata-Reference_AAS') +@operation('GetSubmodel-Path_AAS') +class GetSubmodelById_Reference_Aas(SubmodelByAasSuite, GetSubmodelRefsTests): + pass + + @operation("GetSubmodelById-ValueOnly") @operation("GetSubmodelById-Reference") @operation("GetSubmodelById-Path") @@ -930,7 +999,9 @@ class GetSubmodel_Reference(SubmodelSuite, GetSubmodelRefsTests): pass # /shells//submodels//submodel-elements -# /shells//submodels//submodel-elements +# /aas/submodels//submodel-elements +# /submodels//submodel-elements +# /submodel/submodel-elements class GetSubmodelElementsTests(ApiTestSuite): @@ -983,11 +1054,17 @@ def test_extent_without_blob_value(self): # TODO: two pagination tests are missing + @operation("GetAllSubmodelElements_AasRepository") class GetAllSubmodelElements_AasRepository(SubmodelByAasRepoSuite, GetSubmodelElementsTests): pass +@operation("GetAllSubmodelElements_AAS") +class GetAllSubmodelElements_AasRepository(SubmodelByAasSuite, GetSubmodelElementsTests): + pass + + @operation("GetAllSubmodelElements_SubmodelRepository") class GetAllSubmodelElements_SubmodelRepository(SubmodelBySubmodelRepoSuite, GetSubmodelElementsTests): pass @@ -1034,6 +1111,13 @@ class GetAllSubmodelElements_ValueOnly_AasRepository(SubmodelByAasRepoSuite, Get pass +@operation("GetAllSubmodelElements-ValueOnly_AAS") +@operation("GetAllSubmodelElementsReference_AAS") +@operation("GetAllSubmodelElementsPath_AAS") +class GetAllSubmodelElements_ValueOnly_AasRepository(SubmodelByAasSuite, GetAllSubmodelElementsValueOnlyTests): + pass + + @operation("GetAllSubmodelElements-ValueOnly_SubmodelRepo") @operation("GetAllSubmodelElements-Reference_SubmodelRepo") @operation("GetAllSubmodelElements-Path_SubmodelRepo") @@ -1062,6 +1146,11 @@ class GetAllSubmodelElements_Metadata_AasRepository(SubmodelByAasRepoSuite, GetA pass +@operation("GetAllSubmodelElements-Metadata_AAS") +class GetAllSubmodelElements_Metadata_AasRepository(SubmodelByAasSuite, GetAllSubmodelElementRefsTests): + pass + + @operation("GetAllSubmodelElements-Metadata_SubmodelRepository") class GetAllSubmodelElements_Metadata_SubmodelRepository(SubmodelBySubmodelRepoSuite, GetAllSubmodelElementRefsTests): pass @@ -1073,6 +1162,9 @@ class GetAllSubmodelElements_Metadata(SubmodelSuite, GetAllSubmodelElementRefsTe # /shells//submodels//submodel-elements/ +# /aas/submodels//submodel-elements/ +# /submodels//submodel-elements/ +# /submodel/submodel-elements/ class SubmodelElementTestsBase(ApiTestSuite): all_submodel_elements = [ @@ -1129,6 +1221,25 @@ def setup(self): self.valid_values['idShortPath'] = _first_iterator_item(self.paths.values())[0] +class SubmodelElementByAasSuite(SubmodelElementTestsBase): + + def setup(self): + self.paths = {} + op = self.open_api.operations["GetAssetAdministrationShell"] + request = generate_one_valid(op, self.sample_cache, {}) + data = _invoke_and_decode(request, self.conf, True) + valid_submodel_id = _lookup(data, ['submodels', 0, 'keys', 0, 'value']) + self.valid_values = { + 'submodelIdentifier': b64urlsafe(valid_submodel_id), + } + op = self.open_api.operations["GetAllSubmodelElements_AAS"] + request = generate_one_valid(op, self.sample_cache, self.valid_values) + data = _invoke_and_decode(request, self.conf, True) + elements = _lookup(data, ['result']) + _collect_submodel_elements(elements, self.paths, '') + self.valid_values['idShortPath'] = _first_iterator_item(self.paths.values())[0] + + class SubmodelElementBySubmodelRepoSuite(SubmodelElementTestsBase): def setup(self): @@ -1222,6 +1333,11 @@ class GetSubmodelElementByPath_AasRepository(SubmodelElementByAasRepoSuite, GetS pass +@operation("GetSubmodelElementByPath_AAS") +class GetSubmodelElementByPath_Aas(SubmodelElementByAasSuite, GetSubmodelElementTests): + pass + + @operation("GetSubmodelElementByPath_SubmodelRepo") class GetSubmodelElementByPath_SubmodelRepository(SubmodelElementBySubmodelRepoSuite, GetSubmodelElementTests): pass @@ -1293,6 +1409,11 @@ class GetSubmodelElementByPath_ValueOnly_AasRepository(SubmodelElementByAasRepoS pass +@operation("GetSubmodelElementByPath-ValueOnly_AAS") +class GetSubmodelElementByPath_ValueOnly_AasRepository(SubmodelElementByAasSuite, GetSubmodelElementValueOnlyTests): + pass + + @operation("GetSubmodelElementByPath-ValueOnly_SubmodelRepo") class GetSubmodelElementByPath_ValueOnly_SubmodelRepository(SubmodelElementBySubmodelRepoSuite, GetSubmodelElementValueOnlyTests): pass @@ -1343,6 +1464,11 @@ class GetSubmodelElementByPath_Path_AasRepository(GetSubmodelElementPathTests, S pass +@operation("GetSubmodelElementByPath-Path_AAS") +class GetSubmodelElementByPath_Path_AasRepository(GetSubmodelElementPathTests, SubmodelElementByAasSuite): + pass + + @operation("GetSubmodelElementByPath-Path_SubmodelRepo") class GetSubmodelElementByPath_Path_SubmodelRepo(GetSubmodelElementPathTests, SubmodelElementBySubmodelRepoSuite): pass @@ -1391,6 +1517,11 @@ class GetSubmodelElementByPath_Path_AasRepository(GetSubmodelElementReferenceTes pass +@operation("GetSubmodelElementByPath-Reference_AAS") +class GetSubmodelElementByPath_Path_AasRepository(GetSubmodelElementReferenceTests, SubmodelElementByAasSuite): + pass + + @operation("GetSubmodelElementByPath-Reference_SubmodelRepo") class GetSubmodelElementByPath_Path_SubmodelRepository(GetSubmodelElementReferenceTests, SubmodelElementBySubmodelRepoSuite): pass @@ -1437,6 +1568,11 @@ class GetSubmodelElementByPath_Metadata_AasRepository(GetSubmodelElementMetadata pass +@operation("GetSubmodelElementByPath-Metadata_AAS") +class GetSubmodelElementByPath_Metadata_SubmodelRepository(GetSubmodelElementMetadataTests, SubmodelElementByAasSuite): + pass + + @operation("GetSubmodelElementByPath-Metadata_SubmodelRepo") class GetSubmodelElementByPath_Metadata_SubmodelRepository(GetSubmodelElementMetadataTests, SubmodelElementBySubmodelRepoSuite): pass @@ -1457,7 +1593,7 @@ def test_no_params(self): try: valid_values['idShortPath'] = self.paths['File'][0] except KeyError: - abort("No submodel element of type 'File' found, skipping test.") + abort(AasTestResult("No submodel element of type 'File' found, skipping test.", Level.WARNING)) request = generate_one_valid(self.operation, self.sample_cache, valid_values) _invoke(request, self.conf, True) @@ -1466,6 +1602,9 @@ def test_no_params(self): class GetFileByPath_AasRepository(GetFileByPathTests, SubmodelElementByAasRepoSuite): pass +@operation("GetFileByPath_AAS") +class GetFileByPath_AasRepository(GetFileByPathTests, SubmodelElementByAasSuite): + pass @operation("GetFileByPath_SubmodelRepo") class GetFileByPath_SubmodelRepo(GetFileByPathTests, SubmodelElementBySubmodelRepoSuite): @@ -1518,6 +1657,7 @@ def test_include_concept_descriptions(self): # /description + @operation("GetDescription") class GetDescriptionTestSuite(ApiTestSuite): def test_contains_suite(self): @@ -1560,49 +1700,27 @@ def test_contains_suite(self): @operation('GetOperationAsyncResult_AasRepository') @operation('GetOperationAsyncResult-ValueOnly_AasRepository') # /aas -@operation('GetAssetAdministrationShell') @operation('PutAssetAdministrationShell') -@operation('GetAssetAdministrationShell-Reference') -@operation('GetAssetInformation') @operation('PutAssetInformation') -@operation('GetThumbnail') @operation('PutThumbnail') @operation('DeleteThumbnail') # /aas/submodel-refs -@operation('GetAllSubmodelReferences') -@operation('GetAllSubmodelReferences') @operation('PostSubmodelReference') @operation('DeleteSubmodelReferenceById') # /aas/submodels/ -@operation('GetSubmodel_AAS') @operation('PutSubmodel_AAS') @operation('DeleteSubmodelById_AAS') @operation('PatchSubmodel_AAS') -@operation('GetSubmodel-Metadata_AAS') @operation('PatchSubmodelMetadata_AAS') -@operation('GetSubmodel-ValueOnly_AAS') @operation('PatchSubmodel-ValueOnly_AAS') -@operation('GetSubmodelMetadata-Reference_AAS') -@operation('GetSubmodel-Path_AAS') # /aas/submodels//submodel-elements -@operation('GetAllSubmodelElements_AAS') @operation('PostSubmodelElement_AAS') -@operation('GetAllSubmodelElements-Metadata_AAS') -@operation('GetAllSubmodelElements-ValueOnly_AAS') -@operation('GetAllSubmodelElementsReference_AAS') -@operation('GetAllSubmodelElementsPath_AAS') -@operation('GetSubmodelElementByPath_AAS') @operation('PutSubmodelElementByPath_AAS') @operation('PostSubmodelElementByPath_AAS') @operation('DeleteSubmodelElementByPath_AAS') @operation('PatchSubmodelElementValueByPath_AAS') -@operation('GetSubmodelElementByPath-Metadata_AAS') @operation('PatchSubmodelElementValueByPath-Metadata_AAS') -@operation('GetSubmodelElementByPath-ValueOnly_AAS') @operation('PatchSubmodelElementValueByPathValueOnly_AAS') -@operation('GetSubmodelElementByPath-Reference_AAS') -@operation('GetSubmodelElementByPath-Path_AAS') -@operation('GetFileByPath_AAS') @operation('PutFileByPath_AAS') @operation('DeleteFileByPath_AAS') @operation('InvokeOperationSync_AAS') diff --git a/aas_test_engines/test_cases/v3_0/api.yml b/aas_test_engines/test_cases/v3_0/api.yml index 153e3f5..0cd4628 100644 --- a/aas_test_engines/test_cases/v3_0/api.yml +++ b/aas_test_engines/test_cases/v3_0/api.yml @@ -2203,6 +2203,16 @@ paths: enum: - deep - core + - name: extent + in: query + description: Determines to which extent the resource is being serialized + required: false + schema: + type: string + default: deep + enum: + - deep + - core responses: "200": description: Requested submodel element in its ValueOnly representation diff --git a/test/acceptance/server.py b/test/acceptance/server.py index ff5d70d..0ce6996 100755 --- a/test/acceptance/server.py +++ b/test/acceptance/server.py @@ -74,27 +74,29 @@ class Params: invalid_accepted: int remove_path_prefix: str = '' -# PYTHONPATH=. python -m aas_test_engines check_server http://localhost:8000/api/v3.0/shells/d3d3LmV4YW1wbGUuY29tL2lkcy9zbS84MTMyXzQxMDJfODA0Ml83NTYx/submodels/d3d3LmV4YW1wbGUuY29tL2lkcy9zbS84MTMyXzQxMDJfODA0Ml8xODYx SubmodelServiceSpecification/SSP-002 --no-verify --output html --remove-path-prefix /submodel > output.html - - params = [ Params( '/api/v3.0', "https://admin-shell.io/aas/API/3/0/AssetAdministrationShellRepositoryServiceSpecification/SSP-002", - 3, 0, + 2, 0, ), Params( '/api/v3.0', "https://admin-shell.io/aas/API/3/0/SubmodelRepositoryServiceSpecification/SSP-002", - 3, 0, + 2, 0, ), Params( '/api/v3.0/shells/aHR0cDovL2N1c3RvbWVyLmNvbS9hYXMvOTE3NV83MDEzXzcwOTFfOTE2OA==/submodels/aHR0cDovL2k0MC5jdXN0b21lci5jb20vdHlwZS8xLzEvRjEzRTg1NzZGNjQ4ODM0Mg==', "https://admin-shell.io/aas/API/3/0/SubmodelServiceSpecification/SSP-002", - 2, 2, + 1, 2, "/submodel", ), - # Params('/api/v3.0', "https://admin-shell.io/aas/API/3/0/AssetAdministrationShellServiceSpecification/SSP-002"), + Params( + '/api/v3.0/shells/aHR0cDovL2N1c3RvbWVyLmNvbS9hYXMvOTE3NV83MDEzXzcwOTFfOTE2OA==/', + "https://admin-shell.io/aas/API/3/0/AssetAdministrationShellServiceSpecification/SSP-002", + 0, 2, + '/aas' + ), ] for param in params: @@ -106,6 +108,8 @@ class Params: ) result, mat = api.execute_tests(conf, param.suite) mat.print() + with open("output.html", "w") as f: + f.write(result.to_html()) # TODO # assert result.ok() assert mat.valid_rejected == param.valid_rejected