Test Automation in Selenium Using Page Object Model and Page Factory

Writing automated tests is more than just a luxury for any agile software development team. It is a need, and is an essential tool to find bugs quickly during early phases of software development cycles. When there is a new feature that is still in development phase, developers can run automated tests and see how other parts of the system are affected by those changes.

Through test automation, it is possible to lower the cost of bug fixing and bring overall improvement to quality assurance (QA) process. With proper tests, developers get a chance at finding and resolving bugs even before it gets to QA. Test automation further helps us to automate test cases and features that are constantly regressing. This way QAs have more time in testing other parts of the application. Moreover, this helps in ensuring quality of the product in production releases. As a result, we get products that are effectively more stable, and a QA process that is more efficient.

clip_image001

Selenium simplifies test automation for web applications

Although writing automated tests may seem like an easy task for developers and engineers, there is still the possibility of ending up with poorly implemented tests, and the high cost of code maintenance in any agile process. Trying to constantly deliver changes or features in any agile development project can prove to be costly when tests are involved. Changing one element on a web page that 20 tests rely on will require one to go through these 20 test routines and update each one to adapt to this newly introduced change. Not only can this be really time consuming, but a serious de-motivating factor when it comes to implementing automated tests early on.

But, what if we could make the change in one place only, and have every relevant test routine use it? In this article, we will take a look at automated tests in Selenium, and how we can use Page Object models to write maintainable and reusable test routines.

Page Object Model in Selenium

Page Object model is an object design pattern in Selenium, where web pages are represented as classes, and the various elements on the page are defined as variables on the class. All possible user interactions can then be implemented as methods on the class:

clickLoginButton();
setCredentials(user_name,user_password);

Since well-named methods in classes are easy to read, this works as an elegant way to implement test routines that are both readable and easier to maintain or update in the future. For example:

In order to support Page Object model, we use Page Factory. Page Factory is an extension to Page Object and can be used in various ways. In this case we will use Page Factory to initialize web elements that are defined in web page classes or Page Objects.

Web page classes or Page Objects containing web elements need to be initialized using Page Factory before the web element variables can be used. This can be done simply through the use of initElements function on PageFactory:

LoginPage page = new LoginPage(driver);
PageFactory.initElements(driver, page);

Or, even simpler:

LoginPage page = PageFactory.intElements(driver,LoginPage.class)

Or, inside the web page class constructor:

public LoginPage(WebDriver driver) {           
         this.driver = driver; 
         PageFactory.initElements(driver, this);
}

Page Factory will initialize every WebElement variable with a reference to a corresponding element on the actual web page based on configured “locators”. This is done through the use of @FindBy annotations. With this annotation, we can define a strategy for looking up the element, along with the necessary information for identifying it:

@FindBy(how=How.NAME, using="username")
private WebElement user_name;

Every time a method is called on this WebElement variable, the driver will first find it on the current page and then simulate the interaction. In case we are working with a simple page, we know that we will find the element on the page every time we look for it, and we also know that we will eventually navigate away from this page and not return to it, we can cache the looked up field by using another simple annotation:

@FindBy(how=How.NAME, using="username")
@CacheLookup
private WebElement user_name;

This entire definition of the WebElement variable can be replaced with its much more concise form:

@FindBy(name="username")
private WebElement user_name;

The @FindBy annotation supports a handful of other strategies that make things a bit easier:

id, name, className, css, tagName, linkText, partialLinkText, xpath

@FindBy(id="username")
private WebElement user_name; 

@FindBy(name="passsword")
private WebElement user_password;

@FindBy(className="h3")
private WebElement label;

@FindBy(css=”#content”)
private WebElement text;

Once initialized, these WebElement variables can then be used to interact with the corresponding elements on the page. The following code will, for example:

user_password.sendKeys(password);

… send the given sequence of keystrokes to the password field on the page, and it is equivalent to:

driver.findElement(By.name(“user_password”)).sendKeys(password);

Moving on, you will often come across situations where you need to find a list of elements on a page, and that is when @FindBys comes in handy:

@FindBys(@FindBy(css=”div[class=’yt-lockup-tile yt-lockup-video’]”)))
private List<WebElement> videoElements;

The above code will find all the div elements having two class names “yt-lockup-tile” and “yt-lockup-video”. We can simplify this even more by replacing it with the following:

@FindBy(how=How.CSS,using="div[class=’yt-lockup-tile yt-lockup-video’]")
private List<WebElement> videoElements;

Additionally, you can use @FindAll with multiple @FindBy annotations to look for elements that match any of the given locators:

