BrowserMob Proxy Selenium network performance extension

It’s been a while since I published some Java code here, but as Dexter Morgan would say: today is the day. If you want me to post Java tests more often please let me know in the comments.

BrowserMob Proxy is a very useful tool which ‘can capture performance data for web apps ( via the HAR format), as well as manipulate browser behavior and traffic, such as whitelisting and blacklisting content, simulating network traffic and latency, and rewriting HTTP requests and responses’. It also has built-in support for Selenium integration which adds few nice features for our test suites with very little effort required.

You may, of course, say that a Selenium is not a performance testing tool (and rightly so), but nevertheless, it can contribute to your testing in the following ways:

  • You can quickly assert that none of the web requests returned undesired HTTP responses ( like 404, 5xx). Captured .har network traffic can be easily converted to Apache JMeter using various tools, for example, Har2jmeter
  • .har files can be used for comparison measures. If you do things right (i.e. your testing environment is exactly the same on each test run) changes in overall test execution time can indicate performance problems. Knowing that already you can just compare two *.har files (fast one and slow one) and check exactly which requests had slowed down.* Modify user agent in requests

Those are just a few things that come to my mind right now, the full list of BrowserMob Proxy features is listedhere.

In order to start using BrowserMob Proxy add this Maven dependency to your project:

<dependency>
<groupId>net.lightbody.bmp</groupId>
<artifactId>browsermob-core</artifactId>
<version>2.1.2</version>
</dependency>

Now BrowserMob Proxy can be run using simple methods. I’m using TestNG annotation to start it before the tests, and close just after all of them finish. As you can see I capture all HTTP traffic headers here.

private static final int BROWSER_MOB_PROXY_PORT = 9191;

    protected BrowserMobProxyServer server;

    @BeforeClass
    public void startBMP() {
        server = new BrowserMobProxyServer();
        server.start(BROWSER_MOB_PROXY_PORT);
        server.setHarCaptureTypes(CaptureType.getHeaderCaptureTypes());
    }

    @AfterClass
    public void stopBMP() {
        server.stop();
    }
}

And this Gist shows how to add proxy settings to ChromeDriver. See my Browser capabilities explained post for a more thorough description of browser configuration.

@Override
public WebDriver getDefaultDriver() {
return new ChromeDriver(getChromeCapabilities());
}

    private DesiredCapabilities getChromeCapabilities() {
        DesiredCapabilities capabilities = DesiredCapabilities.chrome();
        capabilities.setCapability(CapabilityType.PROXY, getChromeProxySettings());
        return capabilities;
    }

    private Proxy getChromeProxySettings() {
        return ClientUtil.createSeleniumProxy(server);
    }

Now the most important thing - actual tests. As you can see I’m starting new Har capture on BrowserMob Proxy server before each test (it’s called ‘Awesome Testing Only Test’ or ‘Google Awesome Testing Test’). After the last test step ends network traffic is saved to *.har file. I’m using FluentLenium syntax. Page Objects code can be found on my Github project . Hopefully, you have no problem understanding what the tests do :)

public class BrowserMobChromeTest extends BrowserMobChrome {

    private static final String AWESOME_TESTING = "Awesome Testing";

    @Test
    public void awesomeTestingOnly() throws IOException {
        server.newHar("Awesome Testing Only Test");

        AwesomeTestingPage awesomeTestingPage = createPage(AwesomeTestingPage.class);
        awesomeTestingPage.go();
        awesomeTestingPage.isAt();

        Har har = server.getHar();
        har.writeTo(new File("at.har"));
    }

    @Test
    public void googleAwesomeTesting() throws IOException {
        server.newHar("Google Awesome Testing Test");
        GoogleHomePage googleHomePage = createPage(GoogleHomePage.class);
        googleHomePage.go();
        googleHomePage.isAt();

        GoogleSearchResultPage googleSearchResultPage = googleHomePage.search(AWESOME_TESTING);
        googleSearchResultPage.isAt();

        AwesomeTestingPage awesomeTestingPage = googleSearchResultPage.clickLink(AWESOME_TESTING);
        awesomeTestingPage.isAt();

        Har har = server.getHar();
        har.writeTo(new File("googleat.har"));
    }

}

Our quest for obtaining *.har network traffic file is completed. The screenshot below shows how does it look like in Google HTTP Archive Viewer extension. It took 239 requests and 9.59 seconds to successfully Google my blog.

The file can also be accessed using external libraries. In the code below, I convert it JSON format using HarReader. It’s not exactly part of the test so I put it in external class.

public static void main(String[] args) throws HarReaderException, IOException {
String pathToFile = "at.har";

        HarReader harReader = new HarReader();
        List<HarEntry> harEntryList = harReader.readFromFile(new File(pathToFile)).getLog().getEntries();

        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        try (Writer writer = new BufferedWriter(new OutputStreamWriter(
                new FileOutputStream("filename.txt"), "utf-8"))) {
            writer.write(gson.toJson(harEntryList));
        }
    }

Remember: Complete Java code of this post (and every other) can be found on my Github project.

Tags:

Categories:

Updated: