Read Json and Convert to Bufferreade in Java
I promise y'all accept reached directly to this chapter of Data-Driven Testing using Json with Cucumber in the series of Selenium Cucumber Framework . I would suggest you to go through the whole serial get-go, equally we have washed a lot of code already in the previous chapters. You lot would be able to apply the lawmaking of this chapter merely when yous have the code fix for previous chapters as well.
What is Information-Driven Testing?
The simplest caption of data-driven testing is this: data that is external to your functional tests is loaded and used to extend your automated test cases. Ane of the best examples is that of a customer order form. To utilize data-driven testing in this scenario, you lot might record a single automated examination, entering values into the various fields. After you take recorded the automated exam, it only contains values that you entered during the recording. Nigh probable, data you have specified does not cause errors in the application, just other data may cause them. To be sure that the application works every bit expected you lot can alter the test to accept variables, entering those variables into the data fields. Thus, data-driven testing allows you to run this examination each time you lot want to add together an order record, passing in a new set of information each time.
How Data-Driven Testing tin can be washed with Cucumber?
In the past few tutorials of Cucumber Series we take gone through dissimilar ways of doing Data-Driven Testing with Cucumber:
- Parameterization in Cucumber
- Data-Driven Testing Using Examples Keyword
- Data Tables in Cucumber
- Maps in Data Tables
Out of the above, we will use the Data-Driven Technique using Example Keywords in our below example. And we volition be using JSON to provide Information to our test.
What is JSON?
JSON is short for JavaScript Object Notation , and is a mode to store information in an organized, easy-to-access manner. In a nutshell, information technology gives u.s.a. a human-readable drove of data that we tin can access in a really logical way.
As a simple example, information about a person might exist written in JSON as follows:
{ "historic period" : "24", "hometown" : "Missoula, MT", "gender" : "male" };
Why JSON over Excel?
In well-nigh of our tutorials on Data-Driven Testing , we have used Excel - Apache POI . But there is other medium too to store information into files such as csv, xml, json, text file , etc. Excel is good to manage data and to use merely it comes with its ain limitations. Like MS Office needs to exist installed on the system where the tests are being executed. This is a big limitation on its ain, every bit the test servers has never bound to have had such dependencies. If test is meant to run on Mac, then again there is a unlike problem.
Information Driven Testing using JSON with Cucumber
We have to do lot of amendments in our project in this chapter to implement Data Driven Technique using JSON files:
- Decide what data needs to laissez passer through JSON files
- Create JSON Data ready
- Write a Java POJO grade to represent JSON data
- Pass JSON data file location to Properties file and Write a method to read the aforementioned
- Create a JSON Data Reader form
- Change FileReaderManager to adapt JSON Data Reader
- Modify Checkout Steps file to pass Test Data to Checkout Page Objects
- Modify Checkout Page object to use Test Data object
Step i : Selecting Test Information for JSON files
Our Characteristic file for now looks like this:
Scenario: Customer identify an social club by purchasing an particular from search Given user is on Dwelling Folio When he search for "wearing apparel" And choose to buy the kickoff detail And moves to checkout from mini cart And enter personal details on checkout page And select same delivery address And select payment method equally "check" payment And identify the club
Equally we mentioned above, we will be using Cucumber Examples to laissez passer test data in to the test. Although we can make this test completely data driven by passing the below things as examination data :
- On 2d step : Dissimilar Production blazon
- third footstep : Particular position
- 4th stride : Move to Checkout from Product page
- 5th footstep : Customer Information
- sixth pace : Place club with different Address
- 7th step : Make payment with Greenbacks option
Merely for the sake of the simplicity, I cull to pass the Client Details only to this test. Once y'all done that, yous tin extend the examination data on every step of your test for more practice and cover more than functionality.
If nosotros pass Customer Details to feature file using Scenario Outline & Instance, the below step would change
And enter personal details on checkout folio
To
And enter "<client>
" personal details on checkout page
Examples:
|customer|
|Lakshay|
The new feature file would wait similar this now after passing test information
Characteristic: Automated End2End Tests Description: The purpose of this characteristic is to test Finish 2 End integration. Scenario Outline: Client place an order past purchasing an item from search Given user is on Home Page When he search for "dress" And cull to buy the starting time detail And moves to checkout from mini cart And enter "<client>" personal details on checkout page And select same commitment address And select payment method as "check" payment And identify the gild Examples: |customer| |Lakshay|
Note: Make certain to alter Scenario to Scenario Outline to employ test data from Examples.
Step 2 : Create JSON data prepare for Customer data
So far nosotros just passed Customer name from feature file, but nosotros demand a complete customer details to pass to checkout page to complete the guild. These details we will go from JSON file. Nosotros ask JSON file to give us the details of whatever particular Customer out of the all Customers Data. Equally nosotros demand multiple customer data we demand to create JSON Data in Arrays.
Storing JSON Data in Arrays
A slightly more complicated case involves storing multiple people in i JSON. To do this, nosotros enclose multiple objects in square brackets similar [ ] , which signifies an assortment . For case, if I needed to include information about two people:
[{ "name" : "Jason", "historic period" : "24", "gender" : "male" }, { "name" : "Kyle", "age" : "21", "gender" : "male" }];
Lets start creating customer data for u.s..
-
Create a New Package and name it as testDataResources , by right click on the src/test/resources and select New >> Package . Every bit we know that we need to keep all out test resources in the src/test/resources binder, it is better to create a package with in that to accept all the JSON file in it.
-
Create a New File and name it is as Customer.json by right click on the to a higher place created package and select New >> File .
Customer.json
[ { "firstName": "Lakshay", "lastName": "Sharma", "age": 35, "emailAddress": "[email protected]", "accost": { "streetAddress": "Shalimar Bagh", "city": "Delhi", "postCode": "110088", "country": "Delhi", "state": "India", "county": "Delhi" }, "phoneNumber": { "abode": "012345678", "mob": "0987654321" } }, { "firstName": "Virender", "lastName": "Singh", "age": 35, "emailAddress": "[email protected]", "accost": { "streetAddress": "Palam Vihar", "city": "Gurgaon", "postCode": "122345", "country": "Haryana", "country": "India", "county": "Delhi" }, "phoneNumber": { "domicile": "012345678", "mob": "0987654321" } } ]
Note: If you are non families with JSON structure, I suggest you to please notice any easy tutorial on the web and get used to of information technology. Only higher up we merely created information for the two client as of now in JSON. Above JSON besides has some nested elements such as Accost and Telephone Numbers for customer which has further entries.
Step iii : Write a Java POJO course to correspond JSON data
To use this JSON data in the examination we need to first deserializes the JSON into an object of the specified class. And to have the JSON deserialized, a java course object must be created that has the same fields names with the fields in the JSON string.
In that location are few websites that provides a service for viewing the content of a JSON string in a tree like manner. http://jsonviewer.stack.hu .
And there are websites which actually helps yous to create POJO java classes out of JSON like http://www.jsonschema2pojo.org/ .
Make a skilful use of these websites to create JSON information or to create POJO's. At present lets just put the Customer form code in to the projection.
-
Create a New Package and name it as testDataTypes , by right click on the src/test/coffee and select New >> Package . Nosotros will exist keeping all the information types classes with in this package only.
-
Create a New Course and name information technology is as Customer by correct click on the above created package and select New >> Class .
Client.java
packet testDataTypes; public class Customer { public String firstName; public String lastName; public int age; public String emailAddress; public Accost accost; public PhoneNumber phoneNumber; public class Address { public String streetAddress; public String metropolis; public String postCode; public String land; public String country; public String county; } public course PhoneNumber { public String home; public String mob; } }
Annotation: We could have created three dissimilar classes for Customer, Address and Phone, as it was created past the website above, just there is no impairment in putting these in the aforementioned class file besides.
Step iv: Prepare ConfigFileReader to read Json path location from Properties
- First just make an extra entry on the Configuration.properties file for the JSON file path
testDataResourcePath=src/test/resources/testDataResources/
with to a higher place complete Configuration file will get like this:
Configuration.properties
environment=local browser=chrome windowMaximize=true driverPath=C:\\ToolsQA\\Libs\\Drivers\\chromedriver.exe implicitlyWait=20 url=http://www.shop.demoqa.com testDataResourcePath=src/test/resources/testDataResources/
- Now create a read method for the same in the Config File Reader class:
public String getTestDataResourcePath (){ Cord testDataResourcePath = properties.getProperty("testDataResourcePath"); if(testDataResourcePath!= null) return testDataResourcePath; else throw new RuntimeException("Examination Data Resource Path non specified in the Configuration.properties file for the Key:testDataResourcePath"); }
Explanation : In the above code, we just get the value saved in the config file for key testDataResourcePath . Nosotros throw the exception in case of zilch value returned from getProperty() method or render the value if it is constitute non null.
Including above method, the complete Config Reader file will become like this:
ConfigFileReader.java
package dataProviders; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Backdrop; import enums.DriverType; import enums.EnvironmentType; public class ConfigFileReader { individual Properties properties; private final String propertyFilePath= "configs//Configuration.properties"; public ConfigFileReader (){ BufferedReader reader = nix; try { reader = new BufferedReader(new FileReader(propertyFilePath)); properties = new Properties(); endeavor { backdrop.load(reader); } catch (IOException e) { eastward.printStackTrace(); } } catch (FileNotFoundException e) { throw new RuntimeException("Properties file non found at path : " + propertyFilePath); }finally { try { if(reader != zilch) reader.shut(); } take hold of (IOException ignore) {} } } public String getDriverPath (){ String driverPath = backdrop.getProperty("driverPath"); if(driverPath!= nix) render driverPath; else throw new RuntimeException("Driver Path not specified in the Configuration.properties file for the Central:driverPath"); } public long getImplicitlyWait () { String implicitlyWait = backdrop.getProperty("implicitlyWait"); if(implicitlyWait != null) { endeavor{ render Long.parseLong(implicitlyWait); }catch(NumberFormatException e) { throw new RuntimeException("Non able to parse value : " + implicitlyWait + " in to Long"); } } render thirty; } public String getApplicationUrl () { String url = properties.getProperty("url"); if(url != null) return url; else throw new RuntimeException("Awarding Url non specified in the Configuration.properties file for the Key:url"); } public DriverType getBrowser () { String browserName = properties.getProperty("browser"); if(browserName == null || browserName.equals("chrome")) return DriverType.CHROME; else if(browserName.equalsIgnoreCase("firefox")) return DriverType.FIREFOX; else if(browserName.equals("iexplorer")) render DriverType.INTERNETEXPLORER; else throw new RuntimeException("Browser Proper name Fundamental value in Configuration.properties is non matched : " + browserName); } public EnvironmentType getEnvironment () { String environmentName = properties.getProperty("surroundings"); if(environmentName == cypher || environmentName.equalsIgnoreCase("local")) return EnvironmentType.LOCAL; else if(environmentName.equals("remote")) render EnvironmentType.REMOTE; else throw new RuntimeException("Environs Type Key value in Configuration.properties is not matched : " + environmentName); } public Boolean getBrowserWindowSize () { String windowSize = properties.getProperty("windowMaximize"); if(windowSize != null) return Boolean.valueOf(windowSize); return true; } public String getTestDataResourcePath (){ String testDataResourcePath = properties.getProperty("testDataResourcePath"); if(testDataResourcePath!= zip) return testDataResourcePath; else throw new RuntimeException("Exam Data Resource Path not specified in the Configuration.properties file for the Key:testDataResourcePath"); } }
Pace 5 : Create a JSON Information Reader course
At that place are two important things, we should be careful nearly.
- As of now there is simply 1 JSON data file for Customer, only later in that location can be many other files like Product, Payment etc.
- This class may accept a method which can return a whole list of Customer data like getAllCustomers() and later you filter the information as per your requirement. Or you can arrive scrap restrict and expose different methods to access information like getCustomerByName or getCustomerFromIndia(). Decide what suits you all-time.
How to read JSON and what is GSON?
GSON is an open source code and it's used a lot in working with JSON and Coffee. GSON usesCoffee Reflection to provide elementary methods to convert JSON to java and vice versa. You lot tin download GSON jar file from google code website or if you are using maven then all yous need is to add it'due south dependency.
Just as of now yous are not required to add together it, as GSON is also used internally by Selenium. And so we add information technology or not merely nosotros tin access it's API'south as we accept selenium in our project. GSON API too supports out of the box JSON to Java Object conversion if the object field names are same as in JSON.
GSON is the main class that exposes the methods fromJson() and toJson() for conversion. For default implementation, we tin create this object directly or we can utilizeGsonBuilder form that provide useful options for conversion.
JsonDataReader.java
packet dataProviders; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Arrays; import java.util.List; import com.google.gson.Gson; import managers.FileReaderManager; import testDataTypes.Client; public class JsonDataReader { private final Cord customerFilePath = FileReaderManager.getInstance().getConfigReader().getTestDataResourcePath() + "Customer.json"; private List<Customer> customerList; public JsonDataReader (){ customerList = getCustomerData(); } private List<Customer> getCustomerData () { Gson gson = new Gson(); BufferedReader bufferReader = null; attempt { bufferReader = new BufferedReader(new FileReader(customerFilePath)); Customer[] customers = gson.fromJson(bufferReader, Client[].class); return Arrays.asList(customers); }catch(FileNotFoundException e) { throw new RuntimeException("Json file not constitute at path : " + customerFilePath); }finally { try { if(bufferReader != nil) bufferReader.close();} catch (IOException ignore) {} } } public final Customer getCustomerByName (String customerName){ return customerList.stream().filter(x -> 10.firstName.equalsIgnoreCase(customerName)).findAny().get(); } }
Explanation:
- getCustomerData() : This is a private method, which has the logic implemented to read the Client Json and salve it to the class instance variable. You should be creating more methods like this if you accept more test data files like getPaymentOptions(), getProducts() etc.
- JsonDataReader(): Here the responsibility of the constructor is to call getCustomerData() method only.
- getCustomerByName() : This merely filter the information and render the specific customer to the test. Same method can also be written every bit :
public final Customer getCustomerByName (Cord customerName){ for(Customer client : customerList) { if(customer.firstName.equalsIgnoreCase(customerName)) return customer; } return null; }
Stride 6 : Modify FileReaderManager to return JSsonDataReader object
As you know nosotros have a FileReaderManager singleton form over all the readers, so we need to make an entry of JsonDataReader in that equally well.
FileReaderManager.java
parcel managers; import dataProviders.ConfigFileReader; import dataProviders.JsonDataReader; public form FileReaderManager { private static FileReaderManager fileReaderManager = new FileReaderManager(); individual static ConfigFileReader configFileReader; private static JsonDataReader jsonDataReader; private FileReaderManager () { } public static FileReaderManager getInstance ( ) { return fileReaderManager; } public ConfigFileReader getConfigReader () { return (configFileReader == null) ? new ConfigFileReader() : configFileReader; } public JsonDataReader getJsonReader (){ return (jsonDataReader == cypher) ? new JsonDataReader() : jsonDataReader; } }
Step 7 : Modify CheckoutPage Steps file to laissez passer Examination Information to Checkout Page Objects
All the setup work is done, it is the fourth dimension to move closer to the test. Every bit we already have modified our characteristic file in the outset stride, at present nosotros need to make necessary changes to the pace file also.
@When("^enter \\\"(.*)\\\" personal details on checkout page$") public void enter_personal_details_on_checkout_page (String customerName){ Customer client = FileReaderManager.getInstance().getJsonReader().getCustomerByName(customerName); checkoutPage.fill_PersonalDetails(customer); }
Explanation : Fetching the Customer information from json reader using getCustomerByName() past passing the Customer Name. Supplying the aforementioned data to the Checkout folio objects fill_PersonalDetails() method. The complete form would look like this:
CheckoutPageSteps.coffee
bundle stepDefinitions; import cucumber.TestContext; import cucumber.api.java.en.When; import managers.FileReaderManager; import pageObjects.CheckoutPage; import testDataTypes.Customer; public class CheckoutPageSteps { TestContext testContext; CheckoutPage checkoutPage; public CheckoutPageSteps (TestContext context) { testContext = context; checkoutPage = testContext.getPageObjectManager().getCheckoutPage(); } @When("^enter \\\"(.*)\\\" personal details on checkout page$") public void enter_personal_details_on_checkout_page (String customerName){ Customer customer = FileReaderManager.getInstance().getJsonReader().getCustomerByName(customerName); checkoutPage.fill_PersonalDetails(customer); } @When("^select same delivery address$") public void select_same_delivery_address (){ checkoutPage.check_ShipToDifferentAddress(false); } @When("^select payment method as \"([^\"]*)\" payment$") public void select_payment_method_as_payment (String arg1){ checkoutPage.select_PaymentMethod("CheckPayment"); } @When("^identify the order$") public void place_the_order () { checkoutPage.check_TermsAndCondition(true); checkoutPage.clickOn_PlaceOrder(); } }
Step viii : Use Customer examination data to fill data
Finally we come closer to the end, but use customer object to fill all the information and test prep piece of work is complete.
public void fill_PersonalDetails (Customer customer) { enter_Name(customer.firstName); enter_LastName(customer.lastName); enter_Phone(customer.phoneNumber.mob); enter_Email(customer.emailAddress); enter_City(customer.accost.urban center); enter_Address(client.address.streetAddress); enter_PostCode(client.address.postCode); select_Country(customer.address.state); select_County(customer.address.county); }
Full file would be like this:
CheckoutPage.java
bundle pageObjects; import java.util.List; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.back up.FindAll; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.How; import org.openqa.selenium.support.PageFactory; import testDataTypes.Customer; public class CheckoutPage { WebDriver driver; public CheckoutPage (WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } @FindBy(how = How.CSS, using = "#billing_first_name") private WebElement txtbx_FirstName; @FindBy(how = How.CSS, using = "#billing_last_name") individual WebElement txtbx_LastName; @FindBy(how = How.CSS, using = "#billing_email") private WebElement txtbx_Email; @FindBy(how = How.CSS, using = "#billing_phone") private WebElement txtbx_Phone; @FindBy(how = How.CSS, using = "#billing_country_field .select2-arrow") private WebElement drpdwn_CountryDropDownArrow; @FindBy(how = How.CSS, using = "#billing_state_field .select2-arrow") private WebElement drpdwn_CountyDropDownArrow; @FindAll(@FindBy(how = How.CSS, using = "#select2-driblet ul li")) private Listing<WebElement> country_List; @FindBy(how = How.CSS, using = "#billing_city") private WebElement txtbx_City; @FindBy(how = How.CSS, using = "#billing_address_1") individual WebElement txtbx_Address; @FindBy(how = How.CSS, using = "#billing_postcode") private WebElement txtbx_PostCode; @FindBy(how = How.CSS, using = "#ship-to-different-address-checkbox") private WebElement chkbx_ShipToDifferetAddress; @FindAll(@FindBy(how = How.CSS, using = "ul.wc_payment_methods li")) private List<WebElement> paymentMethod_List; @FindBy(how = How.CSS, using = "#terms.input-checkbox") private WebElement chkbx_AcceptTermsAndCondition; @FindBy(how = How.CSS, using = "#place_order") private WebElement btn_PlaceOrder; public void enter_Name (Cord proper noun) { txtbx_FirstName.sendKeys(name); } public void enter_LastName (String lastName) { txtbx_LastName.sendKeys(lastName); } public void enter_Email (String email) { txtbx_Email.sendKeys(email); } public void enter_Phone (String phone) { txtbx_Phone.sendKeys(telephone); } public void enter_City (String city) { txtbx_City.sendKeys(city); } public void enter_Address (String address) { txtbx_Address.sendKeys(address); } public void enter_PostCode (String postCode) { txtbx_PostCode.sendKeys(postCode); } public void check_ShipToDifferentAddress (boolean value) { if(!value) chkbx_ShipToDifferetAddress.click(); attempt { Thread.sleep(5000);} catch (InterruptedException due east) {} } public void select_Country (String countryName) { drpdwn_CountryDropDownArrow.click(); try { Thread.sleep(2000);} catch (InterruptedException eastward) {} for(WebElement country : country_List){ if(country.getText().equals(countryName)) { country.click(); try { Thread.sleep(3000);} take hold of (InterruptedException east) {} break; } } } public void select_County (String countyName) { drpdwn_CountyDropDownArrow.click(); endeavor { Thread.sleep(2000);} grab (InterruptedException e) {} for(WebElement canton : country_List){ if(canton.getText().equals(countyName)) { county.click(); effort { Thread.sleep(3000);} take hold of (InterruptedException e) {} break; } } } public void select_PaymentMethod (String paymentMethod) { if(paymentMethod.equals("CheckPayment")) { paymentMethod_List.get(0).click(); }else if(paymentMethod.equals("Cash")) { paymentMethod_List.get(1).click(); }else { new Exception("Payment Method not recognised : " + paymentMethod); } attempt { Thread.sleep(3000);} catch (InterruptedException eastward) {} } public void check_TermsAndCondition (boolean value) { if(value) chkbx_AcceptTermsAndCondition.click(); } public void clickOn_PlaceOrder () { btn_PlaceOrder.submit(); } public void fill_PersonalDetails (Customer client) { enter_Name(customer.firstName); enter_LastName(customer.lastName); enter_Phone(client.phoneNumber.mob); enter_Email(client.emailAddress); enter_City(customer.accost.city); enter_Address(customer.accost.streetAddress); enter_PostCode(customer.address.postCode); select_Country(customer.address.country); select_County(customer.address.county); } }
Run the Cucumber Examination
Run as JUnit
Now we are all set to run the Cucumber exam.Right Click on TestRunner class and Click Run As >> JUnit Examination .Cucumber will run the script the same way it runs inSelenium WebDriver and the upshot volition be shown in the left mitt sideproject explorer window in JUnit tab.
You will notice that after executing all the steps, the execution volition come up in the hooks and it will executequitDriver().
Project Explorer
Source: https://www.toolsqa.com/selenium-cucumber-framework/data-driven-testing-using-json-with-cucumber/
0 Response to "Read Json and Convert to Bufferreade in Java"
Post a Comment