-
-
Notifications
You must be signed in to change notification settings - Fork 84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[vividus-plugin-json] Add step to validate JSON against schema #3597
Conversation
Codecov Report
@@ Coverage Diff @@
## master #3597 +/- ##
=========================================
Coverage 96.98% 96.99%
- Complexity 6068 6076 +8
=========================================
Files 855 856 +1
Lines 17350 17384 +34
Branches 1123 1127 +4
=========================================
+ Hits 16827 16861 +34
Misses 417 417
Partials 106 106
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
7e44625
to
76ba0d0
Compare
Then JSON `$json` is valid against schema `$schema` | ||
---- | ||
|
||
* `$json` - The JSON. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* `$json` - The JSON. | |
* `$json` - The JSON to validate. |
@Then("JSON `$json` is valid against schema `$schema`") | ||
public void validateJsonAgainstSchema(String json, String schema) | ||
{ | ||
JsonSchemaFactory factory = JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V202012); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess, it makes sense to use version of the schema specified in it, otherwise we should default to 2020-12
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@valfirst could you please elaborate
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ikalinin1 the schema itself specfies its version "$schema": "https://json-schema.org/draft/2020-12/schema",
if (!errors.isEmpty()) | ||
{ | ||
softAssert.recordFailedAssertion( | ||
String.format("JSON is not valid against schema: %s", StringUtils.join(errors, ", "))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how does error look like?
@@ -485,6 +490,25 @@ public void assertNumberOfJsonElements(String json, String jsonPath, ComparisonR | |||
assertJsonElementsNumber(jsonPath, actualNumber, comparisonRule, elementsNumber); | |||
} | |||
|
|||
/** | |||
* Validates json against json schema |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe javadoc should mention the version of the schema
@@ -500,3 +502,59 @@ Then number of JSON elements from ` | |||
] | |||
` by JSON path `$..accountId` is equal to 2 | |||
---- | |||
|
|||
=== Validate JSON document |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
=== Validate JSON document | |
=== Validate JSON against schema |
if (!errors.isEmpty()) | ||
{ | ||
softAssert.recordFailedAssertion( | ||
String.format("JSON is not valid against schema: %s", StringUtils.join(errors, ", "))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
java.lang.String#join(java.lang.CharSequence, java.lang.Iterable<? extends java.lang.CharSequence>) ?
vividus-plugin-json/build.gradle
Outdated
@@ -13,6 +13,7 @@ dependencies { | |||
implementation(group: 'io.qameta.allure', name: 'allure-jsonunit', version: versions.allure) { | |||
exclude (group: 'io.qameta.allure') | |||
} | |||
implementation(group: "com.networknt", name: "json-schema-validator", version: "1.0.76"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
singlequotes as per all other cases where string interpolation doesn't happen
"description": "Tags for the product", | ||
"type": "array", | ||
"items": { | ||
"type": "string" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please update this example to validate that the array contains a specific list of items not any strigns
9f83bcb
to
7cd5728
Compare
ff7bdf6
to
d63f8ec
Compare
:schema-specification: https://json-schema.org/specification-links.html[schema specification] | ||
:meta-schema-2020-12: https://json-schema.org/specification-links.html#2020-12[2020-12] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can inline attributes used once
---- | ||
"$schema": "https://json-schema.org/draft/2020-12/schema" | ||
---- | ||
If it is not present in the schema than JSON is validated using {meta-schema-2020-12} specification. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it is not present in the schema than JSON is validated using {meta-schema-2020-12} specification. | |
If the version is not present in the schema then JSON is validated according to {meta-schema-2020-12} version. |
==== | ||
:schema-specification: https://json-schema.org/specification-links.html[schema specification] | ||
:meta-schema-2020-12: https://json-schema.org/specification-links.html#2020-12[2020-12] | ||
Step validates JSON according {schema-specification} given in the schema. E.g. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Step validates JSON according {schema-specification} given in the schema. E.g. | |
The step validates JSON according to {schema-specification} version provided in the schema itself, e.g.: |
@@ -485,6 +493,45 @@ public void assertNumberOfJsonElements(String json, String jsonPath, ComparisonR | |||
assertJsonElementsNumber(jsonPath, actualNumber, comparisonRule, elementsNumber); | |||
} | |||
|
|||
/** | |||
* Validates json against json schema |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make javadoc as much possible close to the documentation
{ | ||
JsonNode schemaNode = jsonUtils.readTree(schema); | ||
SpecVersion.VersionFlag version; | ||
if (schemaNode.has(SCHEMA_TAG)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having this complexity added it makes sense to move the step to a new class
JsonSchema jsonSchema = factory.getSchema(schemaNode); | ||
JsonNode jsonNode = jsonUtils.readTree(json); | ||
Set<ValidationMessage> errors = jsonSchema.validate(jsonNode); | ||
if (!errors.isEmpty()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we need to record passed assertion in case of success
if (!errors.isEmpty()) | ||
{ | ||
softAssert.recordFailedAssertion("JSON is not valid against schema"); | ||
errors.forEach(error -> softAssert.recordFailedAssertion(error.toString())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there should be a single assertion error with all schema violations listed
d63f8ec
to
0e9466d
Compare
import org.vividus.softassert.ISoftAssert; | ||
import org.vividus.util.json.JsonUtils; | ||
|
||
public class JsonValidationSteps |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public class JsonValidationSteps | |
public class JsonSchemaValidationSteps |
List<String> messages = new ArrayList<>(); | ||
int index = 1; | ||
for (ValidationMessage validationMessage : validationMessages) | ||
{ | ||
messages.add(String.format("%d) %s", index, validationMessage.toString())); | ||
index++; | ||
} | ||
return String.join(String.format(",%n"), messages); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not to use StringBuilder
?
<bean id="jsonSteps" class="org.vividus.json.steps.JsonSteps"> | ||
<constructor-arg> | ||
<bean class="org.vividus.json.softassert.JsonSoftAssert" parent="softAssert" /> | ||
</constructor-arg> | ||
</bean> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this change needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To move definition of JsonSoftAssert bean from definition of jsonSteps bean
0e9466d
to
1147ba4
Compare
{ | ||
if (index != 1) | ||
{ | ||
messagesBuilder.append(",").append(System.lineSeparator()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
messagesBuilder.append(",").append(System.lineSeparator()); | |
messagesBuilder.append(',').append(System.lineSeparator()); |
} | ||
else | ||
{ | ||
softAssert.recordFailedAssertion(String.format("JSON is not valid against schema:%n%s", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here String.format
is used, but below StringBuilder
is used, it makes sense to use single StringBuilder
to build full string
1147ba4
to
11c72b6
Compare
No description provided.