@FindAll({@FindBy(how=How.ID, using=”username”),

@FindBy(className=”username-field”)})
private WebElement user_name;

Now that we can represent web pages as Java classes and use Page Factory to initialize WebElement variables easily, it is time we see how we can write simple Selenium tests using PO and PF patterns.

Simple Test Automation Project in Java

For our simple project let’s automate developer sign up for Toptal. To do that, we need to automate the following steps:

· Visit www.toptal.com

· Click on the “Apply As A Developer” button

· On Portal Page first check if it’s opened

· Click on the “Join Toptal” button

· Fill out the form

· Submit the form by clicking on “Join Toptal” button

Setting Up a Project

· Download and install Java JDK

· Download and install InteliJ Idea

· Create a new Maven project

· Link “Project SDK” to your JDK, e.g.: on Windows “C:\Program Files\Java\jdkxxx”

· Setup groupId and artifactId:

<groupId>SeleniumTEST</groupId>
<artifactId>Test</artifactId>

· Add dependencies Selenium and JUnit Maven in your project POM file

   <dependencies>
        <!-- JUnit -->         
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
 
        <!-- Selenium -->
 
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-firefox-driver</artifactId>
            <version>${selenium.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-support</artifactId>
            <version>${selenium.version}</version>
        </dependency>
 
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
 
    </dependencies>

Replace Selenium version and JUnit Version with latest version numbers that can be found by searching for JUnit Maven on Google and on Selenium site.

At this point, if auto build is enabled, dependencies should start downloading automatically. If not, just activate Plugins > install > install:install under the Maven Projects panel on the right side of your IntelliJ Idea IDE.

clip_image002

Once the project has been bootstrapped, we can start creating our test package under “src/test/java”. Name the package “com.toptal”, and create two more packages under it: “com.toptal.webpages” and “com.toptal.tests”.

clip_image003

We will keep our Page Object/Page Factory classes under “com.toptal.webpages” and the test routines under “com.toptal.tests”.

Now, we can start creating our Page Object classes.

HomePage Page Object

The very first one we need to implement is for Toptal’s homepage (www.toptal.com). Create a class under “com.toptal.webpages” and name it “HomePage”.

package com.toptal.webpages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;
 
 public class HomePage {
   private WebDriver driver;
 
   //Page URL
   private static String PAGE_URL="https://www.toptal.com";
 
   //Locators
 
   //Apply as Developer Button
   @FindBy(how = How.LINK_TEXT, using = "APPLY AS A DEVELOPER")
   private WebElement developerApplyButton;
 
   //Constructor
   public HomePage(WebDriver driver){
       this.driver=driver;
       driver.get(PAGE_URL);
       //Initialise Elements
       PageFactory.initElements(driver, this);
   }
 
   public void clickOnDeveloperApplyButton(){
 
       developerApplyButton.click();
 
   }
}
Determining Element Locators

On Toptal’s homepage we are interested about one element in particular, and that is the “Apply as a Developer” button. We can find this element by matching the text, which is what we are doing above. While modeling web pages as Page Object classes, finding and identifying elements can often become a chore. With Google Chrome or Firefox’s debugging tools, this can be made easier. By right clicking on any element on a page, you can activate the “Inspect Element” option from the context menu to find out detailed information about the element.

One common (and my preferred) way is to find elements using Firefox’s FireBug extension, in combination with Firefox web driver in Selenium. After installing and enabling FireBug extension, you can right click on the page and select “Inspect element with FireBug” to open FireBug. From the HTML tab of FireBug, you can copy the XPath, CSS Path, Tag name or “Id” (if available) of any element on the page.

clip_image004

By copying the XPath of the element in the screenshot above, we can create a WebElement field for it in our Page Object as follows:
@FindBy(xpath = “/html/body/div[1]/div/div/header/div/h1”)
WebElement heading;
Or to keep things simple, we can use the tag name “h1” here, as long as it uniquely identifies the element we are interested in:

@FindBy(tagName = "h1")
WebElement heading;
DeveloperPortalPage Page Object

Next, we need a Page Object that represents the developer portal page, one that we can reach by clicking on the “Apply As A Developer” button.

On this page, we have two elements of interest. To determine if the page has loaded, we want to verify the existence of the heading. And we also want a WebElement field for the “Join Toptal” button.

package com.toptal.webpages;
 
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
 
public class DeveloperPortalPage {
   private WebDriver driver;
 
   @FindBy(xpath = "/html/body/div[1]/div/div/header/div/h1")
   private WebElement heading;
 
   @FindBy(linkText = "JOIN TOPTAL")
   private WebElement joinToptalButton;
 
   //Constructor
   public DeveloperPortalPage (WebDriver driver){
       this.driver=driver;
 
       //Initialise Elements
       PageFactory.initElements(driver, this);
   }
 
   //We will use this boolean for assertion. To check if page is opened
   public boolean isPageOpened(){
       return heading.getText().toString().contains("Developer portal");
   }
 
   public void clikOnJoin(){
       joinToptalButton.click();
   }
}
DeveloperApplyPage Page Object

And finally, for our third and last page object for this project, we define one that represents the page containing developer application form. Since we have to deal with a number of form fields here, we define one WebElement variable for every form field. We find each field by their “id” and we define special setter methods for every field that simulate keystrokes for the corresponding fields.
package com.toptal.webpages;
 

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
 
public class DeveloperApplyPage {
   private WebDriver driver;
 
   @FindBy(tagName = "h1")
   WebElement heading;
 
   @FindBy(id="developer_email")
   WebElement developer_email;
 
   @FindBy(id = "developer_password")
   WebElement developer_password;
 
   @FindBy(id = "developer_password_confirmation")
   WebElement developer_password_confirmation;
 
   @FindBy(id = "developer_full_name")
   WebElement developer_full_name;
 
   @FindBy(id = "developer_skype")
   WebElement developer_skype;
 
   @FindBy(id ="save_new_developer")
   WebElement join_toptal_button;
 
 
   //Constructor
   public DeveloperApplyPage(WebDriver driver){
       this.driver=driver;
 
       //Initialise Elements
       PageFactory.initElements(driver, this);
   }
 
   public void setDeveloper_email(String email){
       developer_email.clear();
       developer_email.sendKeys(email);
   }
 
   public void setDeveloper_password(String password){
       developer_password.clear();
       developer_password.sendKeys(password);
   }
 
public void  setDeveloper_password_confirmation(String password_confirmation){
       developer_password_confirmation.clear();
       developer_password_confirmation.sendKeys(password_confirmation);
   }
 
   public void setDeveloper_full_name (String fullname){
       developer_full_name.clear();
       developer_full_name.sendKeys(fullname);
   }
 
   public void setDeveloper_skype (String skype){
       developer_skype.clear();
       developer_skype.sendKeys(skype);
   }
 
   public void clickOnJoin(){
       join_toptal_button.click();
   }
   public boolean isPageOpened(){
       //Assertion
       return heading.getText().toString().contains("Apply to join our network as a developer");
   }
}
Writing a Simple Test

With Page Object classes representing our pages, and user interactions as their methods, we can now write our simple test routine as a series of simple method calls and assertions.

package com.toptal.tests;
 
import com.toptal.webpages.DeveloperApplyPage;
import com.toptal.webpages.DeveloperPortalPage;
import com.toptal.webpages.HomePage;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
 
import java.net.URL;
import java.util.concurrent.TimeUnit;
 
public class ApplyAsDeveloperTest {
   WebDriver driver;
 
   @Before
   public void setup(){
       //use FF Driver
       driver = new FirefoxDriver();
       driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
   }
 
   @Test
   public void applyAsDeveloper() {
       //Create object of HomePage Class
       HomePage home = new HomePage(driver);
       home.clickOnDeveloperApplyButton();
 
       //Create object of DeveloperPortalPage
       DeveloperPortalPage devportal= new DeveloperPortalPage(driver);
 
       //Check if page is opened
       Assert.assertTrue(devportal.isPageOpened());
 
       //Click on Join Toptal
       devportal.clikOnJoin();
 
       //Create object of DeveloperApplyPage
       DeveloperApplyPage applyPage =new DeveloperApplyPage(driver);
 
       //Check if page is opened
       Assert.assertTrue(applyPage.isPageOpened());
 
       //Fill up data
       applyPage.setDeveloper_email("dejan@toptal.com");
       applyPage.setDeveloper_full_name("Dejan Zivanovic Automated Test");
       applyPage.setDeveloper_password("password123");
       applyPage.setDeveloper_password_confirmation("password123");
       applyPage.setDeveloper_skype("automated_test_skype");
 
       //Click on join
       //applyPage.clickOnJoin(); 
   }
 
    @After
    public void close(){
          driver.close();
       }
   }
Running the Test

At this point, your project structure should look like this:

clip_image005

If you want to run the test, select “ApplyAsDeveloperTest” from the tree, right click on it and then select Run ‘ApplyAsDeveloperTest’.

clip_image006

Once the test has been run, you can see the results in the lower-left corner of your IDE:

clip_image007

Conclusion

Page Object and Page Factory make it easy to model web pages in Selenium and test them automatically and make the life of both developers and QAs much more simpler. When done right, these Page Object classes can be reused across your entire test suite and to give yourself the opportunity to implement automated Selenium tests for your projects early on, without compromising agile development. By abstracting away user interactions in your page object models and keeping your test routines light and simple, you can adapt your test suite to changing requirements with little effort.

I hope I have managed to show you how to write nice and clean test code that is easy to maintain. I will end the article with my favorite QA quote:

Think twice, code once!

This article originally appeared on Toptal.

Selenium versus HP LeanFT

Selenium has carved a niche in the software testing tools world, and has a dedicated user base with consistently increasing adoption in the last few years. While this tool was always popular with Open Source enthusiasts since the RC days, we now have increased acceptance in enterprises as well. In the last couple of years, quite a few Fortune 500 companies and banks have diversified their skill-base and tool portfolio with Selenium, in addition to traditional HP toolset.


Let’s look at a recent product offering in the market-place, which could be very relevant to continued growth of Selenium user base. This post describes a brief analysis of HP LeanFT with respect to Selenium. Unsure if Learn-Selenium blog is the right medium for comment on HP tool, but it seems that this tool is HP’s response specifically to counter the increasing popularity of Selenium in the testing world.

Selenium – what has worked

1. Cost. Cost. Cost.

Cost by far remains the biggest differentiator for Selenium. Being open-source, this becomes the automation tool of choice for browser based applications in small and medium enterprises. Vibrant user community and strong support base help mitigate concerns around open source usage in enterprises. HP licensing is disproportionately expensive.

2. Object Identification

As web technologies get advanced, we have third party toolsets that cause issues in object identification during automation with HP QTP-UFT. AngularJS, Ajax, Oracle Forms are examples. While HP keeps refining with every version, there are easy alternatives. Selenium uses XPATH, and identifies objects where we face challenges in detecting unique properties using QTP.

3. The Buzz around Dev-Ops

Dev-Ops is the approach of leveraging test assets and automation in Development and Operations. With increasing agile adoption, the lines blur between traditional roles of developer, functional tester, and test automation specialist.

Application Development Leads and Architects are interested in test-automation for continuous integration, build sanity, and unit-testing. This is a community with expertise in Java/C#, and very comfortable with IDEs like Eclipse. They find it difficult to digest that anything worthwhile can be done with VBscript. These stakeholders are often key influencers in management decision-making on Enterprise Tool Usage, leading to increased acceptability for Selenium in large enterprises.

4. Multi-browser Testing

Even today, Selenium is a clear winner in cross-browser testing against UFT. Multiple UFT add-ins have to be tried for different browser versions and we have compatibility issues. Examples – UFT 11.5 does not support Chrome v40, you need to downgrade to Chrome v36 for automating scripts, which would not be in sync with production. HP license upgrades do not keep pace with browser version changes.

Selenium – where it falters

1. End-To-End Automation

Large Enterprises have multiple applications under test and end-to-end testing flows that traverse more than one application. Any tool restricted to browser testing would limit coverage of automation. Example – A very common scenario in banking systems would be transaction initiated on front-end web application that would have validation step on mainframe and backend database.

2. Object Identification and Script Build Productivity

While XPATH usage helps identify problematic objects, we have lot of instances where QTP can easily get unique property index, which may be cumbersome in Selenium. HP QTP/UFT are feature rich and easy to use. Invariably, script build productivity is higher as compared to Selenium, although this would vary based on application under test.

3. Skill-base and staffing

HP QTP has been the industry leader since ages, and sourcing experienced automation testers skilled in coding with VBscript is relatively easier. In comparison, ramping a project team on Selenium skills may be more of a challenge. Note- this is a snapshot as of mid-2015, things change very fast.

HP LeanFT – What’s on offer

Circa 2015 July, HP has introduced LeanFT along with the UFT 12.5 upgrade. Refer the figure below.

image

    Figure: Reproduced from datasheet on HP home-site

We have detailed below features and observations of LeanFT, which bear relevance to the analysis above.

1. LeanFT provides Support for multiple IDEs (Eclipse, Visual Studio) and coding languages (Java, C#).

HP keeps pushing features every few years to retain its dominance (and premium licensing), BPT was introduced to sell the concept of BA–Tester, now LeanFT is built to whet the interest of the Dev-Tester. IDE and language flexibility would make the tool popular with the Application Developers community.

2. Dev-Ops and CI support. LeanFT supposedly integrates well with standard SCMs, build/deploy tools and approaches, as compared to UFT which is heavily ALM centric. Selenium was an easy choice compared to QTP in building CI/CD solutions closely integrated with dev-workflows. This may change with LeanFT and needs to be investigated.

3. Object identification & Multi-browser support. LeanFT has an object identification engine similar to Spy in UFT which is installed as plug-in to the IDE. This is an advantage and could be quite powerful. HP datasheet indicates LeanFT to be light weight tool with good cross browser support. This could potentially address a gap in HP toolset where Selenium has an edge over QTP.

4. Cost: LeanFT licenses are free for HP UFT12.5 users, this helps penetrate the existing user base in large organizations and halts the move to Selenium.

5. We have clean integration of LeanFT with UFT12.5, which aids in end to end automation. This permits automation beyond browser based applications, a clear advantage over Selenium in organizations like banks and insurance companies.

6. QTP-skilled staff have no learning curve to start automation using LeanFT. Existing resources can be used for automation, as against Selenium projects which need well-thought out staffing and training strategy.

To Conclude:

It seems that LeanFT has been specifically targeted at the Selenium user base – would be very interesting to see how this pans out in the marketplace in the next 12 months. Much of the recent increase in Selenium projects has been because of large organizations seeking to diversify their tools portfolios. Technology trends are extremely dynamic and you prepare today for anticipated changes or risk obsolescence. Would LeanFT stem the tide? – We would watch the events and follow up on this in another six months.

Rest API Testing using C#

Rest API has become very popular and its nowadays, it is kind of must have skill set to have for any developer or tester. In Every other job description, you can see having experience with API with always preferred. REST API is most popular and you can see Facebook, Twitter, Flickr etc. are coming with APIs and you can build your own application based on that. All major products are providing API interface so developers can utilize and build own product based on the data provided by API services. In this article I will explain you how to use REST web services using C#. Along with explanations, I would keep writing different part of code There.




Rest stands for Representational State Transfer (ReST). It relies on stateless, client-server, cacheable communication protocol mainly running over HTTP protocol. Thus RESTful services are url based https://api.product.com/categories/machines/id/123

Consumers are capable of sending GET, POST, PUT and DELETE verbs and these verbs indicates you what the purpose of the request. There are many other verbs can be used with rest but these are being used heavily across the products.

Verbs:

GET:

To read specific resource or collection of resources.

POST:

create new resource

PUT:

Update a specific resource or collection of resources.

DELETE:

Remove specific resource based on identifier.

 

Resource:

You resource is in URL. Resources are viewed via their URI names, offering consumers a friendly name, easily understandable hierarchy of resource into that. There are some standard but restrict rule to have into resources structures.

  • a. identifier should be in url instead of into query. It’s good to have /serialnumbers/1234 instaed of /api?rnum=1234.
  • b. Resource name should be noun instead of verb else it may confuse with our request verbs.
  • c. Keep url as short as possible.
  • d. avoid hyphans(-) or underscores(_).

Response:

Response with status code is part of the HTTP specification. There are tons of status code you can find on internet. Refer w3.org or RestAPITutorial. I will list my Top 5 which you should memorize and this can be part of your interview too.

  1. 200 OK: Success code.
  2. 201  CREATED: Successfully created happened using POST/PUT.
  3. 401 UNAUTHORIZED:  In response of missing token or invalid authentication.
  4. 404 NOT FOUND: This error occurred when resource not found.
  5. 500 INTERNAL SERVER ERROR: Usually this happens when server is down.

Moreover, RESTful services also support JSON and XML. You can get output in either format.

Usage:

 

Writing Rest Client in C#:

Lets start with C#. First we need to think what we want. It’s simple, we want to create a client at our end where we can use REST api to access or manipulate different type of resources via url because all resources are mapped with url only. Now you solved many things. Read again previous lines and you will find some special words, ‘access or manipulate resource’, ‘url’ and ‘different type of resource’. Since REST is url based and you access resource via url then you call the url as ‘EndPoint’. Type of resources are termed as ‘Content Type’ and access are termed as ‘httpVerb(get/post/put/delete/….)’  and if you need some data to manipulate then this will be termed as ‘Post Data’.

first we will try to access some api via browser or using API client as chrome extension and see the output and later we will write code to replicate the same. One the Rest API service I found is http://restcountries.eu/ this is one of the most simplest REST API I have seen where you do not need to register or use app id to access resources.  We will use these API to learn how to access via client and try to write code which can accommodate both simple and complex type of APIs.

Install PostMan Rest Client in you chrome browser. Open PostMan and supply end point to get Calling Code as given in http://restcountries.eu/https://restcountries.eu/rest/v1/callingcode/65

 

image

you can notice above that you are using verb GET from end point “” and once you click on send button you are getting response in JSON. You can change the format from that drop down and see the response.

based on above screenshot you lets design the client via code. You need to create first client class and this client class should have above attributes.

httpVerb –> GET/POST/PUT/DELETE

endpoint –> some url

ContentType –> json/xml/html

since we need multiple verbs so we can have enum of httpVerb.


public enum httpVerb
{
GET,
POST,
PUT,
DELETE
}

Now create client class  and have all properties into that class that required for accessing resources.

to for and have multiple constructor using method overloading just in case if you like to


public class Client
    {
        public string EndPoint { get; set; }
        public Verb Method { get; set; }
        public string ContentType { get; set; }
        public string PostData { get; set; }

        public Client()
        {
            EndPoint = "";
            Method = Verb.GET;
            ContentType = "application/JSON";
            PostData = "";
        }

        public Client(string endpoint, Verb method, string postData)
        {
            EndPoint = endpoint;
            Method = method;
            ContentType = "text/json";
            PostData = postData;
        }

}

Once you have object you need methods to perform the the actions on the object. You need to write a method MakeRequest which should perform real action utilizing all variable in that object. Lets work on GET/POST request first.

public string Request(string parameters)
        {
            var request = (HttpWebRequest)WebRequest.Create(EndPoint + parameters);
            request.Method = Method.ToString();
            request.ContentLength = 0;
            request.ContentType = ContentType;
            
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                var responseValue = string.Empty;

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    var message = String.Format("Faile: Received HTTP {0}", response.StatusCode);
                    throw new ApplicationException(message);
                }

                using (var responseStream = response.GetResponseStream())
                {
                    if (responseStream != null)
                        using (var reader = new StreamReader(responseStream))
                        {
                            responseValue = reader.ReadToEnd();
                        }
                }

                return responseValue;
            }
        }

Now its time to call the class and create rest client object and call method to access to your object.

 

In your main method, create client object and supply required info and call appropriate method.


var client = new Client();
client.EndPoint = @"<a href="https://restcountries.eu&quot;;">https://restcountries.eu";</a>
client.Method = Verb.GET;
var pdata = client.PostData;
var response = client.Request("/rest/v1/currency/eur");

You can see parse response and get your desired output in JSON.

You can find complete code here.

 


using System;
using System.IO;
using System.Net;
using System.Text;

public enum Verb
{
    GET,
    POST,
    PUT,
    DELETE
}

namespace RestAPITesting
{
    class Program
    {
        static void Main(string[] args)
        {
           
            var client = new Client();
            client.EndPoint = @"https://restcountries.eu";
            client.Method = Verb.GET;
            var pdata = client.PostData;
            var response = client.Request("/rest/v1/currency/eur");
        }
    }
    public class Client
    {
        public string EndPoint { get; set; }
        public Verb Method { get; set; }
        public string ContentType { get; set; }
        public string PostData { get; set; }

        public Client()
        {
            EndPoint = "";
            Method = Verb.GET;
            ContentType = "application/JSON";
            PostData = "";
        }

        public Client(string endpoint, Verb method, string postData)
        {
            EndPoint = endpoint;
            Method = method;
            ContentType = "text/json";
            PostData = postData;
        }


        public string Request()
        {
            return Request("");
        }

        public string Request(string parameters)
        {
            var request = (HttpWebRequest)WebRequest.Create(EndPoint + parameters);
            request.Method = Method.ToString();
            request.ContentLength = 0;
            request.ContentType = ContentType;
            
            using (var response = (HttpWebResponse)request.GetResponse())
            {
                var responseValue = string.Empty;

                if (response.StatusCode != HttpStatusCode.OK)
                {
                    var message = String.Format("Faile: Received HTTP {0}", response.StatusCode);
                    throw new ApplicationException(message);
                }

                using (var responseStream = response.GetResponseStream())
                {
                    if (responseStream != null)
                        using (var reader = new StreamReader(responseStream))
                        {
                            responseValue = reader.ReadToEnd();
                        }
                }

                return responseValue;
            }
        }

    }
}