Tuesday, September 29, 2015

OkHttp - handy HTTP client for Java

One of my friends who is Java engineer suggested me to use this library. I really liked it, it allows you to implement your HTTP calls smoothly and without extra code :)

Find some examples of usage below (two first are taken from their documentation).

GET request: 
 OkHttpClient client = new OkHttpClient();  
 String run(String url) throws IOException {  
  Request request = new Request.Builder()  
    .url(url)  
    .build();  
  Response response = client.newCall(request).execute();  
  return response.body().string();  
 }  

POST request:
 public static final MediaType JSON  
   = MediaType.parse("application/json; charset=utf-8");  
 OkHttpClient client = new OkHttpClient();  
 String post(String url, String json) throws IOException {  
  RequestBody body = RequestBody.create(JSON, json);  
  Request request = new Request.Builder()  
    .url(url)  
    .post(body)  
    .build();  
  Response response = client.newCall(request).execute();  
  return response.body().string();  
 }  

This is my implementation of methods for HTTP calls.
 private JSONObject request(String path, String method, String body) throws ApiException {  
     Builder builder = new Request.Builder()  
       .url(baseUrl + path.replaceAll("^/", ""));  
     if (method.equals("POST")) {  
       builder.post(RequestBody.create(JSON, body));  
     }  
     else if (method.equals("DELETE")) {  
       builder.delete();  
     }  
     try {  
       Response httpResponse = httpClient.newCall(builder.build()).execute();  
       if (httpResponse.code() != 200) {  
         throw new ApiException(httpResponse.body().string());  
       }  
       String httpResponseBody = httpResponse.body().string();  
       System.out.println("ApiClient.request(" + path + "): " + httpResponseBody);  
       return (JSONObject)JSONValue.parse(httpResponseBody);  
     }  
     catch (IOException e) {  
       throw new ApiException(e.getMessage());  
     }  
   }  
   public JSONObject get(String resource, Map<String, String> params) throws ApiException {  
     return request(resource + "?" + urlEncodeUTF8(params), "GET", "");  
   }  
   public JSONObject post(String path, String body) throws ApiException {  
     return request(path, "POST", body);  
   }  

Monday, September 28, 2015

Charles: usage for native mobile application testing (IOS)

Mobile testing is new for me. I found extremely useful HTTP proxy tool Charles for monitoring traffic, which our mobile app sends/receives. It helped me to investigate bugs more deeply, not just their UI implication.


Set up Charles to see phone’s traffic

  1. Install Charles on your computer.
  2. Start Charles.
  3. Make sure your phone and computer are connected to same WiFi network.
  4. Find your network IP address in System Preferences -> Network.
  5. Open WiFi settings on your phone: Settings -> WiFi -> {your WiFi network name} -> HTTP Proxy. Set proxy to Manual and enter your network IP address and Port (by default it’s 8888). Leave Authentication switched off.
  6. Install root certificate on your IOS device, open following link in your phone browser: http://www.charlesproxy.com/getssl
  7. In Charles add a domain which you want to monitor in Proxy -> SSL Proxying Settings; enable SSl Proxying:
Screen Shot 2015-09-28 at 10.58.42.png
  1. Do any interactions in your app to make any HTTP calls, you should see a popup from Charles to confirm device usage.


Now you should see all calls, which your application makes and what are server responses.


Simulate Internet connection

First of all set up Charles on your computer (see steps above). To change your network connection settings do following steps:
  1. In Charles open Proxy -> Throttle Settings. Enable throttling by checking check box:
Screen Shot 2015-09-28 at 11.25.41.png
  1. Now you can select different throttle presets. You can set your custom network parameters or use ready settings like ‘3G’ throttle preset.
Enjoy your testing :)

Friday, September 4, 2015

Firefox driver - Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms

CASE STUDY
My tests are written with Thucydides + Firefox Driver. Test suite is successfully running on my local machine. My task is to set up tests in CI on remote server. I’m using latest Webdriver and Firefox versions (Selenium documentation says they are compatible). Nevertheless, tests failed with “Unable to connect to host 127.0.0.1 on port 7055 after 45000 ms”.


SOLUTION
I faced this exception several times before. Every time I solved that issue by downgrading Firefox browser on my test environment and turning off automatic updates. This time it didn’t help. I tried several FF & Selenium versions without any success.

Then I found information that Firefox driver runs on 7055 port by default, if the port is busy it tries to run on 7054 or 7056 ports. So when those 3 ports are taken by some process - Webdriver won’t be able to start.

Indeed, I checked if those ports were taken using command:

lsof -i | grep 7055

It turned out that they were busy and this was a cause of the exception. I killed the processes on the named ports and my tests started running successfully.

So as a summary. I was using Thucydides + Firefox driver. In some cases when Thucydides work was interrupted unexpectedly it doesn’t finish it’s processes correctly. So some Firefox processes were hanging on mentioned above 7054-7056 ports and didn’t let driver start over again.

Hope this post will help someone to fix quite popular issue with Webdriver.