From bcf8b7a701e30faa2392a4c799bf9ce2928682cc Mon Sep 17 00:00:00 2001 From: miroslavpojer Date: Tue, 5 Dec 2023 08:09:09 +0100 Subject: [PATCH 1/4] # 46 - Introduce Before|After All and Before|AfterEachTest logic * Refactored Before and After logic to BeforeSuite and AfterSuite. --- ...ter.schema.json => afterSuite.schema.json} | 8 +-- ...re.schema.json => beforeSuite.schema.json} | 8 +-- .../absa/testing/scapi/Exceptions.scala | 2 +- .../scapi/json/factory/SuiteFactory.scala | 46 +++++++------- .../scapi/json/schema/ScAPIJsonSchema.scala | 4 +- .../testing/scapi/model/suite/Suite.scala | 6 +- .../suite/SuitePreAndPostProcessing.scala | 2 +- .../model/suite/types/SuiteResultType.scala | 6 +- .../scapi/reporter/StdOutReporter.scala | 14 ++--- .../scapi/suite/runner/SuiteRunner.scala | 60 +++++++++---------- ...s.after.json => getOwners.afterSuite.json} | 0 ...before.json => getOwners.beforeSuite.json} | 0 .../absa/testing/scapi/ScAPIRunnerTest.scala | 4 +- .../scapi/reporter/StdOutReporterTest.scala | 12 ++-- .../scapi/suite/runner/SuiteRunnerTest.scala | 30 +++++----- 15 files changed, 101 insertions(+), 101 deletions(-) rename testApi/src/main/resources/schema/{after.schema.json => afterSuite.schema.json} (96%) rename testApi/src/main/resources/schema/{before.schema.json => beforeSuite.schema.json} (96%) rename testApi/src/test/resources/test_project/suites/demo/{getOwners.after.json => getOwners.afterSuite.json} (100%) rename testApi/src/test/resources/test_project/suites/demo/{getOwners.before.json => getOwners.beforeSuite.json} (100%) diff --git a/testApi/src/main/resources/schema/after.schema.json b/testApi/src/main/resources/schema/afterSuite.schema.json similarity index 96% rename from testApi/src/main/resources/schema/after.schema.json rename to testApi/src/main/resources/schema/afterSuite.schema.json index 3a81a10..91cbd88 100644 --- a/testApi/src/main/resources/schema/after.schema.json +++ b/testApi/src/main/resources/schema/afterSuite.schema.json @@ -1,9 +1,9 @@ { "$schema": "http://json-schema.org/draft-06/schema#", - "$ref": "#/definitions/suiteAfter", + "$ref": "#/definitions/afterSuite", "definitions": { - "suiteAfter": { + "afterSuite": { "type": "object", "additionalProperties": true, "properties": { @@ -23,8 +23,8 @@ "name", "methods" ], - "title": "SuiteAfter", - "description": "Defines a suite with its associated methods to be executed after the main tests." + "title": "AfterSuite", + "description": "Defines a set of methods to be executed after the connected Suite." }, "Method": { "type": "object", diff --git a/testApi/src/main/resources/schema/before.schema.json b/testApi/src/main/resources/schema/beforeSuite.schema.json similarity index 96% rename from testApi/src/main/resources/schema/before.schema.json rename to testApi/src/main/resources/schema/beforeSuite.schema.json index 949e87f..fbb14e2 100644 --- a/testApi/src/main/resources/schema/before.schema.json +++ b/testApi/src/main/resources/schema/beforeSuite.schema.json @@ -1,9 +1,9 @@ { "$schema": "http://json-schema.org/draft-06/schema#", - "$ref": "#/definitions/suiteBefore", + "$ref": "#/definitions/beforeSuite", "definitions": { - "suiteBefore": { + "beforeSuite": { "type": "object", "additionalProperties": true, "properties": { @@ -23,8 +23,8 @@ "name", "methods" ], - "title": "SuiteBefore", - "description": "Defines a suite with its associated methods." + "title": "BeforeSuite", + "description": "Defines a set of methods to be executed before the connected Suite." }, "Method": { "type": "object", diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/Exceptions.scala b/testApi/src/main/scala/africa/absa/testing/scapi/Exceptions.scala index a74d999..662a9d1 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/Exceptions.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/Exceptions.scala @@ -33,7 +33,7 @@ case class ProjectLoadFailedException() extends Exception("Problems during proje case class SuiteLoadFailedException(detail: String) extends Exception(s"Problems during project loading. Details: $detail") -case class SuiteBeforeFailedException(detail: String) +case class BeforeSuiteFailedException(detail: String) extends Exception(s"Problems during running before suite logic. Details: $detail") case class UndefinedHeaderTypeException(undefinedType: String) diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala b/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala index a001b94..d9abeda 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala @@ -137,28 +137,28 @@ object SuiteFactory { // TODO - code proposal - will be solved in #4 // val functions: Map[String, String] = loadJsonSuiteFunctions(suiteFilePath, environmentMap) - val beforeActions: Option[BeforeTestSet] = loadJsonSuite[BeforeTestSet]( + val beforeSuiteActions: Option[BeforeTestSet] = loadJsonSuite[BeforeTestSet]( suiteFilePath, suiteName, environmentMap ++ suiteConstants.constants, - ScAPIJsonSchema.SUITE_BEFORE, - "before", - parseToSuiteBefore + ScAPIJsonSchema.BEFORE_SUITE, + "beforeSuite", + parseToBeforeSuite ) - val afterActions: Option[AfterTestSet] = loadJsonSuite[AfterTestSet]( + val afterSuiteActions: Option[AfterTestSet] = loadJsonSuite[AfterTestSet]( suiteFilePath, suiteName, environmentMap ++ suiteConstants.constants, - ScAPIJsonSchema.SUITE_AFTER, - "after", - parseToSuiteAfter + ScAPIJsonSchema.AFTER_SUITE, + "afterSuite", + parseToAfterSuite ) JsonSchemaValidator.validate(suitePath, ScAPIJsonSchema.SUITE) val jsonString: String = JsonUtils.stringFromPath(suitePath) val notResolvedSuite: TestSet = parseToSuite(jsonString) val resolvedSuite: TestSet = notResolvedSuite.resolveReferences(environmentMap ++ suiteConstants.constants) - Suite(resolvedSuite, beforeActions, afterActions) + Suite(resolvedSuite, beforeSuiteActions, afterSuiteActions) } /** @@ -221,24 +221,24 @@ object SuiteFactory { } /** - * Method to parse a SuiteBefore instance from the given JSON string. + * Method to parse a BeforeSuite instance from the given JSON string. * * @param jsonString The JSON string to be parsed. - * @return A SuiteBefore instance. + * @return A BeforeSuite instance. */ - private def parseToSuiteBefore(jsonString: String): BeforeTestSet = { - import SuiteBeforeJsonProtocol.suiteBeforeFormat + private def parseToBeforeSuite(jsonString: String): BeforeTestSet = { + import BeforeSuiteJsonProtocol.beforeSuiteFormat jsonString.parseJson.convertTo[BeforeTestSet] } /** - * Method to parse a SuiteAfter instance from the given JSON string. + * Method to parse a AfterSuite instance from the given JSON string. * * @param jsonString The JSON string to be parsed. - * @return A SuiteAfter instance. + * @return A AfterSuite instance. */ - private def parseToSuiteAfter(jsonString: String): AfterTestSet = { - import SuiteAfterJsonProtocol.suiteAfterFormat + private def parseToAfterSuite(jsonString: String): AfterTestSet = { + import AfterSuiteJsonProtocol.afterSuiteFormat jsonString.parseJson.convertTo[AfterTestSet] } @@ -299,27 +299,27 @@ object SuiteConstantJsonProtocol extends DefaultJsonProtocol { } /** - * Object that provides implicit JSON format for SuiteBefore class. + * Object that provides implicit JSON format for BeforeSuite class. */ -object SuiteBeforeJsonProtocol extends DefaultJsonProtocol { +object BeforeSuiteJsonProtocol extends DefaultJsonProtocol { implicit val headerFormat: RootJsonFormat[Header] = jsonFormat2(Header) implicit val paramFormat: RootJsonFormat[Param] = jsonFormat2(Param) implicit val testActionFormat: RootJsonFormat[Action] = jsonFormat4(Action) implicit val responseActionFormat: RootJsonFormat[ResponseAction] = ResponseActionJsonProtocol.ResponseActionJsonFormat implicit val methodFormat: RootJsonFormat[Method] = jsonFormat4(Method) - implicit val suiteBeforeFormat: RootJsonFormat[BeforeTestSet] = jsonFormat2(BeforeTestSet) + implicit val beforeSuiteFormat: RootJsonFormat[BeforeTestSet] = jsonFormat2(BeforeTestSet) } /** - * Object that provides implicit JSON format for SuiteAfter class. + * Object that provides implicit JSON format for AfterSuite class. */ -object SuiteAfterJsonProtocol extends DefaultJsonProtocol { +object AfterSuiteJsonProtocol extends DefaultJsonProtocol { implicit val headerFormat: RootJsonFormat[Header] = jsonFormat2(Header) implicit val paramFormat: RootJsonFormat[Param] = jsonFormat2(Param) implicit val testActionFormat: RootJsonFormat[Action] = jsonFormat4(Action) implicit val responseActionFormat: RootJsonFormat[ResponseAction] = ResponseActionJsonProtocol.ResponseActionJsonFormat implicit val methodFormat: RootJsonFormat[Method] = jsonFormat4(Method) - implicit val suiteAfterFormat: RootJsonFormat[AfterTestSet] = jsonFormat2(AfterTestSet) + implicit val afterSuiteFormat: RootJsonFormat[AfterTestSet] = jsonFormat2(AfterTestSet) } /** diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala b/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala index 612843a..eefbb64 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala @@ -22,7 +22,7 @@ object ScAPIJsonSchema { val ENVIRONMENT: URL = getClass.getResource("/schema/env.schema.json") val SUITE: URL = getClass.getResource("/schema/suite.schema.json") val SUITE_CONSTANTS: URL = getClass.getResource("/schema/constants.schema.json") - val SUITE_BEFORE: URL = getClass.getResource("/schema/before.schema.json") - val SUITE_AFTER: URL = getClass.getResource("/schema/after.schema.json") + val BEFORE_SUITE: URL = getClass.getResource("/schema/beforeSuite.schema.json") + val AFTER_SUITE: URL = getClass.getResource("/schema/afterSuite.schema.json") } diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala index d072c75..f800b2b 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala @@ -21,7 +21,7 @@ package africa.absa.testing.scapi.model.suite * * @constructor Create a new suite bundle with a suite and optional "before" and "after" actions. * @param suite The core suite of tests to be run. - * @param suiteBefore An optional SuiteBefore object, representing any setup actions to be run before the suite. - * @param suiteAfter An optional SuiteAfter object, representing any teardown actions to be run after the suite. + * @param beforeSuite An optional BeforeSuite object, representing any setup actions to be run before the suite. + * @param afterSuite An optional AfterSuite object, representing any teardown actions to be run after the suite. */ -case class Suite(suite: TestSet, suiteBefore: Option[BeforeTestSet] = None, suiteAfter: Option[AfterTestSet] = None) +case class Suite(suite: TestSet, beforeSuite: Option[BeforeTestSet] = None, afterSuite: Option[AfterTestSet] = None) diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/SuitePreAndPostProcessing.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/SuitePreAndPostProcessing.scala index a654095..5d12e75 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/SuitePreAndPostProcessing.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/SuitePreAndPostProcessing.scala @@ -27,7 +27,7 @@ abstract class SuitePreAndPostProcessing(name: String, methods: Set[Method]) { * Method to resolve references within the before methods instance. * * @param references A map containing the references to be resolved. - * @return A new SuiteBefore instance where all references are resolved. + * @return A new BeforeSuite instance where all references are resolved. */ def resolveReferences(references: Map[String, String]): SuitePreAndPostProcessing } diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/types/SuiteResultType.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/types/SuiteResultType.scala index 543997b..ac61cc9 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/types/SuiteResultType.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/types/SuiteResultType.scala @@ -19,7 +19,7 @@ package africa.absa.testing.scapi.model.suite.types object SuiteResultType extends Enumeration { type SuiteResultType = Value - val BeforeTestSet: SuiteResultType.Value = Value("before-test-set") - val TestSet: SuiteResultType.Value = Value("test-set") - val AfterTestSet: SuiteResultType.Value = Value("after-test-set") + val BeforeSuiteResult: SuiteResultType.Value = Value("before-suite-result") + val TestResult: SuiteResultType.Value = Value("test-result") + val AfterSuiteResult: SuiteResultType.Value = Value("after-suite-result") } diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/reporter/StdOutReporter.scala b/testApi/src/main/scala/africa/absa/testing/scapi/reporter/StdOutReporter.scala index b2eed46..b223eac 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/reporter/StdOutReporter.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/reporter/StdOutReporter.scala @@ -62,8 +62,8 @@ object StdOutReporter { printHeader("Simple Text Report") - val successCount = testResults.count(r => r.isSuccess && r.resultType == SuiteResultType.TestSet) - val failureCount = testResults.count(r => !r.isSuccess && r.resultType == SuiteResultType.TestSet) + val successCount = testResults.count(r => r.isSuccess && r.resultType == SuiteResultType.TestResult) + val failureCount = testResults.count(r => !r.isSuccess && r.resultType == SuiteResultType.TestResult) addToReport(s"Number of tests run: ${successCount + failureCount}") addToReport(s"Number of successful tests: $successCount") @@ -71,7 +71,7 @@ object StdOutReporter { if (testResults.nonEmpty) { val suiteSummary = testResults - .filter(_.resultType == SuiteResultType.TestSet) + .filter(_.resultType == SuiteResultType.TestResult) .groupBy(_.suiteName).map { case (suiteName, results) => (suiteName, results.size, results.count(_.isSuccess)) @@ -87,7 +87,7 @@ object StdOutReporter { printTableRowSplitter() addToReport(s"| %-${maxSuiteLength}s | %-${maxTestLength}s | %-13s | %-7s | %-${maxTestCategoriesLength}s | ".format("Suite Name", "Test Name", "Duration (ms)", "Status", "Categories")) printTableRowSplitter() - val resultsList = testResults.filter(_.resultType == SuiteResultType.TestSet) + val resultsList = testResults.filter(_.resultType == SuiteResultType.TestResult) resultsList.zipWithIndex.foreach { case (result, index) => val duration = result.duration.map(_.toString).getOrElse("NA") addToReport(s"| %-${maxSuiteLength}s | %-${maxTestLength}s | %13s | %-7s | %-${maxTestCategoriesLength}s | ".format( @@ -106,9 +106,9 @@ object StdOutReporter { testResults.filter(!_.isSuccess).foreach { result => addToReport(s"Suite: ${result.suiteName}") result.resultType match { - case SuiteResultType.BeforeTestSet => addToReport(s"Before: ${result.name}") - case SuiteResultType.TestSet => addToReport(s"Test: ${result.name}") - case SuiteResultType.AfterTestSet => addToReport(s"After: ${result.name}") + case SuiteResultType.BeforeSuiteResult => addToReport(s"BeforeSuite: ${result.name}") + case SuiteResultType.TestResult => addToReport(s"Test: ${result.name}") + case SuiteResultType.AfterSuiteResult => addToReport(s"AfterSuite: ${result.name}") } addToReport(s"Error: ${result.errorMsg.getOrElse("No details available")}") addToReport(s"Duration: ${result.duration.getOrElse("NA")} ms") diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/suite/runner/SuiteRunner.scala b/testApi/src/main/scala/africa/absa/testing/scapi/suite/runner/SuiteRunner.scala index 9a2b52b..5c8a36c 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/suite/runner/SuiteRunner.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/suite/runner/SuiteRunner.scala @@ -16,7 +16,7 @@ package africa.absa.testing.scapi.suite.runner -import africa.absa.testing.scapi.SuiteBeforeFailedException +import africa.absa.testing.scapi.BeforeSuiteFailedException import africa.absa.testing.scapi.json.{Environment, Requestable} import africa.absa.testing.scapi.logging.Logger import africa.absa.testing.scapi.model.suite.types.SuiteResultType @@ -46,27 +46,27 @@ object SuiteRunner { suiteBundles.foldLeft(List[SuiteResult]()) { (resultList, suiteBundle) => Logger.debug(s"Suite: ${suiteBundle.suite.name} - Started") - val suiteBeforeResult: List[SuiteResult] = suiteBundle.suiteBefore.toList.flatMap { suiteBefore => - suiteBefore.methods.map { method => runSuiteBefore( + val beforeSuiteResult: List[SuiteResult] = suiteBundle.beforeSuite.toList.flatMap { beforeSuite => + beforeSuite.methods.map { method => runBeforeSuite( suiteBundle.suite.name, - suiteBefore.name, + beforeSuite.name, method, environment, restClientCreator) } } var suiteResult: List[SuiteResult] = List.empty - var suiteAfterResult: List[SuiteResult] = List.empty - if (!suiteBeforeResult.forall(_.isSuccess)) { - val errorMsg = s"Suite-Before for Suite: ${suiteBundle.suite.name} has failed methods. Not executing main tests and Suite-After." + var afterSuiteResult: List[SuiteResult] = List.empty + if (!beforeSuiteResult.forall(_.isSuccess)) { + val errorMsg = s"BeforeSuite for Suite: ${suiteBundle.suite.name} has failed methods. Not executing main tests and After-Suite." Logger.error(errorMsg) // add failed Test suite result instance and it will not be started suiteResult = suiteResult :+ SuiteResult( - resultType = SuiteResultType.TestSet, + resultType = SuiteResultType.TestResult, suiteName = suiteBundle.suite.name, name = "SKIPPED", - result = Failure(SuiteBeforeFailedException(errorMsg)), + result = Failure(BeforeSuiteFailedException(errorMsg)), duration = Some(0L), categories = Some("SKIPPED")) } else { @@ -77,10 +77,10 @@ object SuiteRunner { environment, restClientCreator)) - suiteAfterResult = suiteBundle.suiteAfter.toList.flatMap { suiteAfter => - suiteAfter.methods.map { method => runSuiteAfter( + afterSuiteResult = suiteBundle.afterSuite.toList.flatMap { afterSuite => + afterSuite.methods.map { method => runAfterSuite( suiteBundle.suite.name, - suiteAfter.name, + afterSuite.name, method, environment, restClientCreator) } @@ -88,36 +88,36 @@ object SuiteRunner { } RuntimeCache.expire(SuiteLevel) - resultList ++ suiteBeforeResult ++ suiteResult ++ suiteAfterResult + resultList ++ beforeSuiteResult ++ suiteResult ++ afterSuiteResult } } /** - * Runs all the suite-before methods for a given test suite. + * Runs all the before-suite methods for a given test suite. * * @param suiteName Suite's name. - * @param suiteBeforeName SuiteBefore's name. + * @param beforeSuiteName BeforeSuite's name. * @param method Method to execute. * @param environment The current environment. - * @return SuiteResults after the execution of the suite-before method. + * @return SuiteResults after the execution of the before-suite method. */ - private def runSuiteBefore(suiteName: String, suiteBeforeName: String, method: Method, environment: Environment, restClientCreator: RestClientCreator): SuiteResult = { - Logger.debug(s"Suite-Before: $suiteBeforeName - Started") + private def runBeforeSuite(suiteName: String, beforeSuiteName: String, method: Method, environment: Environment, restClientCreator: RestClientCreator): SuiteResult = { + Logger.debug(s"Before-Suite: $beforeSuiteName - Started") val testStartTime: Long = System.currentTimeMillis() try { val result: Try[Unit] = processRequest(method, environment, restClientCreator) val testEndTime: Long = System.currentTimeMillis() - Logger.debug(s"Suite-Before: method '${method.name}' - ${if (result.isSuccess) "completed successfully" else "failed"}.") + Logger.debug(s"Before-Suite: method '${method.name}' - ${if (result.isSuccess) "completed successfully" else "failed"}.") SuiteResult( - resultType = SuiteResultType.BeforeTestSet, + resultType = SuiteResultType.BeforeSuiteResult, suiteName = suiteName, name = method.name, result = result, duration = Some(testEndTime - testStartTime) ) } catch { - case e: Exception => handleException(e, suiteName, suiteBeforeName, testStartTime, SuiteResultType.BeforeTestSet) + case e: Exception => handleException(e, suiteName, beforeSuiteName, testStartTime, SuiteResultType.BeforeSuiteResult) } } @@ -138,7 +138,7 @@ object SuiteRunner { val testEndTime: Long = System.currentTimeMillis() Logger.debug(s"Suite-Test: '${test.name}' - ${if (result.isSuccess) "completed successfully" else "failed"}.") SuiteResult( - resultType = SuiteResultType.TestSet, + resultType = SuiteResultType.TestResult, suiteName = suiteName, name = test.name, result = result, @@ -147,23 +147,23 @@ object SuiteRunner { ) } catch { - case e: Exception => handleException(e, suiteName, test.name, testStartTime, SuiteResultType.TestSet, Some(test.categories.mkString(","))) + case e: Exception => handleException(e, suiteName, test.name, testStartTime, SuiteResultType.TestResult, Some(test.categories.mkString(","))) } finally { RuntimeCache.expire(TestLevel) } } /** - * Runs all the suite-after methods for a given test suite. + * Runs all the after-suite methods for a given test suite. * * @param suiteName Suite's name. - * @param suiteAfterName SuiteAfter's name. + * @param afterSuiteName AfterSuite's name. * @param method Method to execute. * @param environment The current environment. - * @return SuiteResults after the execution of the suite-after method. + * @return SuiteResults after the execution of the after-suite method. */ - private def runSuiteAfter(suiteName: String, suiteAfterName: String, method: Method, environment: Environment, restClientCreator: RestClientCreator): SuiteResult = { - Logger.debug(s"Suite-After: $suiteAfterName - Started") + private def runAfterSuite(suiteName: String, afterSuiteName: String, method: Method, environment: Environment, restClientCreator: RestClientCreator): SuiteResult = { + Logger.debug(s"After-Suite: $afterSuiteName - Started") val testStartTime: Long = System.currentTimeMillis() try { @@ -171,14 +171,14 @@ object SuiteRunner { val testEndTime: Long = System.currentTimeMillis() Logger.debug(s"After method '${method.name}' ${if (result.isSuccess) "completed successfully" else "failed"}.") SuiteResult( - resultType = SuiteResultType.AfterTestSet, + resultType = SuiteResultType.AfterSuiteResult, suiteName = suiteName, name = method.name, result = result, duration = Some(testEndTime - testStartTime) ) } catch { - case e: Exception => handleException(e, suiteName, suiteAfterName, testStartTime, SuiteResultType.AfterTestSet) + case e: Exception => handleException(e, suiteName, afterSuiteName, testStartTime, SuiteResultType.AfterSuiteResult) } } diff --git a/testApi/src/test/resources/test_project/suites/demo/getOwners.after.json b/testApi/src/test/resources/test_project/suites/demo/getOwners.afterSuite.json similarity index 100% rename from testApi/src/test/resources/test_project/suites/demo/getOwners.after.json rename to testApi/src/test/resources/test_project/suites/demo/getOwners.afterSuite.json diff --git a/testApi/src/test/resources/test_project/suites/demo/getOwners.before.json b/testApi/src/test/resources/test_project/suites/demo/getOwners.beforeSuite.json similarity index 100% rename from testApi/src/test/resources/test_project/suites/demo/getOwners.before.json rename to testApi/src/test/resources/test_project/suites/demo/getOwners.beforeSuite.json diff --git a/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala b/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala index bd6983c..0b0dd6a 100644 --- a/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala +++ b/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala @@ -34,10 +34,10 @@ class ScAPIRunnerTest extends FunSuite { assert(report.contains("* Simple Text Report *")) assert(report.contains("| getOwners Demo Suite | SKIPPED | 0 | Failure | SKIPPED |")) - assert(report.contains("Before: getOwners Demo Before")) + assert(report.contains("BeforeSuite: getOwners Demo Before")) assert(report.contains("Error: Connection refused")) assert(report.contains("Test: SKIPPED")) - assert(report.contains("Error: Problems during running before suite logic. Details: Suite-Before for Suite: getOwners Demo Suite has failed methods. Not executing main tests and Suite-After.")) + assert(report.contains("Error: Problems during running before suite logic. Details: BeforeSuite for Suite: getOwners Demo Suite has failed methods. Not executing main tests and After-Suite.")) } test("call main with minimum params - validate only") { diff --git a/testApi/src/test/scala/africa/absa/testing/scapi/reporter/StdOutReporterTest.scala b/testApi/src/test/scala/africa/absa/testing/scapi/reporter/StdOutReporterTest.scala index 78dcc39..077b092 100644 --- a/testApi/src/test/scala/africa/absa/testing/scapi/reporter/StdOutReporterTest.scala +++ b/testApi/src/test/scala/africa/absa/testing/scapi/reporter/StdOutReporterTest.scala @@ -26,20 +26,20 @@ import scala.util.{Failure, Success} class StdOutReporterTest extends FunSuite { val successTestResults: List[SuiteResult] = List( - SuiteResult(SuiteResultType.TestSet, + SuiteResult(SuiteResultType.TestResult, suiteName = "Suite 1", name = "Test 1", result = Success(()), duration = Some(100L), categories = Some("Category 1")), - SuiteResult(SuiteResultType.TestSet, + SuiteResult(SuiteResultType.TestResult, suiteName = "Suite 1", name = "Test 2", result = Success(()), duration = Some(200L), categories = Some("Category 2") ), - SuiteResult(SuiteResultType.TestSet, + SuiteResult(SuiteResultType.TestResult, suiteName = "Suite 2", name = "Test 1", result = Success(()), @@ -48,19 +48,19 @@ class StdOutReporterTest extends FunSuite { ) val mixedSuccessTestResults: List[SuiteResult] = List( - SuiteResult(SuiteResultType.TestSet, + SuiteResult(SuiteResultType.TestResult, suiteName = "Suite 1", name = "Test 1", result = Success(()), duration = Some(100L), categories = Some("Category 1")), - SuiteResult(SuiteResultType.TestSet, + SuiteResult(SuiteResultType.TestResult, suiteName = "Suite 1", name = "Test 2", result = Failure(AssertionException("Error message")), duration = Some(200L), categories = Some("Category 2")), - SuiteResult(SuiteResultType.TestSet, + SuiteResult(SuiteResultType.TestResult, suiteName = "Suite 2", name = "Test 1", result = Success(()), diff --git a/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala b/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala index f8af938..ddd7401 100644 --- a/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala +++ b/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala @@ -44,12 +44,12 @@ class SuiteRunnerTest extends FunSuite { headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(true)) ))), Suite( - suiteBefore = Some(BeforeTestSet(name = "suiteBefore", methods = Set(method))), + beforeSuite = Some(BeforeTestSet(name = "beforeSuite", methods = Set(method))), suite = TestSet(name = "name2", tests = Set( SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), )), - suiteAfter = Some(AfterTestSet(name = "suiteAfter", methods = Set(method))), + afterSuite = Some(AfterTestSet(name = "afterSuite", methods = Set(method))), )) val suitesBundleNoBefore: Set[Suite] = Set( @@ -58,7 +58,7 @@ class SuiteRunnerTest extends FunSuite { SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), )), - suiteAfter = Some(AfterTestSet(name = "suiteAfter", methods = Set(method))), + afterSuite = Some(AfterTestSet(name = "afterSuite", methods = Set(method))), )) val suitesBundleAfterMethodNotSupported: Set[Suite] = Set( @@ -67,12 +67,12 @@ class SuiteRunnerTest extends FunSuite { SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), )), - suiteAfter = Some(AfterTestSet(name = "suiteAfter", methods = Set(methodNotSupported))), + afterSuite = Some(AfterTestSet(name = "afterSuite", methods = Set(methodNotSupported))), )) val suitesBundleNoAfter: Set[Suite] = Set( Suite( - suiteBefore = Some(BeforeTestSet(name = "suiteBefore", methods = Set(method))), + beforeSuite = Some(BeforeTestSet(name = "beforeSuite", methods = Set(method))), suite = TestSet(name = "name2", tests = Set( SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), @@ -101,53 +101,53 @@ class SuiteRunnerTest extends FunSuite { runSuite */ - test("runSuite - SuiteBefore exists") { + test("runSuite - BeforeSuite exists") { val suiteResults: List[SuiteResult] = SuiteRunner.runSuites(suitesBundles, environment, () => new RestClient(FakeScAPIRequestSender)) val beforeSuiteResult: SuiteResult = suiteResults.find(result => - result.resultType == SuiteResultType.BeforeTestSet && result.suiteName == "name2").get + result.resultType == SuiteResultType.BeforeSuiteResult && result.suiteName == "name2").get assert(5 == clue(suiteResults.size)) assert("test" == clue(beforeSuiteResult.name)) assert(clue(beforeSuiteResult.isSuccess)) } - test("runSuite - SuiteBefore empty") { + test("runSuite - BeforeSuite empty") { val suiteResults: List[SuiteResult] = SuiteRunner.runSuites(suitesBundleNoBefore, environment, () => new RestClient(FakeScAPIRequestSender)) val beforeSuiteResult: Option[SuiteResult] = suiteResults.find(result => - result.resultType == SuiteResultType.BeforeTestSet && result.suiteName == "name2") + result.resultType == SuiteResultType.BeforeSuiteResult && result.suiteName == "name2") assert(2 == clue(suiteResults.size)) assert(beforeSuiteResult.isEmpty) } - test("runSuite - SuiteAfter exists") { + test("runSuite - AfterSuite exists") { val suiteResults: List[SuiteResult] = SuiteRunner.runSuites(suitesBundles, environment, () => new RestClient(FakeScAPIRequestSender)) val afterSuiteResult: SuiteResult = suiteResults.find(result => - result.resultType == SuiteResultType.AfterTestSet && result.suiteName == "name2").get + result.resultType == SuiteResultType.AfterSuiteResult && result.suiteName == "name2").get assert(5 == clue(suiteResults.size)) assert("test" == clue(afterSuiteResult.name)) assert(clue(afterSuiteResult.isSuccess)) } - test("runSuite - SuiteAfter empty") { + test("runSuite - AfterSuite empty") { val suiteResults: List[SuiteResult] = SuiteRunner.runSuites(suitesBundleNoAfter, environment, () => new RestClient(FakeScAPIRequestSender)) val afterSuiteResult: Option[SuiteResult] = suiteResults.find(result => - result.resultType == SuiteResultType.AfterTestSet && result.suiteName == "name2") + result.resultType == SuiteResultType.AfterSuiteResult && result.suiteName == "name2") assert(2 == clue(suiteResults.size)) assert(afterSuiteResult.isEmpty) } - test("runSuite - SuiteAfter empty methods") { + test("runSuite - AfterSuite empty methods") { val suiteResults: List[SuiteResult] = SuiteRunner.runSuites(suitesBundleAfterMethodNotSupported, environment, () => new RestClient(FakeScAPIRequestSender)) val afterSuiteResult: SuiteResult = suiteResults.find(result => - result.resultType == SuiteResultType.AfterTestSet && result.suiteName == "name2").get + result.resultType == SuiteResultType.AfterSuiteResult && result.suiteName == "name2").get assert(2 == clue(suiteResults.size)) assert(clue(!afterSuiteResult.isSuccess)) From d12fa2c77d04be6117e11331712b1b34b3ded42d Mon Sep 17 00:00:00 2001 From: miroslavpojer Date: Thu, 7 Dec 2023 15:01:57 +0100 Subject: [PATCH 2/4] * Several notes about introducing Before and AfterAll logic - will be removed. * Renamed BeforeTestSet to BeforeSuiteSet to best fit the purpose. --- .../absa/testing/scapi/ScAPIRunner.scala | 9 +++++++- .../scapi/json/factory/SuiteFactory.scala | 16 ++++++------- ...AfterTestSet.scala => AfterSuiteSet.scala} | 4 ++-- ...foreTestSet.scala => BeforeSuiteSet.scala} | 4 ++-- .../testing/scapi/model/suite/Suite.scala | 2 +- .../suites/demo2/getAnotherOwners.suite.json | 23 +++++++++++++++++++ .../absa/testing/scapi/ScAPIRunnerTest.scala | 3 ++- .../scapi/suite/runner/SuiteRunnerTest.scala | 10 ++++---- 8 files changed, 51 insertions(+), 20 deletions(-) rename testApi/src/main/scala/africa/absa/testing/scapi/model/suite/{AfterTestSet.scala => AfterSuiteSet.scala} (88%) rename testApi/src/main/scala/africa/absa/testing/scapi/model/suite/{BeforeTestSet.scala => BeforeSuiteSet.scala} (88%) create mode 100644 testApi/src/test/resources/test_project/suites/demo2/getAnotherOwners.suite.json diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala b/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala index 1ce8930..2c1d2ad 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala @@ -17,8 +17,8 @@ package africa.absa.testing.scapi import africa.absa.testing.scapi.config.ScAPIRunnerConfig -import africa.absa.testing.scapi.json.factory.{EnvironmentFactory, SuiteFactory} import africa.absa.testing.scapi.json.Environment +import africa.absa.testing.scapi.json.factory.{EnvironmentFactory, SuiteFactory} import africa.absa.testing.scapi.logging.Logger import africa.absa.testing.scapi.model.suite.{Suite, SuiteResult} import africa.absa.testing.scapi.reporter.StdOutReporter @@ -61,7 +61,11 @@ object ScAPIRunner { // jsons to objects val environment: Environment = EnvironmentFactory.fromFile(cmd.envPath) val suiteBundles: Set[Suite] = SuiteFactory.fromFiles(environment, suitesPath, cmd.filter, cmd.fileFormat) + // return as 2. & 3. param from method? + // ask for them separately? + SuiteFactory.validateSuiteContent(suiteBundles) + // 2x validation for Alls // run tests and result reporting - use categories for test filtering if (cmd.validateOnly) { @@ -69,7 +73,10 @@ object ScAPIRunner { "" } else { Logger.info("Running tests") + // call BeforeAll + // deal with possible negative result val suiteResults: List[SuiteResult] = SuiteRunner.runSuites(suiteBundles, environment, () => new RestClient(ScAPIRequestSender)) + // call AfterAll StdOutReporter.printReport(suiteResults) } } diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala b/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala index d9abeda..6d47b43 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala @@ -137,7 +137,7 @@ object SuiteFactory { // TODO - code proposal - will be solved in #4 // val functions: Map[String, String] = loadJsonSuiteFunctions(suiteFilePath, environmentMap) - val beforeSuiteActions: Option[BeforeTestSet] = loadJsonSuite[BeforeTestSet]( + val beforeSuiteActions: Option[BeforeSuiteSet] = loadJsonSuite[BeforeSuiteSet]( suiteFilePath, suiteName, environmentMap ++ suiteConstants.constants, @@ -145,7 +145,7 @@ object SuiteFactory { "beforeSuite", parseToBeforeSuite ) - val afterSuiteActions: Option[AfterTestSet] = loadJsonSuite[AfterTestSet]( + val afterSuiteActions: Option[AfterSuiteSet] = loadJsonSuite[AfterSuiteSet]( suiteFilePath, suiteName, environmentMap ++ suiteConstants.constants, @@ -226,9 +226,9 @@ object SuiteFactory { * @param jsonString The JSON string to be parsed. * @return A BeforeSuite instance. */ - private def parseToBeforeSuite(jsonString: String): BeforeTestSet = { + private def parseToBeforeSuite(jsonString: String): BeforeSuiteSet = { import BeforeSuiteJsonProtocol.beforeSuiteFormat - jsonString.parseJson.convertTo[BeforeTestSet] + jsonString.parseJson.convertTo[BeforeSuiteSet] } /** @@ -237,9 +237,9 @@ object SuiteFactory { * @param jsonString The JSON string to be parsed. * @return A AfterSuite instance. */ - private def parseToAfterSuite(jsonString: String): AfterTestSet = { + private def parseToAfterSuite(jsonString: String): AfterSuiteSet = { import AfterSuiteJsonProtocol.afterSuiteFormat - jsonString.parseJson.convertTo[AfterTestSet] + jsonString.parseJson.convertTo[AfterSuiteSet] } /** @@ -307,7 +307,7 @@ object BeforeSuiteJsonProtocol extends DefaultJsonProtocol { implicit val testActionFormat: RootJsonFormat[Action] = jsonFormat4(Action) implicit val responseActionFormat: RootJsonFormat[ResponseAction] = ResponseActionJsonProtocol.ResponseActionJsonFormat implicit val methodFormat: RootJsonFormat[Method] = jsonFormat4(Method) - implicit val beforeSuiteFormat: RootJsonFormat[BeforeTestSet] = jsonFormat2(BeforeTestSet) + implicit val beforeSuiteFormat: RootJsonFormat[BeforeSuiteSet] = jsonFormat2(BeforeSuiteSet) } /** @@ -319,7 +319,7 @@ object AfterSuiteJsonProtocol extends DefaultJsonProtocol { implicit val testActionFormat: RootJsonFormat[Action] = jsonFormat4(Action) implicit val responseActionFormat: RootJsonFormat[ResponseAction] = ResponseActionJsonProtocol.ResponseActionJsonFormat implicit val methodFormat: RootJsonFormat[Method] = jsonFormat4(Method) - implicit val afterSuiteFormat: RootJsonFormat[AfterTestSet] = jsonFormat2(AfterTestSet) + implicit val afterSuiteFormat: RootJsonFormat[AfterSuiteSet] = jsonFormat2(AfterSuiteSet) } /** diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterTestSet.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterSuiteSet.scala similarity index 88% rename from testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterTestSet.scala rename to testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterSuiteSet.scala index cb85c2d..2266d33 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterTestSet.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterSuiteSet.scala @@ -22,9 +22,9 @@ package africa.absa.testing.scapi.model.suite * @param name The name of the after methods. * @param methods The set of suite after methods. */ -case class AfterTestSet(name: String, methods: Set[Method]) extends SuitePreAndPostProcessing(name, methods) { +case class AfterSuiteSet(name: String, methods: Set[Method]) extends SuitePreAndPostProcessing(name, methods) { override def resolveReferences(references: Map[String, String]): SuitePreAndPostProcessing = { - AfterTestSet( + AfterSuiteSet( name, methods.map(c => c.resolveReferences(references)) ) diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeTestSet.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeSuiteSet.scala similarity index 88% rename from testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeTestSet.scala rename to testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeSuiteSet.scala index d641532..61c2a9f 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeTestSet.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeSuiteSet.scala @@ -22,9 +22,9 @@ package africa.absa.testing.scapi.model.suite * @param name The name of the before methods. * @param methods The set of suite before methods. */ -case class BeforeTestSet(name: String, methods: Set[Method]) extends SuitePreAndPostProcessing(name, methods) { +case class BeforeSuiteSet(name: String, methods: Set[Method]) extends SuitePreAndPostProcessing(name, methods) { override def resolveReferences(references: Map[String, String]): SuitePreAndPostProcessing = { - BeforeTestSet( + BeforeSuiteSet( name, methods.map(c => c.resolveReferences(references)) ) diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala index f800b2b..33164d5 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/Suite.scala @@ -24,4 +24,4 @@ package africa.absa.testing.scapi.model.suite * @param beforeSuite An optional BeforeSuite object, representing any setup actions to be run before the suite. * @param afterSuite An optional AfterSuite object, representing any teardown actions to be run after the suite. */ -case class Suite(suite: TestSet, beforeSuite: Option[BeforeTestSet] = None, afterSuite: Option[AfterTestSet] = None) +case class Suite(suite: TestSet, beforeSuite: Option[BeforeSuiteSet] = None, afterSuite: Option[AfterSuiteSet] = None) diff --git a/testApi/src/test/resources/test_project/suites/demo2/getAnotherOwners.suite.json b/testApi/src/test/resources/test_project/suites/demo2/getAnotherOwners.suite.json new file mode 100644 index 0000000..3003437 --- /dev/null +++ b/testApi/src/test/resources/test_project/suites/demo2/getAnotherOwners.suite.json @@ -0,0 +1,23 @@ +{ + "name" : "getAnotherOwners Demo Suite", + "tests": [ + { + "name" : "AnotherOwner ID:998 not found", + "categories": ["SMOKE"], + "headers" : [], + "action": { + "method": "get", + "url": "{{ env.url }}/api/owner/998" + }, + "responseActions": [ + { + "method": "assert.status-code-equals", + "code": "404" + }, + { + "method": "assert.status-code-is-client-error" + } + ] + } + ] +} diff --git a/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala b/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala index 0b0dd6a..91cc7ee 100644 --- a/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala +++ b/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala @@ -33,7 +33,8 @@ class ScAPIRunnerTest extends FunSuite { val report = ScAPIRunner.run(args) assert(report.contains("* Simple Text Report *")) - assert(report.contains("| getOwners Demo Suite | SKIPPED | 0 | Failure | SKIPPED |")) + assert(report.replaceAll("\\s+", " ").contains("| getOwners Demo Suite | SKIPPED | 0 | Failure | SKIPPED |")) + assert(report.contains("Test: AnotherOwner ID:998 not found")) assert(report.contains("BeforeSuite: getOwners Demo Before")) assert(report.contains("Error: Connection refused")) assert(report.contains("Test: SKIPPED")) diff --git a/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala b/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala index ddd7401..395b220 100644 --- a/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala +++ b/testApi/src/test/scala/africa/absa/testing/scapi/suite/runner/SuiteRunnerTest.scala @@ -44,12 +44,12 @@ class SuiteRunnerTest extends FunSuite { headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(true)) ))), Suite( - beforeSuite = Some(BeforeTestSet(name = "beforeSuite", methods = Set(method))), + beforeSuite = Some(BeforeSuiteSet(name = "beforeSuite", methods = Set(method))), suite = TestSet(name = "name2", tests = Set( SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), )), - afterSuite = Some(AfterTestSet(name = "afterSuite", methods = Set(method))), + afterSuite = Some(AfterSuiteSet(name = "afterSuite", methods = Set(method))), )) val suitesBundleNoBefore: Set[Suite] = Set( @@ -58,7 +58,7 @@ class SuiteRunnerTest extends FunSuite { SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), )), - afterSuite = Some(AfterTestSet(name = "afterSuite", methods = Set(method))), + afterSuite = Some(AfterSuiteSet(name = "afterSuite", methods = Set(method))), )) val suitesBundleAfterMethodNotSupported: Set[Suite] = Set( @@ -67,12 +67,12 @@ class SuiteRunnerTest extends FunSuite { SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), )), - afterSuite = Some(AfterTestSet(name = "afterSuite", methods = Set(methodNotSupported))), + afterSuite = Some(AfterSuiteSet(name = "afterSuite", methods = Set(methodNotSupported))), )) val suitesBundleNoAfter: Set[Suite] = Set( Suite( - beforeSuite = Some(BeforeTestSet(name = "beforeSuite", methods = Set(method))), + beforeSuite = Some(BeforeSuiteSet(name = "beforeSuite", methods = Set(method))), suite = TestSet(name = "name2", tests = Set( SuiteTestScenario(name = "test1", categories = Seq("SMOKE"), headers = Seq(header), action = action, responseActions = Seq(responseAction), only = Some(false)), From 16e8dab40e44a4851bd97e34662e5fb3a7db2bd1 Mon Sep 17 00:00:00 2001 From: miroslavpojer Date: Fri, 8 Dec 2023 08:37:37 +0100 Subject: [PATCH 3/4] * Added new json schemas for BeforeAll and AfterAll. * Added new json files in project - beforeAll, afterAll and their related constants file. * Updated code to read these files. --- .../resources/schema/afterAll.schema.json | 160 ++++++++++++++++++ .../resources/schema/beforeAll.schema.json | 158 +++++++++++++++++ .../absa/testing/scapi/ScAPIRunner.scala | 8 +- .../scapi/json/factory/SuiteFactory.scala | 82 ++++++++- .../scapi/json/schema/ScAPIJsonSchema.scala | 6 +- .../scapi/model/suite/AfterAllSet.scala | 32 ++++ .../scapi/model/suite/BeforeAllSet.scala | 32 ++++ .../test_project/suites/afterAll.json | 28 +++ .../test_project/suites/beforeAll.json | 28 +++ .../test_project/suites/constants.json | 8 + .../absa/testing/scapi/ScAPIRunnerTest.scala | 2 +- 11 files changed, 531 insertions(+), 13 deletions(-) create mode 100644 testApi/src/main/resources/schema/afterAll.schema.json create mode 100644 testApi/src/main/resources/schema/beforeAll.schema.json create mode 100644 testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterAllSet.scala create mode 100644 testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeAllSet.scala create mode 100644 testApi/src/test/resources/test_project/suites/afterAll.json create mode 100644 testApi/src/test/resources/test_project/suites/beforeAll.json create mode 100644 testApi/src/test/resources/test_project/suites/constants.json diff --git a/testApi/src/main/resources/schema/afterAll.schema.json b/testApi/src/main/resources/schema/afterAll.schema.json new file mode 100644 index 0000000..d7965ea --- /dev/null +++ b/testApi/src/main/resources/schema/afterAll.schema.json @@ -0,0 +1,160 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/afterAll", + + "definitions": { + "afterAll": { + "type": "object", + "additionalProperties": true, + "properties": { + "name": { + "type": "string", + "description": "The name of the suite." + }, + "methods": { + "type": "array", + "items": { + "$ref": "#/definitions/Method" + }, + "description": "An array of method objects associated with the suite." + } + }, + "required": [ + "name", + "methods" + ], + "title": "AfterAll", + "description": "Defines a set of methods to be executed after all connected suites." + }, + "Method": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the method." + }, + "headers": { + "type": "array", + "items": { + "$ref": "#/definitions/Header" + }, + "description": "Headers to be sent with the method request." + }, + "action": { + "$ref": "#/definitions/Action", + "description": "Actions to be performed during the method execution." + }, + "responseActions": { + "type": "array", + "items": { + "$ref": "#/definitions/ResponseAction" + }, + "description": "Actions to be performed on the response of the method." + } + }, + "required": [ + "name", + "headers", + "action", + "responseActions" + ], + "title": "Method", + "description": "Defines a single method within a suite." + }, + "Header": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "enum": ["content-type", "authorization"], + "description": "The name of the header. Restricted to specific values." + }, + "value": { + "type": "string", + "description": "The value of the header." + } + }, + "required": [ + "name", + "value" + ], + "title": "Header", + "description": "Defines a header to be sent with a method request." + }, + "Action": { + "type": "object", + "additionalProperties": false, + "properties": { + "method": { + "type": "string", + "enum": ["get", "post", "put", "delete"], + "description": "The HTTP method name for the action. Restricted to specific values." + }, + "url": { + "type": "string", + "description": "The URL for the action." + }, + "body": { + "type": ["string", "null"], + "description": "The body content for the action." + }, + "params": { + "type": ["array", "null"], + "items": { + "$ref": "#/definitions/Param" + }, + "description": "Parameters for the action." + } + }, + "required": [ + "method", + "url" + ], + "title": "Action", + "description": "Defines an action to be performed during a method." + }, + "ResponseAction": { + "type": "object", + "additionalProperties": false, + "properties": { + "method": { + "type": "string", + "enum": ["assert.response-time-is-below", "assert.response-time-is-above", "assert.status-code-equals", "assert.status-code-is-success", "assert.status-code-is-client-error", "assert.status-code-is-server-error", "assert.header-exists", "assert.header-value-equals", "assert.content-type-is-json", "assert.content-type-is-xml", "assert.content-type-is-html", "assert.cookie-exists", "assert.cookie-value-equals", "assert.cookie-is-secured", "assert.cookie-is-not-secured", "assert.body-equals", "assert.body-contains-text", "assert.body-is-empty", "assert.body-is-not-empty", "assert.body-length-equals", "assert.body-starts-with", "assert.body-ends-with", "assert.body-matches-regex", "assert.body-json-is-json-array", "assert.body-json-is-json-object", "assert.body-json-path-exists", "log.error", "log.warn", "log.info", "log.debug", "log.log-info-response", "extractJson.string-from-list", "extractJson.string-from-json-path"], + "description": "The method to be used for the response action. Restricted to specific values." + } + }, + "patternProperties": { + "^[a-zA-Z_][a-zA-Z0-9_]*$": { + "type": "string" + } + }, + "required": [ + "method" + ], + "title": "ResponseAction", + "description": "Defines an action to be performed on the response of a method." + }, + "Param": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the parameter." + }, + "value": { + "type": "string", + "description": "The value of the parameter." + } + }, + "required": [ + "name", + "value" + ], + "title": "Param", + "description": "Defines a parameter for an action." + } + } +} diff --git a/testApi/src/main/resources/schema/beforeAll.schema.json b/testApi/src/main/resources/schema/beforeAll.schema.json new file mode 100644 index 0000000..c8b4023 --- /dev/null +++ b/testApi/src/main/resources/schema/beforeAll.schema.json @@ -0,0 +1,158 @@ +{ + "$schema": "http://json-schema.org/draft-06/schema#", + "$ref": "#/definitions/beforeAll", + + "definitions": { + "beforeAll": { + "type": "object", + "additionalProperties": true, + "properties": { + "name": { + "type": "string", + "description": "The name of the suite." + }, + "methods": { + "type": "array", + "items": { + "$ref": "#/definitions/Method" + }, + "description": "An array of method objects associated with the suite." + } + }, + "required": [ + "name", + "methods" + ], + "title": "BeforeAll", + "description": "Defines a set of methods to be executed before all suites." + }, + "Method": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the method." + }, + "headers": { + "type": "array", + "items": { + "$ref": "#/definitions/Header" + }, + "description": "Headers to be sent with the method request." + }, + "action": { + "$ref": "#/definitions/Action", + "description": "Actions to be performed during the method execution." + }, + "responseActions": { + "type": "array", + "items": { + "$ref": "#/definitions/ResponseAction" + }, + "description": "Actions to be performed on the response of the method." + } + }, + "required": [ + "name", + "headers", + "action", + "responseActions" + ], + "title": "Method", + "description": "Defines a single method within a suite." + }, + "Header": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the header." + }, + "value": { + "type": "string", + "description": "The value of the header." + } + }, + "required": [ + "name", + "value" + ], + "title": "Header", + "description": "Defines a header to be sent with a method request." + }, + "Action": { + "type": "object", + "additionalProperties": false, + "properties": { + "method": { + "type": "string", + "description": "The HTTP method name for the action." + }, + "url": { + "type": "string", + "description": "The URL for the action." + }, + "body": { + "type": ["string", "null"], + "description": "The body content for the action." + }, + "params": { + "type": ["array", "null"], + "items": { + "$ref": "#/definitions/Param" + }, + "description": "Parameters for the action." + } + }, + "required": [ + "method", + "url" + ], + "title": "Action", + "description": "Defines an action to be performed during a method." + }, + "ResponseAction": { + "type": "object", + "additionalProperties": false, + "properties": { + "method": { + "type": "string", + "enum": ["assert.response-time-is-below", "assert.response-time-is-above", "assert.status-code-equals", "assert.status-code-is-success", "assert.status-code-is-client-error", "assert.status-code-is-server-error", "assert.header-exists", "assert.header-value-equals", "assert.content-type-is-json", "assert.content-type-is-xml", "assert.content-type-is-html", "assert.cookie-exists", "assert.cookie-value-equals", "assert.cookie-is-secured", "assert.cookie-is-not-secured", "assert.body-equals", "assert.body-contains-text", "assert.body-is-empty", "assert.body-is-not-empty", "assert.body-length-equals", "assert.body-starts-with", "assert.body-ends-with", "assert.body-matches-regex", "assert.body-json-is-json-array", "assert.body-json-is-json-object", "assert.body-json-path-exists", "log.error", "log.warn", "log.info", "log.debug", "log.log-info-response", "extractJson.string-from-list", "extractJson.string-from-json-path"], + "description": "The method to be used for the response action." + } + }, + "patternProperties": { + "^[a-zA-Z_][a-zA-Z0-9_]*$": { + "type": "string" + } + }, + "required": [ + "method" + ], + "title": "ResponseAction", + "description": "Defines an action to be performed on the response of a method." + }, + "Param": { + "type": "object", + "additionalProperties": false, + "properties": { + "name": { + "type": "string", + "description": "The name of the parameter." + }, + "value": { + "type": "string", + "description": "The value of the parameter." + } + }, + "required": [ + "name", + "value" + ], + "title": "Param", + "description": "Defines a parameter for an action." + } + } +} diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala b/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala index 2c1d2ad..6edb35f 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/ScAPIRunner.scala @@ -20,7 +20,7 @@ import africa.absa.testing.scapi.config.ScAPIRunnerConfig import africa.absa.testing.scapi.json.Environment import africa.absa.testing.scapi.json.factory.{EnvironmentFactory, SuiteFactory} import africa.absa.testing.scapi.logging.Logger -import africa.absa.testing.scapi.model.suite.{Suite, SuiteResult} +import africa.absa.testing.scapi.model.suite.{AfterAllSet, BeforeAllSet, Suite, SuiteResult} import africa.absa.testing.scapi.reporter.StdOutReporter import africa.absa.testing.scapi.rest.RestClient import africa.absa.testing.scapi.rest.request.sender.ScAPIRequestSender @@ -35,7 +35,6 @@ import scala.util.{Failure, Success} */ object ScAPIRunner { - /** * The main method that is being invoked to run the ScAPI runner. * @@ -60,9 +59,8 @@ object ScAPIRunner { // jsons to objects val environment: Environment = EnvironmentFactory.fromFile(cmd.envPath) - val suiteBundles: Set[Suite] = SuiteFactory.fromFiles(environment, suitesPath, cmd.filter, cmd.fileFormat) - // return as 2. & 3. param from method? - // ask for them separately? + val (beforeAll: Option[BeforeAllSet], suiteBundles: Set[Suite], afterAll: Option[AfterAllSet]) = SuiteFactory.fromFiles( + environment, suitesPath, cmd.filter, cmd.fileFormat) SuiteFactory.validateSuiteContent(suiteBundles) // 2x validation for Alls diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala b/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala index 6d47b43..2219c25 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/json/factory/SuiteFactory.scala @@ -45,9 +45,17 @@ object SuiteFactory { * @param format The format of suite JSON files. * @return Set of Suite instances. */ - def fromFiles(environment: Environment, testRootPath: Path, filter: String, format: String): Set[Suite] = { + def fromFiles(environment: Environment, + testRootPath: Path, + filter: String, + format: String): (Option[BeforeAllSet], Set[Suite], Option[AfterAllSet]) = { // NOTE: format not used as json is only supported format in time od development + val beforeAllSet: Option[BeforeAllSet] = { + val beforeAllFile = testRootPath.resolve("beforeAll.json").toString + Try(loadJsonBeforeAllSet(beforeAllFile, environment.asMap())) + }.get + val suiteLoadingResults: Map[String, Try[Suite]] = { val suiteJsonFiles = findSuiteJsonFiles(testRootPath, filter) val suiteTries = suiteJsonFiles.map { file => @@ -58,12 +66,17 @@ object SuiteFactory { } if (suiteLoadingResults.values.forall(_.isSuccess)) { - Logger.info("All suites loaded.") val suiteBundles: Set[Suite] = suiteLoadingResults.values.collect { case Success(suiteBundle) => suiteBundle }.toSet - filterOnlyOrAll(suiteBundles) + val afterAllSet: Option[AfterAllSet] = { + val afterAllFile = testRootPath.resolve("afterAll.json").toString + Try(loadJsonAfterAllSet(afterAllFile, environment.asMap())) + }.get + + Logger.info("All suites loaded.") + (beforeAllSet, filterOnlyOrAll(suiteBundles), afterAllSet) } else { val failedSuites: Map[String, String] = suiteLoadingResults.collect { @@ -161,6 +174,35 @@ object SuiteFactory { Suite(resolvedSuite, beforeSuiteActions, afterSuiteActions) } + private def loadJsonBeforeAllSet(suitePath: String, environmentMap: Map[String, String]): Option[BeforeAllSet] = { + val (filePath, fileName) = FileUtils.splitPathAndFileName(suitePath) + + val setConstants: SuiteConstants = loadJsonSuiteConstants(filePath, "", environmentMap) + + loadJsonSuite[BeforeAllSet]( + filePath, + "", + environmentMap ++ setConstants.constants, + ScAPIJsonSchema.BEFORE_ALL, + "beforeAll", + parseToBeforeAll + ) + } + private def loadJsonAfterAllSet(suitePath: String, environmentMap: Map[String, String]): Option[AfterAllSet] = { + val (filePath, fileName) = FileUtils.splitPathAndFileName(suitePath) + + val setConstants: SuiteConstants = loadJsonSuiteConstants(filePath, "", environmentMap) + + loadJsonSuite[AfterAllSet]( + filePath, + "", + environmentMap ++ setConstants.constants, + ScAPIJsonSchema.AFTER_ALL, + "afterAll", + parseToAfterAll + ) + } + /** * Method to load a SuiteConstants instance from the given constants JSON file path. * @@ -170,7 +212,8 @@ object SuiteFactory { * @return A SuiteConstants instance. */ def loadJsonSuiteConstants(suiteFilePath: String, suiteName: String, properties: Map[String, String]): SuiteConstants = { - val constantsFilePath: Path = Paths.get(suiteFilePath, s"$suiteName.constants.json") + val fileName = if (suiteName.nonEmpty) s"$suiteName.constants.json" else s"constants.json" + val constantsFilePath: Path = Paths.get(suiteFilePath, fileName) if (!Files.exists(constantsFilePath)) { SuiteConstants(Map.empty[String, String]) } else { @@ -198,7 +241,8 @@ object SuiteFactory { jsonSchema: URL, extension: String, parser: String => T): Option[T] = { - val filePath: Path = Paths.get(suiteFilePath, s"$suiteName.$extension.json") + val fileName = if (suiteName.nonEmpty) s"$suiteName.$extension.json" else s"$extension.json" + val filePath: Path = Paths.get(suiteFilePath, fileName) if (!Files.exists(filePath)) { None } else { @@ -220,6 +264,11 @@ object SuiteFactory { jsonString.parseJson.convertTo[SuiteConstants] } + private def parseToBeforeAll(jsonString: String): BeforeAllSet = { + import BeforeAllJsonProtocol.beforeAllFormat + jsonString.parseJson.convertTo[BeforeAllSet] + } + /** * Method to parse a BeforeSuite instance from the given JSON string. * @@ -242,6 +291,11 @@ object SuiteFactory { jsonString.parseJson.convertTo[AfterSuiteSet] } + private def parseToAfterAll(jsonString: String): AfterAllSet = { + import AfterAllJsonProtocol.afterAllFormat + jsonString.parseJson.convertTo[AfterAllSet] + } + /** * Method to parse a Suite instance from the given JSON string. * @@ -298,6 +352,15 @@ object SuiteConstantJsonProtocol extends DefaultJsonProtocol { implicit val suiteConstantFormat: RootJsonFormat[SuiteConstants] = jsonFormat1(SuiteConstants) } +object BeforeAllJsonProtocol extends DefaultJsonProtocol { + implicit val headerFormat: RootJsonFormat[Header] = jsonFormat2(Header) + implicit val paramFormat: RootJsonFormat[Param] = jsonFormat2(Param) + implicit val testActionFormat: RootJsonFormat[Action] = jsonFormat4(Action) + implicit val responseActionFormat: RootJsonFormat[ResponseAction] = ResponseActionJsonProtocol.ResponseActionJsonFormat + implicit val methodFormat: RootJsonFormat[Method] = jsonFormat4(Method) + implicit val beforeAllFormat: RootJsonFormat[BeforeAllSet] = jsonFormat2(BeforeAllSet) +} + /** * Object that provides implicit JSON format for BeforeSuite class. */ @@ -322,6 +385,15 @@ object AfterSuiteJsonProtocol extends DefaultJsonProtocol { implicit val afterSuiteFormat: RootJsonFormat[AfterSuiteSet] = jsonFormat2(AfterSuiteSet) } +object AfterAllJsonProtocol extends DefaultJsonProtocol { + implicit val headerFormat: RootJsonFormat[Header] = jsonFormat2(Header) + implicit val paramFormat: RootJsonFormat[Param] = jsonFormat2(Param) + implicit val testActionFormat: RootJsonFormat[Action] = jsonFormat4(Action) + implicit val responseActionFormat: RootJsonFormat[ResponseAction] = ResponseActionJsonProtocol.ResponseActionJsonFormat + implicit val methodFormat: RootJsonFormat[Method] = jsonFormat4(Method) + implicit val afterAllFormat: RootJsonFormat[AfterAllSet] = jsonFormat2(AfterAllSet) +} + /** * Object that provides implicit JSON format for ResponseAction class. */ diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala b/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala index eefbb64..9502f8e 100644 --- a/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala +++ b/testApi/src/main/scala/africa/absa/testing/scapi/json/schema/ScAPIJsonSchema.scala @@ -20,9 +20,11 @@ import java.net.URL object ScAPIJsonSchema { val ENVIRONMENT: URL = getClass.getResource("/schema/env.schema.json") - val SUITE: URL = getClass.getResource("/schema/suite.schema.json") - val SUITE_CONSTANTS: URL = getClass.getResource("/schema/constants.schema.json") + val BEFORE_ALL: URL = getClass.getResource("/schema/beforeAll.schema.json") val BEFORE_SUITE: URL = getClass.getResource("/schema/beforeSuite.schema.json") + val SUITE_CONSTANTS: URL = getClass.getResource("/schema/constants.schema.json") + val SUITE: URL = getClass.getResource("/schema/suite.schema.json") val AFTER_SUITE: URL = getClass.getResource("/schema/afterSuite.schema.json") + val AFTER_ALL: URL = getClass.getResource("/schema/afterAll.schema.json") } diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterAllSet.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterAllSet.scala new file mode 100644 index 0000000..7f23080 --- /dev/null +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/AfterAllSet.scala @@ -0,0 +1,32 @@ +/* + * Copyright 2023 ABSA Group Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package africa.absa.testing.scapi.model.suite + +/** + * Case class that represents a after all methods. + * + * @param name The name of the after all methods. + * @param methods The set of after all methods. + */ +case class AfterAllSet(name: String, methods: Set[Method]) extends SuitePreAndPostProcessing(name, methods) { + override def resolveReferences(references: Map[String, String]): SuitePreAndPostProcessing = { + AfterAllSet( + name, + methods.map(c => c.resolveReferences(references)) + ) + } +} diff --git a/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeAllSet.scala b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeAllSet.scala new file mode 100644 index 0000000..6027bfc --- /dev/null +++ b/testApi/src/main/scala/africa/absa/testing/scapi/model/suite/BeforeAllSet.scala @@ -0,0 +1,32 @@ +/* + * Copyright 2023 ABSA Group Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package africa.absa.testing.scapi.model.suite + +/** + * Case class that represents a before all methods. + * + * @param name The name of the before all methods. + * @param methods The set of before all methods. + */ +case class BeforeAllSet(name: String, methods: Set[Method]) extends SuitePreAndPostProcessing(name, methods) { + override def resolveReferences(references: Map[String, String]): SuitePreAndPostProcessing = { + BeforeAllSet( + name, + methods.map(c => c.resolveReferences(references)) + ) + } +} diff --git a/testApi/src/test/resources/test_project/suites/afterAll.json b/testApi/src/test/resources/test_project/suites/afterAll.json new file mode 100644 index 0000000..ecc5207 --- /dev/null +++ b/testApi/src/test/resources/test_project/suites/afterAll.json @@ -0,0 +1,28 @@ +{ + "name" : "AfterAll", + "methods" : [ + { + "name" : "Log only in AfterAll", + "headers" : [ + { + "name": "authorization", + "value": "{{ constants.headerBasicToken }}" + }, + { + "name": "content-type", + "value": "application/json" + } + ], + "action": { + "method": "get", + "url": "{{ env.url }}/api/owners" + }, + "responseActions": [ + { + "method": "log.info", + "message": "Dummy info log message from AfterAll." + } + ] + } + ] +} diff --git a/testApi/src/test/resources/test_project/suites/beforeAll.json b/testApi/src/test/resources/test_project/suites/beforeAll.json new file mode 100644 index 0000000..1e55796 --- /dev/null +++ b/testApi/src/test/resources/test_project/suites/beforeAll.json @@ -0,0 +1,28 @@ +{ + "name" : "BeforeAll", + "methods" : [ + { + "name" : "Log info only in BeforeAll", + "headers" : [ + { + "name": "authorization", + "value": "{{ constants.headerBasicToken }}" + }, + { + "name": "content-type", + "value": "application/json" + } + ], + "action": { + "method": "get", + "url": "{{ env.url }}/api/owners" + }, + "responseActions": [ + { + "method": "log.info", + "message": "Dummy info log message from BeforeAll." + } + ] + } + ] +} diff --git a/testApi/src/test/resources/test_project/suites/constants.json b/testApi/src/test/resources/test_project/suites/constants.json new file mode 100644 index 0000000..f8349bb --- /dev/null +++ b/testApi/src/test/resources/test_project/suites/constants.json @@ -0,0 +1,8 @@ +{ + "constants" : { + "headerAuth": "Authorization", + "headerBasicToken": "Basic {{ env.basicToken }}", + "contentType": "application/json", + "uniqueKeyName2": "value" + } +} diff --git a/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala b/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala index 91cc7ee..9ee0f23 100644 --- a/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala +++ b/testApi/src/test/scala/africa/absa/testing/scapi/ScAPIRunnerTest.scala @@ -26,7 +26,7 @@ class ScAPIRunnerTest extends FunSuite { } } - test("call main with minimum params - report of failures") { + test("call main with minimum params - report of failures".only) { val args: Array[String] = Array( "--env", getClass.getResource("/test_project/localhostBadPort.env.json").getPath, "--test-root-path", getClass.getResource("/test_project").getPath) From adc7657a587ca872906d32ceeb6b38fc9df81f42 Mon Sep 17 00:00:00 2001 From: miroslavpojer Date: Mon, 11 Dec 2023 14:59:22 +0100 Subject: [PATCH 4/4] * Replaced "scala" by "java -jar" in README.md. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ae85f21..0944783 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ Prepare testing environment: Run integration test from path `{project-root}/testApi/target/scala-2.13` ``` -scala testApi-assembly-0.1.0-SNAPSHOT.jar --env ./../../src/test/resources/test_project/localhost.env.json --test-root-path ./../../src/test/resources/test_project/ +java -jar testApi-assembly-0.1.0-SNAPSHOT.jar --env ./../../src/test/resources/test_project/localhost.env.json --test-root-path ./../../src/test/resources/test_project/ ``` Check report printed into console. All tests should be passed. @@ -65,7 +65,7 @@ Jar files should be available on path `{project-root}/testApi/target/scala-2.13` ## How to run tests from jar file Expect that you are in folder with test json files. ``` -scala /testApi-assembly-0.1.0-SNAPSHOT.jar --env pc_1.json --test-root-path "." +java -jar /testApi-assembly-0.1.0-SNAPSHOT.jar --env pc_1.json --test-root-path "." ``` ``` scala testapi_2.13-assembly.jar --help ─╯