Category Archives: Java

Spring Boot, Docker integration with IntelliJ and Windows

In this post I’ll give a more detailed guide for the Spring Boot and Docker initiative.

The final goal that I had in mind, was to have a Docker container that runs the packaged java application in a clean environment.
Support for remote debugging is included in the configuration, as well with both running and debug listening ports mapped/forwarded between the windows and docker machine. So in the end you can access the application as if it was running on your “localhost” 😀

Pre-requisites:
– Docker ToolBox for Windows (with VirtuaBox) Dowload link
– A Spring Boot or any Java project with Maven support will suite the purpose Getting Started with Spring Boot
– IntelliJ Docker plugin installed

After installing the Docker Toolbox (next > next > next…) we can jump right into creating a simple HelloWorld Spring Boot Web Starter project.
To do this in the fastest way, create a New Project > Maven and inside the pom.xml add the following dependency:

1
2
3
4
5
6
7
8
9
10
11
12
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
    </parent>

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

Next, add a “hello” package and a java class that will act as our Rest Controller (HelloController.java) in which we map the default “/” context path to a method that returns a default “Hello” String.

1
2
3
4
5
6
7
8
9
@RestController
public class HelloController {

    @RequestMapping("/")
    public String index() {
        return "This is Spring Boot with Docker!!";
    }

}

Create another class, with a main method that will be the entry-point to our application. The @SpringBootApplication makes everything smooth :)

1
2
3
4
5
6
7
8
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

This is my trimmed version of the “Getting Started with Spring Boot” from the official site.
You can go ahead and run “mvn package” command to generate the application’s executable .jar file.

Now for the Docker part, let’s start with installing the IntelliJ “Docker integration” plugin. This offers easier communication with the docker and saves some time, cause you won’t have to spam “docker build” … “docker run” commands in a separate console.

In the Maven pom.xml file, you’ll need to add the following docker-maven-plugin along with a few very important configuration lines.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.4.5</version>
                <configuration>
                    <dockerHost>https://192.168.99.100:2376</dockerHost>
                    <imageName>spring</imageName>
                    <baseImage>java</baseImage>
                    <env>
                        <server.port>8888</server.port>
                        <java.security.egd>file:/dev/./urandom</java.security.egd>
                    </env>
                    <exposes>
                        <expose>8888</expose>
                        <expose>5005</expose>
                    </exposes>
                    <entryPoint>["java", "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005", "-jar", "/${project.build.finalName}.jar"]
                    </entryPoint>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

In the configuration we are able to specify the baseImage and imageName along with the expose and entrypoint parameters which are very common in a Dockerfile. In our case, we won’t be needing one at all, because the maven plugin will do all the work for us!

The environment variables are used to specify the server.port to run on 8888 instead of the default 8080 (yes, I’m still using Skype…)
The ports also need to be exposed from the docker container so both the server and remote debugging ports are added.
Entrypoint is basically the whole java command used to run the server, in our case the resulting “.jar” file after mvn package. It contains some extra arguments to enable remote debugging for the server.

In order to make use of this plugin we need to run “docker:build” from maven/plugins section.

Docker Build mvn
After it’s finished we will have a new “spring” image derived from the default Java one. Now here comes the Docker and IntelliJ integration part.

Docker plugin

We will go ahead and create a new Docker Deployment configuration as follows.
Docker Run configuration

We can then press Play and our container will be started along with the application server. In order to be able to access the server from Windows, we need to forward the 8888 and 5005 port respectively, from the docker machine to running Windows OS (this isn’t necessary if you’re a Linux guy, because the docker-host is running natively).

To do this we can use the following commands from an “elevated windows command prompt” (just run it as Administrator):

1
2
netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=8888 connectaddress=192.168.99.100 connectport=8888
netsh interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=5005 connectaddress=192.168.99.100 connectport=5005

Everything is set and we can now access our application deployed inside the docker container from windows: http://localhost:8888

You can find the code here: SpringDocker Project

Hope you enjoyed this tutorial,
-M.

Soap WebService testing using Stub generation

In this tutorial I will show an easy way on how to generate Stubs needed to call SOAP webservice methods from Java (or in this tutorial, with Groovy).

The SOAP webservice that I have in mind for this demo is the free Global Weather WebService and we will be needing its WSDL:

1
http://www.webservicex.net/globalweather.asmx?WSDL

Will now go ahead and create a new Maven project in IntelliJ IDEA 15 and then Add Framework Support and select check the Webservice client.
You can also find a link to the GitHub project at the end of this post.

Before generating the stubs, we need a few dependencies to be added in the pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<dependencies>
        <dependency>
            <groupId>org.apache.axis</groupId>
            <artifactId>axis</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>axis</groupId>
            <artifactId>axis-wsdl4j</artifactId>
            <version>1.5.1</version>
        </dependency>

        <dependency>
            <groupId>axis</groupId>
            <artifactId>axis-jaxrpc</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>commons-discovery</groupId>
            <artifactId>commons-discovery</artifactId>
            <version>0.5</version>
        </dependency>

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>2.4.5</version>
        </dependency>
    </dependencies>

What we need to do now is right click on a folder in our project and select the last option WebServices -> Generate Java Code from Wsdl

IDEA

After the Stub generation is finished, we will find the following files inside the stubs package

IDEA Project Structure

We are aiming to be able to call the methods of the global webservice:

1
2
public String getWeather(String cityName, String countryName)
public String getCitiesByCountry(String countryName)

but in order to do that, we need to get ourselves an instance of the GlobalWeatherLocator and furthermore, access the GlobalWeatherSoap_PortType object which has the 2 methods that we’re interested in.
A quick note here: Don’t be fooled by the “String” return type of these 2 methods, the String is actually … XML so we’re going to need a XmlSlurper to parse it and perform asserts.

Using Groovy, this code will look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
import stubs.GlobalWeather
import stubs.GlobalWeatherLocator
import stubs.GlobalWeatherSoap_PortType


GlobalWeather globalWeather = new GlobalWeatherLocator()
GlobalWeatherSoap_PortType globalWeatherSoap = globalWeather.getGlobalWeatherSoap()

def xmlResponse = globalWeatherSoap.getWeather("Bucuresti", "Romania")

def parsedXML = new XmlSlurper().parseText(xmlResponse)
assert parsedXML.Status == "Success"

The code for the project can be found on GitHub – WebServiceClientStubs

Hope you’ve enjoyed generating some stubs.

Selenium TestNG – Customizing tests at runtime with IAnnotationTransformer

Recently I had a request to have the possibility to choose which @Test to run from an external file that is human readable and easily configurable thus testng.xml was out of the question.

My first thought was: this should be easy, we can just pass a true or false value from an external file, to the “enabled” test method attribute. This approach quickly failed since the annotation’s attributes seem to accept only constants, so for “enabled” it’s either true or false, not a “superposition” of both :)

So I started doing a little digging and ultimately found the ITestAnnotation Transformer interface:

1
2
3
4
public interface IAnnotationTransformer {
public void transform(ITest annotation, Class testClass,
Constructor testConstructor, Method testMethod);
}

The transform() method will be executed before any of the annotated methods/classes in our code and when we implement it we have the opportunity to use setters to alter the annotation attributes.

Let’s take the following example with 3 tests:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package testthis.selenium;
import org.testng.annotations.Test;
public class SelectTestToRun {
@Test(testName = "test1", enabled = false)
public void testing() {
System.out.println("test1 run");
}
@Test(testName = "test2", enabled = false)
public void testing2() {
System.out.println("test2 run");
}
@Test(testName = "test3", enabled = false)
public void testing3() {
System.out.println("test3 run");
}
}

