Posts Tagged: ‘Testing’

Testing XPages (2): BrowserMob Proxy

17. September 2015 Posted by Sven Hasselbach

When testing XPages or other web applications, you may want to have more control about the requests and responses during the JUnit testing. For example, if you want to test if a specific HTTP header exists in the response, or if it is required to add some HTTP headers to the request. But you cannot doe this out of the box with Selenium. Instead, you have to add a proxy to the Firefox controller, which then gives you a handle to the HTTP data and allows you to control the flow.

An good solution for this is BrowserMob Proxy, which can be used by adding the required dependency to your Maven pom.xml:

<dependency>
    <groupId>net.lightbody.bmp</groupId>
    <artifactId>browsermob-proxy</artifactId>
    <version>2.0.0</version>
</dependency>

[This is version 2.0.0, the latest stable version]

The proxy runs locally on the specified port as soon the JUnit test starts and ends automatically after finishing the tests.  In order to accomplish this, the setUp method has to be modified:

// start the proxy (listens on port 4444)
server = new ProxyServer(4444);
server.start();

// get the Selenium proxy object
Proxy proxy = server.seleniumProxy();

// configure it as a desired capability
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.PROXY, proxy);

Now, the proxy setting must be added to the Firefox driver:

driver = new FirefoxDriver(capabilities);

In the test class, three global variables must be defined; these are giving you access to the proxy server and latest the request and response during testing:

private ProxyServer server;
private BrowserMobHttpResponse httpResponse;
private BrowserMobHttpRequest httpRequest;

With the help of a ResponseInterceptor, the httpResponse property is always filled with the latest response. To initialize it, an anonymous class in the setUp method has to be created:

// add a response interceptor
ResponseInterceptor interceptor = new ResponseInterceptor() {
    public void process(BrowserMobHttpResponse response, Har har) {
          httpResponse = response;
    }
};

// add the interceptor to the server
server.addResponseInterceptor(interceptor);

For the RequestInterceptor it is the same procedure:

// add a request interceptor
RequestInterceptor requestInterceptor = new RequestInterceptor() {
    public void process(BrowserMobHttpRequest request, Har har) {
       httpRequest = request;
    }
};

server.addRequestInterceptor(requestInterceptor);

Now, it is possible to use it in a JUnit test:

@Test
public void testDemo() throws Exception {
 
    // add a request header
    server.addHeader("X-FOO", "BAR");
 
    // load the page
    reloadPage();

    // TEST RESPONSE STATUS
    HttpResponse httpRawResponse = httpResponse.getRawResponse();
    assertTrue("HTTP/1.1 200 OK".equals(httpRawResponse.getStatusLine()
       .toString()));
 
    // TEST SERVER HEADER
    assertTrue( "Lotus-Domino".equals( httpResponse.getHeader("Server")) );
 
}

The Browsermob-proxy has a lot of additional features: You can modify the allowed speed for up- and downstreams, use basic authentication, upload files, etc.

Testing XPages

16. September 2015 Posted by Sven Hasselbach

When testing XPages with Selenium, you can easily pre-generate the JUnit test code with the browser plugin. But when you then change the structure of the XPage (f.e. by moving the components from an XPage to a custom control), all the IDs of the JUnit test will not work anymore.

That’s why it is better to use CSS selectors to access the generated fields:

driver.findElements(By.cssSelector("input[id*='idOfTheComponent']"));

With the selector „id*=’idOfTheComponent'“ you can access the elements by their component id, idependently of their full generated client id.

Here is an example with a small XPage with a radio group and a listbox:

 

A simple XPage to test (SimpleDemo.xsp)

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">

    <xp:radioGroup
        id="radioGroupSimpleDemo"
        defaultValue="1">
        <xp:selectItem itemLabel="1" itemValue="1" />
        <xp:selectItem itemLabel="2" itemValue="2" />
    </xp:radioGroup>


    <xp:listBox id="listBoxSimpleDemo" multiple="true">
        <xp:selectItem itemLabel="1" itemValue="1" />
        <xp:selectItem itemLabel="2" itemValue="2" />
        <xp:selectItem itemLabel="3" itemValue="3" />
    </xp:listBox>
 
</xp:view>

 The JUnit Test

package ch.hasselba.xpages.test.seleniumdemo;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.List;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.Select;

public class SimpleDemo {

	private WebDriver driver;
	private String baseUrl = "http://127.0.0.1/WebTestDemo.nsf/SimpleDemo.xsp";
	private StringBuffer verificationErrors = new StringBuffer();

	@Before
	public void setUp() throws Exception {
		driver = new FirefoxDriver();
		driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
	}

	@After
	public void tearDown() throws Exception {
		driver.quit();
		String verificationErrorString = verificationErrors.toString();
		if (!"".equals(verificationErrorString)) {
			fail(verificationErrorString);
		}
	}

	@Test
	public void testDemo() throws Exception {
		reloadPage();
		List elemRadio = driver.findElements(By
				.cssSelector("input[id*='radioGroupSimpleDemo']"));
		assertTrue(elemRadio.get(0).isSelected());
		assertFalse(elemRadio.get(1).isSelected());

		Select select = new Select(driver.findElement(By
				.cssSelector("select[id*='listBoxSimpleDemo']")));
		List listSelect = select.getOptions();
		for (WebElement listElem : listSelect) {
			assertFalse(listElem.isSelected());
			assertTrue(listElem.isEnabled());
		}

	}

	public void reloadPage() {
		driver.get(baseUrl);
	}
}

The Maven pom.xml file

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
    http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>
    <groupId>ch.hasselba.xpages.test</groupId>
    <artifactId>seleniumdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>seleniumdemo</name>
    <url>http://hasselba.ch</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>2.46.0</version>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>pl.pragmatists</groupId>
            <artifactId>JUnitParams</artifactId>
            <version>1.0.4</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Isolation and multi-tenancy in the IBM PureApplication System – Cloud Groups are the NEW Virtual Systems

9. April 2014 Posted by Yathish Kumar

(This is a guest entry posted on behalf of Georg Ember)

Almost any application running in the cloud is designed to share resources. Virtualization is the key enabler for cloud computing in integrated or converged systems. Applications run in the cloud as workloads that share system resources, such as CPU, memory and networking.  However, there are legal or organizational requirements where workloads must be isolated from each other and the key question is: What type of isolation is the right way to protect the application environments from each other?

Isolation (also as know as multi-tenancy) is a key requirement for cloud computing. An application deployed into a cloud environment must be able to run independently and separately from other applications in the cloud. Each application requires it to move traffic along the network and protect its data as well.

Isolation of applications and data, by physical separation or by virtualization within an integrated system, may satisfy security requirements and ensure that a failure of one application will not cause the failure of other applications. While the data has to be kept isolated, in many cases, other departments within a company are not allowed to see deployed resources (Virtual Machines) of other environments.

An ideal solution to implement such an application and virtual systems isolation is to exploit the multi-tenancy features of the IBM PureApplication System.

A comfortable and easy way to isolate LAN, SAN and Server resources, on a physical as well as a logical level in PureApplication System, is to use the concept of Cloud Groups and environment profiles.

Using the isolation techniques that are incorporated within the IBM PureApplication System can help minimize business risks and increase the availability. By selecting nodes to Cloud Groups which are placed in separate chassis modules, the performance and availability of a Cloud Group can be greatly increased.

image

If you are required to isolate applications and data not only on a logical level, the concept of Cloud Groups in the PureApplication Systems is the right choice for you. You do not need to acquire multiple physical systems, except for high availability or disaster recovery reasons, when you need to separate multiple application environments in a multi-tenant infrastructure. PureApplication System offers the concept of dedicated Cloud Groups.

IBM PureApplication System Cloud Groups physically separate:

  • Compute Nodes (server nodes), across IBM Flex Chassis,
  • LANs by defining VLANs (on dedicated LAN ports) and IP groups (IP address ranges),
  • Services running on the System (so called shared services), each Cloud Group can have “private” services running, without affecting other Cloud Groups. Examples of shared services are monitoring, OS updates, Load Balancers and clustered file systems services, just to name a few.
  • Workload (deployment) users, where each user belongs to one or more environment profiles, can deploy an application to the designated Cloud Group, without seeing other deployed resources from other users or being seen by other users on the Cloud Groups.

image

Companies normally separate environments according to application development lifecycle. The typical divisions are:

  • Development (DEV): An environment used for developing applications.
  • Testing (TEST): Used for testing applications.
  • Production (PROD): Used for running applications; this is the realm of business or end users.

Each of these environments typically runs on totally independent sets of hardware and networks to avoid cross-environment issues. But, when using Cloud Groups in the PureApplication System, application environments are totally isolated from each other, if required, even by the users and shared services they use. Consecutively, you do not need to acquire multiple physical systems – one PureApplication System does it all for isolation of application environments. There is full isolation and protection in any layer of the stack.