Table of contents
- Migration motivation
- Arquillian Ajocado project set up
- Writing tests
- RichFaces Selenium vs. Ajocado API
Migration motivation
Initial reason for migrating was a problem with Maven cargo plugin and its support of JBoss AS 7. In a short time, we also realized how many additional advantages Arquillian would bring into our project.
My task was to prove this concept by porting functional tests of RichFaces showcase app to the Arquillian framework.
Our former functional test suite was written as Selenium tests, more precisely we used our homemade framework (RichfFaces Selenium)
in top of Selenium 1, from which Arquillian Ajocado was born. You can read more about RichFaces Selenium on its author blog.
So the benefits of the new platform - Arquillian + Arquillian Ajocado - were pretty obvious:
- support for various containers (JBoss AS 6.0, JBoss AS 7.0, Tomcat 7 and many others, see this for more)
- some of them are managed by Arquillian, so starting, deploying etc. is done automatically, therefore they are suitable for CI tools like Jenkins for example
- Drone extension brings features of type safe Selenium 1.0 API by providing Ajocado, and also comes with Selenium 2.0 support and it's WebDriver API
- tests rapid development with Ajocado
- Ajocado best feature is not only the type safe API, but also it fills in Selenium gaps with very useful tools for testing Ajax requests, by it's waitAjax and guardXHR methods, which are so essential in AJAX frameworks like RichFaces
- Arquillian future support of mobile devices testing, and current WebDriver support of mobile devices testing with it's Android and iOS plugins.
- last but not least Arquillian is an opensource project with quite big community, it is quickly evolving, and as it is with opensource, when you do not have the feature, you can either easily develop it with support of community (which I found out for myself when I was developing Tomcat managed container for Arquillian) or you can file a feature request.
The only drawback, which we were aware of, was the API incompatibilities between RichFaces Selenium and Ajocado. I will return to them in the end.
Arquillian Ajocado project set up
The best way to set up Arquillian project is described in the documentation. As recommended it is good to configure it as Maven project. The first recommendation fulfilled from RichFaces side.
In short, two configuration files need to be written or altered. Here are the examples of such from migrated RichFaces projects, pom.xml and arquillian.xml.
As you can read in docs, the only thing you need to add to your pom.xml is Arquillian dependencies and some profiles, which represents desired containers on which will be the testing application deployed. There is also an option to run tests from these containers, but in our project it is enough to run them on client.
An example of such dependencies are:
<dependency> <groupId>org.jboss.arquillian.ajocado</groupId> <artifactId>arquillian-ajocado-testng</artifactId> <version>1.0.0-SNAPSHOT</version> <type>pom</type> </dependency> <dependency> <groupId>org.jboss.arquillian.extension</groupId> <artifactId>arquillian-drone-webdriver</artifactId> <version>1.0.0.CR3</version> </dependency>With this, you bring to your project all required Ajocado dependencies, and also WebDriver object. Of course you have other options, like use instead of TestNG the JUnit test framework. For complete set up, again please see the corresponding docs.
Next xml snippet is required Maven profile, which represents container into which our application under test will be deployed. This is an example of JBoss AS 7.1.0.CR1b Arquillian container.
Note that 7.1.0.Final are going to be released soon (7 February 2012), and than it will not take much time to release also arquillian managed dependency. So in order to use newer versions of container, please checkout available maven dependencies (JBoss Nexus) or JBoss AS download page and change accordingly.
Note that 7.1.0.Final are going to be released soon (7 February 2012), and than it will not take much time to release also arquillian managed dependency. So in order to use newer versions of container, please checkout available maven dependencies (JBoss Nexus) or JBoss AS download page and change accordingly.
<profile> <id>jbossas-managed-7-1</id> <properties> </properties> <dependencies> <dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-arquillian-container-managed</artifactId> <version>7.1.0.CR1b</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>unpack</id> <phase>process-test-classes</phase> <goals> <goal>unpack</goal> </goals> <configuration> <artifactItems> <artifactItem> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-dist</artifactId> <version>7.1.0.CR1b</version> <type>zip</type> <overWrite>false</overWrite> <outputDirectory>${project.build.directory}</outputDirectory> </artifactItem> </artifactItems> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.9</version> <configuration> <systemProperties> <arquillian.launch>jbossas-managed-7-1</arquillian.launch> </systemProperties> <environmentVariables> <JBOSS_HOME>${project.build.directory}/jboss-as-7.1.0.CR1b</JBOSS_HOME> </environmentVariables> </configuration> </plugin> </plugins> </build> </profile>When this profile is executed in standard way, mvn -Pjbossas-managed-7-1, the distribution of JBoss AS is downloaded from Maven repo, and unziped to the target directory.
With help of surefire plugin, we then set system property arquillian.launch, which fires the right configuration from arquillian.xml. Indeed you can achieve this by -Darquillian.launch=[correspondingArquillianXMLQualifier]. And lastly, we set up JBOSS_HOME environmental variable,to say to Arquillian where our managed container is installed. Same thing can be achieved by setting up correctly jbossHome property in arquillian.xml.
The last required config file is arquillian.xml, placed on the classpath, so ideal place for it is src/test/resource. Example which set ups config for above mentioned JBoss AS, config for Ajocado, Selenium server and WebDriver would look like:
The last required config file is arquillian.xml, placed on the classpath, so ideal place for it is src/test/resource. Example which set ups config for above mentioned JBoss AS, config for Ajocado, Selenium server and WebDriver would look like:
<arquillian xmlns="http://jboss.com/arquillian" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jboss.org/schema/arquillian http://jboss.org/schema/arquillian/arquillian_1_0.xsd"> <engine> <property name="maxTestClassesBeforeRestart">10</property> </engine> <container qualifier="jbossas-managed-7-1"> <configuration> <property name="javaVmArguments">-Xms1024m -Xmx1024m -XX:MaxPermSize=512m</property> <property name="serverConfig">standalone-full.xml</property> </configuration> <protocol type="jmx-as7"> <property name="executionType">REMOTE</property> </protocol> </container> <extension qualifier="selenium-server"> <property name="browserSessionReuse">true</property> <property name="port">8444</property> </extension> <extension qualifier="ajocado"> <property name="browser">*firefox</property> <property name="contextRoot">http://localhost:8080/</property> <property name="seleniumTimeoutAjax">7000</property> <property name="seleniumMaximize">true</property> <property name="seleniumPort">8444</property> <property name="seleniumHost">localhost</property> </extension> <extension qualifier="webdriver"> <property name="implementationClass">org.openqa.selenium.firefox.FirefoxDriver</property> </extension> </arquillian>In this file we defined that the maximum number of tests classes which will be executed is 10. Then the container will be restarted. This is a workaround for famous OutOfMemory exception: PERM_GEN thrown after multiple deployments on containers. The number 10 was chosen by multiple running the suite and it seems for now that this is the optimal number of tests, but you should test your test suite and you should choose your number. See also the MaxPermsSize, set for all containers for a quite big chunk of memory, this is also due to above mentioned error.
Next configuration is for JBoss AS managed container, there is JBOSS_HOME omitted since we are setting it up in pom.xml. Then there are additional JVM arguments, mainly increasing the permanent memory size and heap size. These setups seems to be the best effective, we can manage to run 10 test classes and run it quickly.
Configuration for selenium server consists from property browserSessionReuse, which determines whether the same session of browser should be use, in other words whether there will be start of new browser after each test. The true value accelerates tests quite dramatically. Selenium server need to be run for Ajocado tests, for WebDriver not. For further configuration options, please see the docs.
There is also a need to alter your Java code, to run with Arquillian. If you will be following docs, you will be successful for sure. I am just providing our approach.
We have one base class which is common for whole test suite. It contains method for deploying application under test. We are deploying whole application for all test classes, which will be probably replaced by deploying only what is needed, with help of ShrinkWrap project. This improvement should accelerate the testing.
Since we want to write both Ajocado and WebDriver tests we are providing two classes which particular tests will extends. It is not possible now to have Ajocado and WebDriver objects simultaneously accessible from the same test class.
Writing tests
So, as I mentioned above, to run successfully test, there should be:
Method for deploying application under test:
Method for loading correct page on the browser:
Writing tests
Writing tests with Ajocado and Arquillian is really simple and fast. It is so because of Ajocado is targeting on rapid development with his OO API as much as possible. With these features and modern IDE code completing, it is more pleasure than struggle to write tests. This is an example of such test, lets examine it further.
So, as I mentioned above, to run successfully test, there should be:
Method for deploying application under test:
@Deployment(testable = false) public static WebArchive createTestArchive() { WebArchive war = ShrinkWrap.createFromZipFile(WebArchive.class, new File("target/showcase.war")); return war; }We are deploying a war, which was copied into project build directory with help of Maven dependency plugin. This method is located in the parent of test, as it is the same for all tests. The argument in the annotations stands for running tests on the client rather than on server side.
Method for loading correct page on the browser:
@BeforeMethod(groups = { "arquillian" }) public void loadPage() { String addition = getAdditionToContextRoot(); this.contextRoot = getContextRoot(); selenium.open(URLUtils.buildUrl(contextRoot, "/showcase/", addition)); }
We have set our tests that it is loading the correct page according to the test class name, so the method getAdditionToContextRoot is dealing with it, the context root can be set in arquillian.xml and finally you just load that page as you are used to with Selenium 1, but again instead of String you are using higher object. Just note that if you are using testng.xml for including some test groups, you need to add you before, after ... methods to the group arquillian, and also to include this group in particular testng.xml
protected JQueryLocator commandButton = jq("input[type=submit]"); protected JQueryLocator input = jq("input[type=text]"); protected JQueryLocator outHello = jq("#out"); @Test public void testTypeSomeCharactersAndClickOnTheButton() { /* * type a string and click on the button, check the outHello */ String testString = "Test string"; //write something to the input selenium.typeKeys(input, testString); //check whether after click an AJAX request was fired guardXhr(selenium).click(commandButton); String expectedOutput = "Hello " + testString + " !"; assertEquals(selenium.getText(outHello), expectedOutput, "The output should be: " + expectedOutput); }
I think the test is pretty much self explanatory. Here you can also see the differences between Selenium 1 and Ajocado. Aim mainly your focus on the fact that Ajocado uses various objects instead of just String for everything. In this example it is JQyeryLocator, which provide convenient and fast way for locating page elements by JQuery selectors.
RichFaces Selenium vs. Ajocado API
The API differences where one of the last problems we had. As we were using RichFaces Selenium, which has very similar API to Ajocado, the migration could be done automatically. However, at first I had to migrate the whole suite manually to see exactly the differences. With the list of API changes I was able to develop small Java app to automate this migrating in future. It was created mainly for our purposes, as there were new tests to migrate each day, but you can accommodate that app for your purposes too. It is nothing big, it can be probably easily done in bash, but I am quite weak in bash scripting, so I did in Java.
For complete Ajocado vs. RichFaces Selenium differences, please visit the mention app sources, where you can find all. Here I am providing just the most important ones:
Richfaces Selenium | Ajoado |
---|---|
ElementLocator.getAsString | ElementLocator.getRawLocator |
AjaxSeleniumProxy.getInstance() | AjaxSeleniumContext.getProxy() |
SystemProperties | SystemPropertiesConfiguration, and its methods are no more static, for example seleniumDebug is retrieved in this way: AjocadoConfigurationContext.getProxy().isSeleniumDebug() |
JQueryLocator.getNthOccurence | JQueryLocator.get |
RetrieverFactory.RETRIEVE_TEXT | TextRetriever.getInstance() |
removed getNthChildElement(i) | can be replaced by JQueryLocator(SimplifiedFormat.format("{0}:nth-child({1})", something.getRawLocator(), index)); |
RequestTypeGuard | RequestGuardInterceptor |
RequestTypeGuardFactory | RequestGuardFactory |
RequestInterceptor | RequestGuard |
CommandInterceptionException | CommandInterceptorException |
keyPress(String) | keyPress(char) |
keyPressNative(String) | keyPressNative(int), so it is possible now to use KeyEvent static fields directly |
isNotDisplayed | elementNotVisible, what is important about all displayed vs visible change is that visible methods will fail when the element is not present, displayed methods will return true, so keep it in mind while using visible methods, whether you need to use at first elementPresent |
selenium.isDisplayed | selenium.isVisible |
selenium.getRequestInterceptor() | selenium.getRequestGuard() |
clearRequestTypeDone() | clearRequestDone() |
waitXhr, waitHttp | guard(selenium, RequestType.XHR), guard(selenium, RequestType.HTTP) |
FrameLocator | it has now two implementations FrameIndexLocator and FrameDOMLocator |
ElementLocator methods | almost all mothods were removed, only few lasted, since now ElementLocator is implementing Iterator interface, and it is possible to replace them easily with it. Example of this is here (see the initializeStateDataFromRow method) |
Have you looked at ShrinkWrap.create(MavenImporter.class) instead of ShrinkWrap.createFromZipFile(WebArchive.class, new File("target/showcase.war")) ?
ReplyDeleteWe're using it here:
https://github.com/droolsjbpm/guvnor/blob/master/guvnor-webapp-drools/src/test/java/org/drools/guvnor/server/GuvnorTestBase.java#L46
Thanks for pointing on some usages, these deployments methods will be refactored in our projects.
DeleteBut to be sure, my way is bad because of drawbacks mentioned in comment:
https://issues.jboss.org/browse/SHRINKWRAP-325?focusedCommentId=12626898&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12626898
?
Everyone wants to get unique place in the IT industry’s for that you need to upgrade your skills, your blog helps me improvise my skill set to get good career, keep sharing your thoughts with us.
ReplyDeleteselenium training in chennai|
selenium training in bangalore|
Whoa! I’m enjoying the template/theme of this website. It’s simple, yet effective. A lot of times it’s very hard to get that “perfect balance” between superb usability and visual appeal. I must say you’ve done a very good job with this.
ReplyDelete<a href="http://www.traininginmarathahalli.in/dot-net-training-in-bangalore/”> Dotnet Training in Marathahalli </a>|
I have to voice my passion for your kindness giving support to those people that should have guidance on this important matter.
ReplyDeletehadoop training in bangalore
big data training in chennai
It was as great as I didn't even expect.
ReplyDeleteBig data training in chennai | Hadoop training in chennai
Dot Net Training in chennai
The way you have expressed your thoughts in this blog was nice with clear explanation. Thanks for sharing.
ReplyDeleteGerman Classes in Adyar
German Classes in Velachery
French Classes in Velachery
French Classes in Tambaram
Selenium Training in Chennai
Big Data Training in Chennai
Thanks For Your valuable posting, it was very informative
ReplyDeletereviewcouncil
Article submission sites
Innovative thinking of you in this blog makes me very useful to learn.i need more info to learn so kindly update it.
ReplyDeleteCloud computing Training
Cloud Computing Training in Anna Nagar
Cloud Computing Training in T nagar
Cloud Computing Training in OMR
This technical post helps me to improve my skills ,thanks for this wonder post I expect your upcoming blog, so keep sharing...
ReplyDeleteSpoken English in Chennai
Best Spoken English Institute in Chennai
English Coaching Class in Chennai
Best English Coaching Center in Chennai
English Coaching in Chennai
English Coaching Centre in Chennai
English Courses in Chennai
English Coaching in Chennai
Spoken English Institutes in Chennai
One of the best blogs that i have read still now. Thanks for your contribution in sharing such a useful information. Waiting for your further updates.
ReplyDeleteIELTS Coaching in Mulund | IELTS Training in Mulund West | IELTS Centres in Mulund East | Best IELTS Coaching Institute in Mulund | IELTS Courses in Mulund | IELTS Coaching Centres in Mulund | IELTS Training in Mulund
It is really an awesome post. Thank you for sharing this wonderful information.
ReplyDeleteCorporate Training in Chennai | corporate training | corporate training companies | Corporate Training in Adyar | Corporate Training Institute in Velachery | Corporate Training Institute in Tambaram
Thanks for your sharing such a useful information. this was really helpful to me.
ReplyDeleteInformatica Training
Learn Informatica
Informatica course
Informatica MDM Training in Chennai
This post is very nice.It will be used for improve our self.Truely well post.Keep it up.
ReplyDeleteEthical Hacking Certification
Ethical Hackingp Training in Nolambur
Ethical Hacking Training in Saidapet
Learned a lot from your blog. Good creation and hats off to the creativity of your mind. Share more like this.
ReplyDeleteSpring Training in Chennai
Spring course in Chennai
Spring Hibernate Training in Chennai
Spring Hibernate Training
Struts Training
Struts Training near me
It was really a nice article and I was really impressd by reading this.
ReplyDeleteThank you for such amazing post. Keep up the good work.
Primavera Training in Chennai
Primavera Course in Chennai
Primavera Software Training in Chennai
Best Primavera Training in Chennai
Primavera p6 Training in Chennai
Primavera Coaching in Chennai
Primavera Course
Thanks for a marvelous posting! I definitely enjoyed reading it, you could be a great author.I like your post.
ReplyDeletePHP Training Institute in Bangalore
PHP Training in Bangalore
PHP Course in Mogappair
PHP Training in Chennai Annanagar
PHP Classes near me
PHP Training Institute in Velachery
PHP Course in Padur
PHP Training in Tambaram
Great Post. It shows your deep understanding of the topic. Thanks for Posting.
ReplyDeleteNode JS Training in Chennai
Node JS Course in Chennai
Node JS Advanced Training
Node JS Training Institute in chennai
Node JS Training Institutes in chennai
Node JS Course
https://vodafonecustomercarenumber.hatenablog.com
ReplyDeletehttps://vodafonecustomercarenumber.hatenablog.com
https://mpcustomercareno.blogspot.com
https://mpcustomercareno.blogspot.com
https://myairtelcustomercarenumber.blogspot.com
https://myairtelcustomercarenumber.blogspot.com
It was really fun reading ypur article. Thankyou very much. # BOOST Your GOOGLE RANKING.It’s Your Time To Be On #1st Page
ReplyDeleteOur Motive is not just to create links but to get them indexed as will
Increase Domain Authority (DA).We’re on a mission to increase DA PA of your domain
High Quality Backlink Building Service
Boost DA upto 15+ at cheapest
Boost DA upto 25+ at cheapest
Boost DA upto 35+ at cheapest
Boost DA upto 45+ at cheapest
nices information thanku so much this information
ReplyDeletethanku so much
nices
Think This Is Owsm Post, But If You Check This INTERACTIVE BROKERS
ReplyDeleteWant To Trade Forex With AVATRADE REVIEW ? Read This Blog First To Find Out About The Best Forex Trading Conditions. We Review The Most Popular Forex Brokers And Tell You What You Need To Know.
ReplyDeleteEn son çıkan perde modelleri
ReplyDeleteSms onay
vodafone mobil ödeme bozdurma
Nft Nasıl Alinir
ANKARA EVDEN EVE NAKLİYAT
TRAFİK SİGORTASİ
dedektor
websitesi kurma
ASK ROMANLARİ
Thanks For Your valuable posting, it was very informative
ReplyDeletejewellery erp software
Jewellery erp software
Thanks For Your valuable posting, it was very informative
ReplyDeleteJewellery ERP Software UAE
Jewellery ERP Software UAE