As you can see we initialize the tests with the enabled attribute set to false and also give them a testName. In order to have a test running, we will have to set it to true from the transform() method.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package testthis.selenium;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;
import org.testng.IAnnotationTransformer;
import org.testng.annotations.ITestAnnotation;
public class AnnotationTest implements IAnnotationTransformer {
Properties props = new Properties();
public void transform(ITestAnnotation annotation, Class testClass,
Constructor testConstructor, Method testMethod) {
try {
props.load(new FileInputStream("configure.properties"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (props.values().contains(annotation.getTestName())) {
annotation.setEnabled(true);
}
}
}

Now here was the tricky part. This needed a way to differentiate between our test methods, because annotation.setEnabled(true) will cause all the @Test methods to run.
So we had to perform a check if among the values read from the properties file, there are any testNames matching. If so, then that @Test will have its enabled attribute set to “true”.

To make this easier, we will name the keys inside the properties file with the same value as the testNames and if we have the same value, then the test is run.

1
2
3
4
key=value
test1=test
test2=test2
test3=test3

For this to work, we have to Run As TestNG Suite, from the testng.xml and also pass a listener class, in our case, it is the fully qualified name of the AnnotationTest class.

Now let’s have a look at the results:

1
2
3
4
5
6
7
8
[TestNG] Running:
C:\Users\mdima\workspace\SeleniumTest\testng.xml
test2 run
test3 run
===============================================
Suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================

Since we passed something else rather than the testName of the first test, test1() method was not run.

So we can now easily customize which tests to run from the properties file, without touching the Test methods, as long as we’re using the testng.xml and therefore this is also useful for the maven-surefire-plugin in a maven project.

Enjoy TestNG customization,
-M.

Test execution priority in Selenium TestNG

Hello everyone,

Few days ago I was taking a look over a class which contained many @Test methods (from org.testng.annotations of course :) ) and whenever it was running, I was getting a different order of the tests in the results’ summary.

So this got me thinking and a quick solution came to mind: test dependency (dependsOnMethods / dependsOnGroups) but this would then imply that if the initial test fails, the execution would stop right then and there. I then found out about test method priority and it seems to be exactly what I was looking for and very easy to use.

Given the following example let’s see how we can obtain a desired order of execution: A > B > C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @Test(priority = 1)
    public void testC() {
        System.out.println("Test C");
    }

    @Test(priority = 2)
    public void testA() {
        System.out.println("Test A");
    }

    @Test
    void testB() {
        System.out.println("Test B");
    }

In the above case, we get this order of execution: B > C > A which isn’t exactly what we wanted, let’s see how we can change that.

A few things need to mentioned about test method priorities:

  • lowest priority (can also be negative) will be executed first, thus -5 will run before priority 1
  • when no priority is specified, the default priority is 0, in our example, testB has the default priority

Since we’re aiming to obtain the A -> B ->C flow, we should use, the lowest priority for testA and set B and C to 1 and 2 respectively:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    @Test(priority = 2)
    public void testC() {
        System.out.println("Test C");
    }

    @Test
    public void testA() {
        System.out.println("Test A");
    }

    @Test(priority = 1)
    void testB() {
        System.out.println("Test B");
    }

SoapUI – Parameterizing Requests in the free version

Hello,

This post will show how to send values from an external file to specific WSDL tags as arguments. In this way if you have to perform combinatorial testing with let’s say, 50 different requests, instead of creating individual SOAP requests, you’ll only need one and a (rather big) testdata file.

For this example we’ll be reading the testdata from an Excel file so you should first make sure to place the Apache POI jar file in the “SoapUI\bin\ext” folder. This is the content of the Excel file:

City Name Zip
New York 10001
not found 33333
Minneapolis 55555
BeverlyHills 90210

 

Now open SoapUI and create a new project using a WSDL file such as the famous weather one:  http://wsf.cdyne.com/WeatherWS/Weather.asmx?WSDL

We’re now going to Generate a TestSuite by right-clicking the WeatherSoap interface and selecting the GetCityForecastByZip operation. In the TestCase and open TestSteps and add a new step of type “Properties”, name it something like “property-loop” open it and insert a new property named “Zip”. Now open the Soap Request (GetCityForecastByZip) and right click on the question mark “?” and select GetData > property-loop> Zip. It should look something like this:

SoapUI-Property

We have the request mapped to the property Zip value but now we need to also pass the data from the excel to the property. We can do this by using a Groovy Script so let’s get groovy 😀

Add a new test step select Groovy Script and insert the following code for reading an Excel file:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import java.io.*

File excel = new File("D:/data.xls"); // path to the Excel file

FileInputStream fis = new FileInputStream(excel);
HSSFWorkbook wb = new HSSFWorkbook(fis);
HSSFSheet ws = wb.getSheetAt(0); // get the first Sheet of the Excel file

int rowNum = ws.getLastRowNum() + 1;
int colNum = ws.getRow(0).getLastCellNum();
propTestStep = context.testCase.getTestStepByName("property-loop") // get the Property step (ours is named "property-loop")

    for (int i = 1; i&lt; rowNum; i++) {
        HSSFRow row = ws.getRow(i);
        for (int j=1; j &lt; colNum; j++) {
            HSSFCell cell = row.getCell(j);
            String value = cellToString(cell);

            log.info ("The value is " + value);
            propTestStep.setPropertyValue("Zip", cellToString(row.getCell(1))) //set the value of "Zip" property equal to Excel's column B ( getCell(1) )

        }
        testRunner.runTestStepByName("GetCityForecastByZIP"); //we're going to run the Soap Request after each iteration of the Excel's rows.
    }

    //a helper method to convert the Cell's value to String
    public static String cellToString(HSSFCell cell) {
        int type;
        Object result;
        type= cell.getCellType();

        switch (type) {
            case 0 : //numeric value in Excel
                result = String.valueOf((int)cell.getNumericCellValue());
                break;
            case 1 : //String value in Excel
                result = cell.getStringCellValue();
                break;
            default:
                result = cell.getCellType();
                throw new RuntimeException("There is no reader for this type of Excel data");
        }
        return result.toString();
    }

So what the above script does is for each row in the Excel file, we’re passing the value from the Column B to the Property field named “Zip” and then run our SoapRequest.

We can also disable the property and the soap request so that our TestCase only executes the Groovy Script which calls the request using testRunner.runTestStepByName(“GetCityForecastByZIP”).

Hope you’ll find this helpful,
-M.

Selenium DDT with TestNG and DataProvider

Hi there,

Of course there are many ways to do Data Driven Testing but if you’re familiar with Java or OOP in general you’re going to like this approach with TestNG and DataProvider.

First let’s give a short intro to @DataProvider; this annotation will require a name and holds a method that returns either an Object[][] or an Interator

For the scope of this article, we will try to login multiple times on a particular site, such as gmail.com with the username and password combinations provided in an “input.txt” file:


1
2
3
user1, pass1;
user2, pass2;
user3, pass3;

Now let’s see the code for our custom readText() method and review it based on the particularities of the above input.txt file:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    public static Object[][] readFile(File file) throws IOException {
        String text = FileUtils.readFileToString(file);
        String[] row = text.split(";");

        int rowNum = row.length;
        int colNum = row[0].split(",").length;

        Object[][] data = new String[rowNum][colNum];

        for (int i = 0; i &lt; rowNum; i++) {
            String[] cols = row[i].split(",");
            for (int j = 0; j &lt; colNum; j++) {
                data[i][j] = cols[j].trim();
                System.out.println("The value is " + cols[j].trim());
            }
        }
        return data;
    }

So as you can see, we’ll be passing 1 argument to our readText() method, the “file” that needs to be read. We’re then using the Apache Commons IO, FileUtils library to read our .txt file so make sure you have that imported (seems that our “custom” readText() method is not so custom afterall :) )

We’re storing all the read content inside a string and then we’re going to do a split (a fabulous one) by the semicolon (“;”) character since that seems to be separating each individual row.

Now to find out the number of “columns” we can do another split by the comma character (“,”) since it is separating each username by its password. Of course you can use any other character for separation and then do a split by it (i.e. a pipe | or a tilda `  or anything else).

Next step will create an array of array of Objects called “data” and it will have the size of data[rows][columns] that we obtained earlier.

What’s left next is to make 2 for loops in order to iterate through the number of rows and then columns while assigning the read value to the data[][] array without the whitespaces, which will be trimmed.

In the end our method will return the “data” Object[][].

So we’re now going to use this method for the @DataProvider annotation:


1
2
3
4
5
6
7
@DataProvider(name = "text")
    public static Object[][] readFile() throws IOException {
        File file = new File("input.txt");
        ReadText txt = new ReadText();
        Object[][] returnObjArray=txt.readFile(file);
        return returnObjArray;
    }

What’s left to do is to pass this @DataProvider to a @Test method that makes use of its 2 parameters and since we said we’re going to try to login to gmail we’re gonna do just that:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 @Test (dataProvider = "text")
    public void loginGmail(String user, String pass) {
        driver = new FirefoxDriver();

        driver.manage().timeouts().implicitlyWait(7, TimeUnit.SECONDS);
        driver.get("http://www.gmail.com");
        WebElement username = driver.findElement(By.id("Email"));
        username.sendKeys(user);

        WebElement password = driver.findElement(By.id("Passwd"));
        password.sendKeys(pass);

        WebElement loginButton = driver.findElement(By.id("signIn"));
        loginButton.click();

        Assert.assertTrue(driver.findElement(By.cssSelector("a[title*='Inbox']")).isDisplayed());
    }

Notice how the dataProvider name in the @Test annotation corresponds with the name of the @DataProvider and how the test method “loginGmail” accepts 2 String arguments which corresponds with a row of parameters from our input.txt file

In the end our test will be executed 3 times because there are 3 rows of username+password combinations which are passed from file.

Enjoy DDT,

-M.