Say it ain't so, I will not go, Turn the lights off, carry me home, Keep your head still, I'll be your thrill, The night will go on, my little windmill (All The Small Things - Blink-182)
lunes, agosto 29, 2016
Configuring Maven Release Plugin to Skip Tests
Etiquetas: maven, maven release plugin
jueves, agosto 18, 2016
Making Web UI testing great again with Arquillian, Docker and Selenium (part 1)
Introduction to the Problem
Most of the time when you need to write functional tests/end-to-end tests for web UI, you end up by using Selenium, which it can consider the de-facto tool in Java world for web UI testing. I am sure you've already used it for these kind of tests.
Fixing First Problem
To fix the first problem, the most easier solution you can think is using Docker containers and of course Docker compose since you can define and run multi-container Docker applications. So basically you define in docker-compose file, all the servers that you might need to run the tests so when you run tests you have all of them running and more important with a fixed version, so you can be sure that the tests are always run against a known/desired specific version of the servers, same JDK, ... and not depending on what is installed in developers/CI machine.
But this approach has one problem. You need to specifically run docker-compose up, docker-compose down. Of course you can automate this in your build script, which will solve the problem on CI environment, but if a developer wants to execute a test from IDE, let's say for debugging, then he needs to be aware of that fact.
And this is what Arquillian Cube solves. Arquillian Cube is an Arquillian extensions that uses docker-compose file to start and configure all the containers defined there, execute the tests and finally shutting down all of them. The good news is that since Arquillian works with JUnit (and TestNG and Spock), you can run the tests from the IDE without worrying about starting and stopping containers since Docker lifecycle is managed by Arquillian Cube.
So first part of the problem that is defining the test environment is fixed with Arquillian Cube. Let's see how to fix the second one.
Fixing Second Problem
Selenium project provides a Docker images with Selenium standalone or Selenium node with browser (Firefox or Chrome) and a VNC server installed.
So it seems a perfect fit to fix the problem of having to install browsers with a concrete version or concrete configurations locally since you can use a docker image with a browser configured for the tests.
New Problems When Using Docker for Testing
And that's cool, but it has some problems. The first one is that you need to create a docker-compose file specific for testing purposes, although this is not a bad thing per se, but it requires more management from dev part to maintain this file as well and of course repeat again and again in all the projects you want to use it, defining the browser to use and the VNC client image to get the recording for future inspection.
The second problem is the configuration of WebDriver. When running WebDriver against a remote browser, you need to set the location (IP) of the browser and configure the RemoteWebDriver accordantly with desired capabilities.
So again you have to write in all the tests the WebDriver configuration again and again. You can create a factory class that can be reused in all the projects, and it is good, but you still have one problem, some developers might use Docker machine so IP would not be static and might change every time, other might be using native Docker, and for example some phases of CI pipeline might run the tests against a remote fully environment like preproduction environment, so before executing tests you would need to specify manually the IP of container of Docker host.
And the third problem you'll get is that you need to instruct WebDriver to open a page:
webdriver.get("http://www.google.com");
The problem is that in this case the browser is inside the Docker infrastructre so you need to set the internal IP of the server container, so you don't only need to know the Docker host IP for connecting the remote web driver but also the internal IP of the server container to open the page in remote browser using the get method. And again this might be quite difficult to acquire in an automatic way.
But all these problems are solved when using the new integration between Arquillian Drone and Arquillian Cube.
Fixing New Problems
Arquillian Drone is an Arquillian extension that integrates Selenium WebDriver to Arquillian. This extension manages the configuration of the WebDriver so you don't need to repeat it in all your tests, and also the lifecycle of the browser.
So as you can see this pair of extensions seems a perfect fit for solving these problems. Drone takes care of configuration meanwhile Cube takes care of configuring correctly the Selenium/VNC containers and starting and stopping them.
As you might see, you don't need to worry about creating docker-compose file for testing purposes. You only need to create the one used for deploying, and Arquillian will take care of the rest.
Example
The first thing to do is create a project with required dependencies. For this example we are using Maven, but you can achieve the same using other build tools.
Things important to notice is that you are using BOM definitions for setting versions of the components. Then we set Arquillian Standalone dependency because our test is not going to have @Deployment method since the deployment file is already created inside the Docker image used in the application. Finally Arquillian Cube and Arquillian Drone dependencies are added.
Next step is creating at src/test/resources a file called arquillian.xml which is used for configuring extensions.
You can see that:
- You need to specify the docker machine name where to start containers in case of using docker machine. If you are using native Docker then you don't need to set this attribute.
- You need to set a location relative to root folder of the project where docker-compose file is located. Note that you could use any other name.
And finally the test:
There are some interesting parts in this test.
- It is a standard Arquillian test in the sense it uses Arquillian runner.
- Uses @Drone injection mechanism provided by Arquillian Drone to enrich test with a WebDriver configured to connect to remote browser.
- Uses @CubeIp annotation to enrich test with the internal IP of the container helloworld. Since browser is running inside Docker host, we can use the internal IP for this purpose. Also it is important that you need to use the exposed port and not the bind port.
- Everything else is managed by Arquillian Cube like the start and stop of the Docker containers(helloworld in this case) but also the ones containing the browser and the VNC client. If you put a debug point inside test method, and then execute a docker ps on a terminal, you'll see that three containers are started, not just helloworld.
- If after running the test you inspect target/reports/videos directory you will find the video recording of the test.
When I look 'round, I only see outta one eye
As the smoke surrounds my head, the sauna (Stickin' In My Eye - NOFX)
Etiquetas: arquillian, arquillian cube, arquillian drone, Docker, selenium, ui testing, WebDriver
jueves, marzo 31, 2016
Continuous Stress Testing for your JAX-RS (and JavaEE) applications with Gatling + Gradle + Jenkins Pipeline
First thing to develop is the JAX-RS JavaEE service:
So create a directory called src/test/scala and create a new class called AverageOrbitalPeriodSimulation.scala with next content:
Every simulation must extends Simulation object. This simulation takes base URL of the service from starwars_planets_url environment or system property, it creates the scenario pointing to the endpoint defined in JAX-RS, and finally during 3 seconds it will gradually add users until 10 users are running at the same time. The test will pass only if all the requests succeed in less than 3 seconds.
Now we need to run this test. You will notice that this is not a JUnit test, so you cannot do a Run As JUnit test. What you need to do is use a runnable class provided by Gatling which requires you pass as argument the simulation class. This is really easy to do with Gradle.
We are defining a Gradle task of type JavaExec, since what we want is to run a runnable class. Then we make the life a bit easier for developer by automatically detect that if starwars_planets_url is not set, we are running this test into a machine that has Docker installed so probably this is the host to be used.
Finally we override the environment variable if it is required, we set the runnable class with required properties and we configure Gradle to execute this task every time the test task is executed (./gradlew test).
If you run it, you might see some output messages from Gatling, and after all a message like: please open the following file: /Users/..../stress-test/build/reports/gatling-results/averageorbitalperiodsimulation-1459413095563/index.html and this is where you can get the report. Notice that a random number is appended at the end of the directory and this is important as we are going to see later. The report might looks like:
At this time we have Gatling integrated with Gradle, but there is a missing piece here, and it is adding the continuous part on the equation. For adding continuous stress testing we are going to use Jenkins and Jenkins Pipeline as CI server so for each commit stress tests are executed among other tasks such as compile, run unit, integration tests, or code quality gate.
Historically Jenkins jobs were configured using web UI, requiring users to manually create jobs, fill the details of the job and create the pipeline through web browser. Also this makes keeping configuration of the job separated from the actual code being built.
With the introduction of Jenkins Pipeline plugin. This plugin is a Groovy DSL that let's implement you the entire build process in a file and store that alongside its code. Jenkins 2.0 comes by default with this plugin, but if you are using Jenkins 1.X you can install it as any other plugin (https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Plugin)
So now we can start coding our release plugin but for the purpose of this post only stress part is going to be covered. You need to create a file called Jenkinsfile (the name is not mandatory but it is the de-facto name) on the root of your project, and in this case with next content:
In this case we are defining a new stage which is called Stress Test. Stage step is only used as informative and it will be used for logging purposes. Next a node is defined. A node is a Jenkins executor where to execute the code. Inside this node, the source code is checked out from the same location where Jenkinsfile is placed, sets a new environment variable pointing out to the location where the application is deployed, and finally a shell step which executes the Gradle test task.
Last step in Jenkins is to create a new job of type Pipeline and set the location of the Jenkinsfile. So go to Jenkins > New Item > Pipeline and give a name to the job.
Then you only need to go to Pipeline section and configure the SCM repository where the project is stored.
And then if you have correctly configured the hooks from Jenkins and your SCM server, this job is going to be executed for every commit, so your stress tests are going to run continuously.
Of course probably you have noticed that stress tests are executed but no reports are published in Jenkins, so you have no way to see or compare results from different executions. For this reason you can use publishHtml plugin to store the generated reports in Jenkins. If you don't have the plugin installed yet, you need to install it as any other Jenkins plugin.
PublishHtml plugin allows us to publish some html files generated by our build tool to Jenkins so they are available to users and also categorised by build number. You need to configure the location of the directory of files to publish, and here we find the first problem, do you remember that Gatling generates a directory with a random number? So we need to fix this first. You can follow different strategies, but the easiest one is simply rename the directory to a known static name after the tests.
Open Gradle build file and add next content.
We are creating a new task executed at the end of test task that renames the last created directory to averageorbitalperiodsimulation.
Final step is add after shell call in Jenkinsfile next call:
publishHTML(target: [reportDir:'stress-test/build/reports/gatling-results/averageorbitalperiodsimulation', reportFiles: 'index.html', reportName: 'Gatling report', keepAll: true])
After that you might see a link in the job page that points to the report.
And that's all, thanks of Gradle and Jenkins you can implement a continuous stress testing strategy in an easy way and just using code the language all developers speak.
We keep learning,
Alex.
I can live whatever way I please, I move around among the seven seas, No one will miss me when the sun goes down, and in the morning I'be out of town (Movin' Cruisin' - The Fantastic Oceans)
Music: https://www.youtube.com/watch?v=Byg5Xq_pb74
Source Code: https://github.com/lordofthejars/starwars
Etiquetas: Apache TomEE, continuous delivery, gatling, gradle, java ee7, jaxrs, jenkins, pipeline, stress testing
lunes, marzo 07, 2016
Docker and Jenkins - Orchestrating Continuous Delivery
Past week I had the honour of speaking in Docker Barcelona Meetup about how to use Jenkins for doing typical Docker tasks like creating images, publishing them or having a trace of what has occurred on them. Finally I introduced the new (or not so new) Jenkins Pipeline plugin which allows you to create your continuous delivery pipeline by coding it using a Groovy DSL instead of relaying on static steps like happens when you use FreeStyle jobs. At the end I showed how to use it with Docker.
You can see the slides in slideshare or as html.
We keep learning,
Alex.
Hello, it's me, I was wondering if after all these years you'd like to meet, To go over everything, They say that time's supposed to heal ya (Hello - Adele)
Music: https://www.youtube.com/watch?v=YQHsXMglC9A
Etiquetas: continuous delivery, Docker, gradle, jenkins, plugins
viernes, enero 08, 2016
Container Object pattern. A new pattern for your tests.
This reduces the amount of duplicated code and means that if the UI changes, the fix need only be applied in one place.
You can think about Container Object as areas of a container (for now Docker container) that your test might interact with. For example some of these areas could be:
- To get the host IP where container is running.
- The bounded port for a given exposed port.
- Any parameter configured inside the configuration file (Dockerfile) like a user or password to access to the service which the container exposes.
- Definition of the containers.
One way to do this is using Docker to start a FTP server just before executing the test, then execute the test using this Docker container for FTP server, before stopping the container check that the file is there, and finally stop the container.
- Which image is used
- IP and bounded port of host where this FTP server is running
- Username and password to access to the FTP server
- Methods for asserting the existence of a file
Again as in Page Object, any change on the container only affects the Container Object and not the test itself.
The Container Object will be like a simple POJO with special annotations:
- @Cube annotation configures Container Object.
- A Container Object can be enriched with Arquillian enrichers.
- Bounded port is injected for given exposed port.
- Container Object hides how to connect to PingPong server.
Notice that this can be an array to set more than one port binding definition.
Next annotation is @CubeDockerFile which configure how Container is created. In this case using a Dockerfile located at default classpath location. The default location is the package+classname, so for example in previous case, Dockerfile should be placed at org/superbiz/containerobject/PingPongContainer directory.
Of course you can set any other class path location by passing as value of the annotation. CubeDockerFile annotation sets the location where the Dockerfile is found and not the file itself.
Also this location should be reachable from ClassLoader, so it means it should be loaded from classpath in order to find it.
Any Cube can be enriched with any client side enricher, in this case with @HostIp enricher, but it could be enriched with DockerClient using @ArquillianResource as well.
Finally the @HostPort is used to translate the exposed port to bound port.
So in this example port value will be 5000. You are going to learn briefly why this annotation is important.
And then you can start using this container object in your test:
It is very important to annotate the field with Cube, so before Arquillian runs the test, it can detect that it needs to start a new Cube (Docker container), create the Container Object and inject it in the test.
Notice that this annotation is exactly the same as used when you defined the Container Object.
And it is in this way because you can override any property of the Container Object from the test side. This is why @HostPort annotation is important, since port can be changed from the test definition, you need to find a way to inject the correct port inside the container object.
In this post I have introduced Container Object pattern and how can be used in Arquillian Cube. But this is only an small taste, you can read more about Arquillian Cube and Container Object integration at https://github.com/arquillian/arquillian-cube#arquillian-cube-and-container-object
Also a running examples can be found at https://github.com/arquillian/arquillian-cube/tree/master/docker/ftest-docker-containerobject
We keep learning,
Alex.
It's time to see what I can do, To test the limits and break through, No right, no wrong, no rules for me, I'm free! (Let It Go - Idina Menzel)
Music: https://www.youtube.com/watch?v=moSFlvxnbgk
Etiquetas: arquillian, container object, Docker, integration tests, patterns
miércoles, noviembre 25, 2015
Java EE, Gradle and Integration Tests
In the last years Apache Maven has become the de-facto build tool for Java and Java EE projects. But from two years back Gradle is gaining more and more users. Following my previous post (http://www.lordofthejars.com/2015/10/gradle-and-java-ee.html), In this post you are going to see how to use Gradle for writing integration tests for Java EE using Arquillian.
To start using Arquillian, you need to add Arquillian dependencies, which comes in form of BOM. Gradle does not support BOM artefacts out of the box, but you can use dependency-management-plugin Gradle plugin to have support to define BOMs.
- src/integrationTests/java and src/integrationTests/resources as valid source set folders.
- A dependency configuration named integrationTestsCompile which extends from testCompile, and another one called integrationTestRuntime which extends from testRuntime.
- A Test task named integrationTests which runs the tests in the set.
- A Jar task named integrationTestsJar which packages the tests.
Next step is creating the integration tests using Arquillian inside integrationTests test set. For example an Arquillian test for validating that you can POST a color in a REST API and it is returned when GET method is called, would look like:
You can now run integration tests by simply executing gradlew integrationTests
Alex.
There must be more to life than this, There must be more to life than this, How do we cope in a world without love (There Must Be More To Life Than This - Freddie Mercury - Michael Jackson)
Etiquetas: arquillian, continuous integration, gradle, groovy, integration tests, jacoco, java ee
miércoles, octubre 07, 2015
Gradle and Java EE
$ curl -s get.sdkman.io | bash
After that you can init sdkman by running:
$ source "$HOME/.sdkman/bin/sdkman-init.sh"
With sdkman installed, installing Gradle is as easier as running:
$ sdk install gradle
Now you can start creating the build script. The first thing to do is creating a settings.gradle where in this case we are going to set the name of the project.
This file is also used in case of multiple module projects.
Last file you might need is one called build.gradle which manages all the build process.
Sun's in your eyes the heat is in your hair. They seem to hate you. Because you're there. (Wonderful Life - Black)
Etiquetas: continuous delivery, continuous integration, gradle, JavaEE, simpliciy
martes, agosto 11, 2015
Arquillian Cube: Write Tests Once, Run Them Everywhere
Alex.
You’re a shooting star I see, A vision of ecstasy, When you hold me, I’m alive, We’re like diamonds in the sky (Diamonds - Rihanna)Music: https://www.youtube.com/watch?v=lWA2pjMjpBs
Etiquetas: arquillia, arquillian cube, arquillian in action, digital ocean, integration tests
lunes, agosto 03, 2015
Arquillian in Action goes MEAP
Algo lo que me invade, todo viene de dentro, Nunca lo que me sacie, siempre quiero, lobo hambriento. (Por la boca vive el pez - Fito & Fitipaldis)
Music: https://www.youtube.com/watch?v=iUXs4Nt3Y7Y
Etiquetas: announcement, arquillian, arquillian in action, Docker, testing
miércoles, abril 01, 2015
Apache Mesos + Marathon and Java EE
- Running Linux binary
- Cluster-wide process supervisor
- Service Discovery and load balancing (HAProxy)
- Automated software and hardware failure handling
- Deployment and scaling
- REST friendly
So let me explain what's happening here or what Mesosphere does:
And that's all, as you may see Apache Mesos and Marathon is not as hard as you may expect at first.
We keep learning,
Alex.
Dilegua, o notte!, Tramontate, stelle!, Tramontate, stelle!, All'alba vincerò!, Vincerò! Vincerò! (Nessun dorma - Giacomo Puccini)
Etiquetas: Apache TomEE, haproxy, mesos, mesosphere, paas, playa-mesos, vagrant
miércoles, marzo 04, 2015
Restful Web Service Guide
We keep learning,
Alex.
It might seem crazy what I'm about to say, Sunshine she's here, you can take away, I’m a hot air balloon, I could go to space ,With the air, like I don't care baby by the way (Happy - Pharrell Williams)
Music: https://www.youtube.com/watch?v=y6Sxv-sUYtM
Etiquetas: jaxrs, rest, restful web services, scytl
jueves, enero 22, 2015
Self-Signed Certificate for Apache TomEE (and Tomcat)
Generate Private Key
openssl genrsa -des3 -out server.key 1024
Generate CSR
openssl req -new -key server.key -out server.csr
Now that we have the private key and the csr, we are ready to generate a X.509 self-signed certificate valid for one year by running next command:
Generate a Self-Signed Certificate
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
Prepare for Apache TomEE
openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -name test_server -caname root_ca
keytool -importkeystore -destkeystore keystore.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcalias test_server -destalias test_server
And now we have a keystore.jks file created at {userhome}/certs.
Installing Keystore into Apache TomEE
<Service name="Catalina">
<Connector port="8443" protocol="HTTP/1.1"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="${user.home}/certs/keystore.jks" keystorePass="apachetomee"
clientAuth="false" sslProtocol="TLS" />
</Service>
Preparing the Browser
Before starting the server we need to add the server.crt as valid Authorities in browser.
In Firefox: Firefox Preferences -> Advanced -> View Certificates -> Authorities (tab) and then import the server.crt file.
In Chrome: Settings -> HTTPS/SSL -> Manage Certificates ... -> Authorities (tab) and then import the server.crt file.
We keep learning,
Alex.
Dog goes woof, Cat goes meow, Bird goes tweet and mouse goes squeek (What Does the Fox Say - Ylvis)
Music: https://www.youtube.com/watch?v=jofNR_WkoCE
Etiquetas: Apache Tomcat, Apache TomEE, certificate, self-signed
lunes, enero 12, 2015
Apache TomEE + JMS. It has never been so easy.
Business Code
Test
And if you run the test you will receive a green bullet. But wait, probably you are wondering where is the JMS broker and its configuration? Where is the definition of ConnectionFactory and JMS queue? And this is where OpenEJB (and Apache TomEE) comes into to play.
No se lo qué hacer para que me hagas caso, lo he intentado todo menos bailar ballet, ya va siendo hora de mandarte a paseo, si consigo olvidarte tal vez pueda vivir. (Voy A Acabar Borracho - Platero y Tú)Music: https://www.youtube.com/watch?v=aK6oIQikjZU
Etiquetas: Apache TomEE, JavaEE, jms, openEJB, test