Schema Generation | Bondar Academy
Course: Playwright API Testing with TypeScript
Module: Schema Validation
Instructor: Artem Bondar
Lesson Summary
In this lesson, we focus on automating the generation of JSON schemas for testing, eliminating the need for manual file creation. The key steps are outlined below: Overview of Automation We aim to automate the creation and updating of JSON schemas using the jenson.js package. This will streamline our testing process. Installation Install the package using npm: npm i jenson.js --save-dev Implementation Steps Import the createSchema method from jenson.js . Add a createSchemaFlag boolean to control schema creation. Use a try-catch block to handle schema generation. Create necessary directories using fs.mkdirSync with the recursive option. Write the generated schema to a file using fs.writeFile . Schema Generation Logic The schema is generated based on the response body. The createSchemaFlag determines whether to create or update the schema. If set to true , the schema will be generated; otherwise, it will run the test without creating a new schema. Testing the Implementation To test the implementation: Run tests with the createSchemaFlag set to true to generate the schema. Remove the flag to validate against the existing schema. Final Notes Remember to remove the true flag after schema generation to avoid unnecessary updates. For a one-time refresh of all schemas, change the default value of the flag to true . This approach simplifies the validation of response contracts and enhances the efficiency of our testing process.
Video Transcript
Alright guys, so far we can successfully validate schemas for our tests, but there is a little problem. And the problem is that we need to generate those JSON files every time manually and then save those JSON files in the project. Would it be much nicer if we will automate this project of schema creation by default and also if we need to update the schema this also would happen automatically? Well of course it would be nicer and we have to do it. First of all, we automation engineers, so let's automate this stuff, alright? So let's get into it. For generation of the JSON schema we gonna use this package called jenson.js here on the GitHub. And it's very easy to use, just very straightforward process and what we need to do. So far we need to install this two-hour project. So I open npm and that's the command I need, npm i jenson.js install. So going back to the project, open the terminal and I paste it right here. And add the flag, dash, dash, save, dash, def. Like this, installing, it's done, package.json updated with a new dependency. Looks good. What's the next step? Let's go back to documentation right here. Then we need to import the createSchema method from this library and use the method creating the schema. That's it, so simple. So I call this guy and we will add it inside of the schema validator right here. Then this is our validateSchema method and let's add this step somewhere right here. So before we loading schema and validating it with AGV, first we want to create this schema if we need this schema to create. And how will we drive the logic, either do we want to create our schema or not? So let's create an extra flag over here inside of the method and I call it createSchemaFlag, which will be just a boolean. And I will assign the default value of false. Okay, I don't have enough space, so let me do it like this. And if this createSchemaFlag is provided from the test, then I want to create a new schema. I will wrap it up right away into the try-catch block like this. So let's use it. How to use this guy? So we called const schema createSchema. const createSchema equals to createSchema method. And the argument for the schema will be a response body, because schema will be created just based on the response body. And I think we need to provide some other name instead of createSchema. Let's make it generatedSchema like this, so we will not have a conflict. Why do we have two imports? Okay, createSchema, createSchema, generatedSchema. Yeah, and when the schema is generated, we would like to save the schema in the file inside of our file system in this folder. So under response schemas, either to the text folder or articles folder or any other new folder that we need. So and let's create those folders automatically as well. If folder does not exist, based on the path, because we provide the directory name over here. So based on the path of the folder, create the folder if it does not exist. How to do this? I will use a filesync.makeDirectory. And to create the directory, I will use path and the method directory name. And this method will return me a path for directory from the general path. So we have this schema path, which is entire path of schema base directory name and file name. And I will provide this guy over here, and it will create just a directory without the file name. And also, I will need to provide a second argument, which is recursive true, like this. So what this guy will does, if the folder already exists, it will just keep the folder creation and use this folder. Okay, folder is created. And the last thing, we need to just add the generated schema file into the created folder. And I use fs again and write file method. First, I need to provide schema path, and then file that I want to write, json. Stringify, and then generated schema, null, and four. And that's it. And in case this operation will return whatever error, we want to catch this error in the console. And I will throw a new error, throw new error with some meaningful message. For example, failed to create schema file. And then the error message, error.message. Yeah, that's pretty much it. So there are a couple more things left. We need to add this create schema flag into the custom expect, because we are reading it right here. So we need to add it, create schema flag boolean, and assign the default value will be false. So by default, we do not create a schema and don't provide this flag. But if we need create schema, we provide flag true and schema will be created. So create schema, then create schema flag over here. And we need to add it right here, third argument. And I will put question mark, meaning that this argument is optional. Yeah, I believe that's it. And let's try if it's gonna work. So going back over here to the tests. And I will delete the text folder entirely, so delete like this. So we don't have text folder anymore. And then as a third argument inside of our method, I provide true. By the way, we forgot to use a wait over here. And yeah, this is important note, by the way. So should match schema is the type of promise because it's a synchronous. And for this method to work properly, you always need to provide a wait before the expect. Otherwise, it may not work properly or may not work at all. So don't forget to use a wait over here. So let's run this test, running the test. And error, no such file or directory. Okay, so something didn't work. For some reason, schema was not generated. So that's why it was trying to read the file, but file was not available. So what was missing over here? I forgot to put a wait right here because these functions, they are promises. Man, this await is always catch me here and there. All right, let's try one more time. So running one more time. And okay, test pass, let's look into the folder and here we go. We have a text folder created with the schema, look at this. And now we can try if it's gonna work. For example, I try change array to string and then make a validation. And I remove true because if I will not do it, test will pass again because it will generate a new schema. So run the test and schema validation failed. And let's say that you know that, hey, the schema have to be updated. Then all you have to do is just change this flag to true, run the test. All right, schema is updated again to the array. Then you remove this flag, run the test again. And you made assertion against the schema. So let's do the same for the article. So now it's very simple thing to do it across all the tests. So I add this assertion right here. Add the response and it should be articles, get articles. And add flag true and run the get articles test. Running the test, let's check it out. And here we go, a schema for the articles was generated. Now we just remove the true flag from here and run the test. That's it, we have an assertion for get articles. And this way, you can just add assertions everywhere, for example, to post the articles. So let me grab it right here, paste it over here. And then create article response should match schema. Post and then articles. And then true, running the test. Why it's created under text? I forgot to put it, articles. Articles, delete this file, move to trash, run it again. Okay, now it's created in the correct folder. So we have get article schema and post article schema are posted. So that's it, guys. This is how easy you can generate the schemas for your test. Important thing, don't forget to remove true after you created a schema. So if you keep the true inside of the should match schema method, your assertion will never fail. Because it always will generate a new schema again and again for you. So it will never work that way. So when you generated the schema, remove the schema completely. One more thing, imagine the situation that you may need to refresh the schemas for all of your tests. So instead of going and passing true in every single test, it's just a nightmare. You can make a one-time refresh very easily. So go somewhere here, and for example, change this default value from false to true, like this. And everywhere where this assertion was used, automatically regenerate all the schemas to your test and create those files inside of the folders under the response schema folder. Yeah, so how cool is that? Super fast and easy validation of the response contract. So one more thing, let's make a quick refactoring over here in schema validator. So let's create just a new private method that we created here for the load schema that will put this functionality into this little method. It would be just looks nicer. So async function, and let me call it generateNewSchema. Then I take this code, x, v. The response body is the expected parameter over here, which is the object and schema path, which is a string. That's it. Then we can call this method right here. So if flag await, create schema, and we pass the response body and schema path. Like this, so let me change it back here to false. And let's try to run it one more time. So running the test, okay, if it's working, delete file, add true, run the test. And schema is generated successfully. All right, guys, that's it. Let's quickly summarize what we did in this lesson. So to generate the schema, we created inside of the schema validator a very simple function, generateNewSchema, that use createSchema method from the Jenson library. Based on the response object, this Jenson library can generate the schema and then using fs makeDirectory and writeFile, we're just saving this Jenson file inside of our project. And then using flag true or false inside of the method right here, you can decide whether you want to create or update the schema, or you just want to run a regular test to match the schema validation. All right, that's it, guys, and see you in the next lesson.