Last active
July 4, 2016 09:46
-
-
Save p00j4/d73c0bdae2a1dc95b6332bc856832765 to your computer and use it in GitHub Desktop.
Gist for documenting elemental tips
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Useful for testing of the products for which post parameters & response validation is very important at the client side itself. | |
The Problem | |
question: In general how do you do API testing? | |
answer: take the API from development document, hit it manually and check the response based on the post payload or may be write a automation suit around API using tools like SoapUI or Postman or some sort of API tests running in isolation from functional tests, isn't it? | |
what if when you can actually automate the API testing within the same functional test which ensures the user functional flow? does it sound more reliable testing! | |
or assume an automated way which can also give debugging metrics to figure out the Caught bug is from front-end or backend and help tracking almost all integration issues(front-edn to backend) at earlier stage. One more layer of smartness to add up in test report, sounds interesting? | |
A Solution | |
Need a mechanism which can be mixed in the existing selenium functional ui test and can give a way to capture the post data to the backend. | |
This tip can be handy and solve the problem with just few more lines to the proxy server which we had set up and captured the network traffic to do load testing in previous tip.( hyperlink to http://elementalselenium.com/tips/68-load-testing-revisited) | |
An Example | |
First we'll set up our requisite libraries to drive the browser (e.g., selenium-webdriver) and perform an assertion. After that, we'll create some simple setup, teardown, andrun methods fooled by proxy for networ data capture and then retrieve post payload in code to validate it. | |
# filename: LoginTest | |
import static org.hamcrest.CoreMatchers.is; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertThat; | |
import java.io.File; | |
import java.io.IOException; | |
import java.util.HashMap; | |
import java.util.HashSet; | |
import java.util.List; | |
import net.lightbody.bmp.BrowserMobProxy; | |
import net.lightbody.bmp.BrowserMobProxyServer; | |
import net.lightbody.bmp.client.ClientUtil; | |
import net.lightbody.bmp.core.har.Har; | |
import net.lightbody.bmp.core.har.HarEntry; | |
import net.lightbody.bmp.core.har.HarPostData; | |
import net.lightbody.bmp.core.har.HarPostDataParam; | |
import net.lightbody.bmp.core.har.HarRequest; | |
import net.lightbody.bmp.proxy.CaptureType; | |
import org.junit.After; | |
import org.junit.Before; | |
import org.junit.Test; | |
import org.openqa.selenium.By; | |
import org.openqa.selenium.Proxy; | |
import org.openqa.selenium.WebDriver; | |
import org.openqa.selenium.WebElement; | |
import org.openqa.selenium.firefox.FirefoxDriver; | |
import org.openqa.selenium.remote.CapabilityType; | |
import org.openqa.selenium.remote.DesiredCapabilities; | |
public class LoginTest { | |
WebDriver driver; | |
BrowserMobProxy proxy; | |
Har har ; | |
String uName = "tomsmith"; | |
String pwd = "SuperSecretPassword!"; | |
HashMap<String,String> param_map = new HashMap<String,String>(); | |
HashMap<String,String> param_values = new HashMap<String,String>(); | |
@Before | |
public void setUp() throws Exception { | |
proxy = new BrowserMobProxyServer(); | |
proxy.start(0); | |
Proxy seleniumProxy = ClientUtil.createSeleniumProxy(proxy); | |
DesiredCapabilities capabilities = new DesiredCapabilities(); | |
capabilities.setCapability(CapabilityType.PROXY, seleniumProxy); | |
driver = new FirefoxDriver(capabilities); | |
HashSet<CaptureType> captureTypes = new HashSet<CaptureType>(); | |
captureTypes.add(CaptureType.REQUEST_HEADERS); | |
captureTypes.add(CaptureType.REQUEST_CONTENT); | |
captureTypes.add(CaptureType.RESPONSE_HEADERS); | |
captureTypes.add(CaptureType.RESPONSE_CONTENT); | |
proxy.enableHarCaptureTypes(captureTypes); | |
{ //mocking parameters to be passed/accepted at server end | |
param_map.put("username",uName); //change accordingly | |
param_map.put("password",pwd); | |
} | |
} | |
@Test | |
public void withValidCredentials() throws IOException { | |
proxy.newHar(); | |
driver.navigate().to("http://the-internet.herokuapp.com/login"); | |
driver.findElement(By.id("username")).sendKeys(uName); | |
driver.findElement(By.id("password")).sendKeys(pwd); | |
driver.findElement(By.cssSelector("button")).click(); | |
WebElement successMessage = driver.findElement(By.cssSelector(".flash.success")); | |
assertThat(successMessage.isDisplayed(), is(Boolean.TRUE)); | |
har = proxy.getHar(); | |
File harFile = new File(System.getProperty("user.dir") + "/test.har"); | |
har.writeTo(harFile); // performance capture for further load testing | |
validatePassedPayload(har, "auth"); // post data validation | |
System.out.println("Passed:: Captured har for performance check \"test.har\" + validated posted parameters"); | |
} | |
/** | |
* To sniff post payload for validating if client side parameters are being passed correctly | |
* useful to use with ui automation test like with webdriver to ensure if user has posted correct data to server | |
* @param har | |
* @param filterStr: to refine url | |
*/ | |
public void validatePassedPayload(Har har, String filterStr){ | |
for (HarEntry entry : har.getLog().getEntries()) { | |
if (entry.getRequest() != null) { | |
HarRequest request = entry.getRequest(); | |
String requestUrl = entry.getRequest().getUrl(); | |
if (requestUrl.contains(filterStr)) { | |
HarPostData postData = request.getPostData(); | |
if (postData != null) { | |
System.out.println(requestUrl); | |
List<HarPostDataParam> paramsList = request | |
.getPostData().getParams(); | |
if (paramsList != null) { | |
for (int i = 0; i < paramsList.size(); i++) { | |
HarPostDataParam param = paramsList.get(i); | |
String paramName = param.getName(); | |
System.out.println(param.getName()+":"+param.getValue()); //to debug | |
assertThat(param.getValue(), is(param_map.get(paramName))); //will fail if either param doesn't exist or value doesn't match | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
@After | |
public void tearDown() throws Exception { | |
proxy.stop(); | |
driver.quit(); | |
} | |
} | |
Expected Behavior | |
1. Selenium runs the test in Firefox while connected to the proxy server | |
2. The HTTP Archive (HAR) is exported to a file on disk | |
3. Retrieve the required post data from the captured HARD and validate the same. | |
Outro | |
Alternatively, you could write the post data validation code separately by reading the exported HAR file, this will be helpful when you have multiple requests to validate | |
Happy Automated Testing! |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment