JMeter, CQ SmokeTesting, and much much more

JMeter, CQ SmokeTesting, and much much more

Sometimes when trying to solve one problem, I discover the answer to another yet undiscovered problem.

My pet peeve with CQ development is detecting in a semi-automated painless fashion, when templates, components or client side functionality are broken.  While JUnit integration testing catches some issues, what about "client side" integration testing?  The question is, how do you make sure the build you just pushed with Jenkins, that was green, didn't break the functionality of a component, template, service, etc?.  The interaction of classes, JSP's (page and content components), and the client.  Yes, I know there are Sling bundles to allow server side JUnit testing, and I have found a few others as well.  When you don't have any of the foundation for this kind of testing, nor the time to create it and your timeline is tight with NO wiggle room, what do you do?

If you view the pages in FireFox, IE, Chrome, whatever, the effect of the last build is obvious.  OK - lets use Selenium.  Well, that needs some foundation building as well.  It has "macro recording" - but my recollection of that is it was a PITA.  Maybe it is better today than what I remember, but after 15 minutes of frigging with it I abandoned it to a later date when I have more "free range" thinking time.  That day is not today.

I wrote some scripts that use the JSON Query Servlet to find all page paths within a branch, contruct URL's both with and without request parameters (to control Dispatcher caching), then iterate through each one executing a curl GET.  This was OK, and produces some nice page load statistics.  I even extrapolated this to do the same thing for all components, on all pages within a branch.  It also reports all 404's - which is really what I was after.  What is broken.  I want to know what is broken before QA and UAT knows what is broken.  I even used both of these in conjunction with a Unit testing framework HtmlUnit.  It does generally the same thing as the other two scripts, but HtmlUnit claims (seems to work, at least to me) to have some Client Side functionality.  That is, it will execute some of the JavaScript.  The script will either stop, or simply report JavaScript errors when they happen.

Being technologically discontented, as I typically am, wondering "how can I do this better", I wondered how I could leverage my old friend JMeter.  So, I wrote another script, leveraging the above "foundational" scripts to produce configuration chunks of a JMeter test plan.  Thats when I wondered, "how can I generate the whole test plan" automatically?

That my friends is when I discovered that JMeter runs as a proxy server.  So you say, why don't I use the proxy server that comes with CQ?  Take note: the CQ proxy server is useful, and you will undoubtedly use it at least once in your CQ career.  But, can the CQ proxy server generate a fully executable JMeter test plan?  That you can run over, and over, and over.....  And this is when I realized the true value of this methodology of working with CQ and JMeter.

Remember how the whole CQ stack is RESTful, everything is accessible from a URL?  Well you know have a way of discovering how to interact with CQ through it's RESTful interface TO DO ANYTHING.

I wanted a scripted way to create two dozen pages, and set some page properties on those pages.  It would have taken me an hour or so to do this manually, maybe less, maybe more.  While I spent maybe an hour writing the script, and figuring out the guts of the page creation and property setting logic, I now have a repeatable, reliable process for doing so with any set of pages.

I fired up JMeter, creating the proxy.  I fired up my favorite browser, configured it to use my HTTP proxy, logged into CQ (which was recorded by JMeter), created a page, set a property.  The I went back and looked at the JMeter test plan to find the HTTP PUT's that handled the page creation and the property setting.  I could have used to figure some of it out, but this approach gives you THE DEFINITIVE ANSWER, with no doubt as to how to accomplish the task.

This example uses JMeter 2.9, here is the zip and the tgz binary downloads.  Download, unpack, and run

  1. Add a ThreadGroup to the Test Plan.  Right click on Test Plan > Add > Threads (Users) > Thread Group
  2. Add HTTP Request Defaults to the Thread Group.  Right click Thread Group > Add > Config Element > HTTP Request Defaults
  3. Add a Recording Controller to the Thread Group.  Right click Thread Group > Add > Logic Controller > Recording Controller
  4. Add HTTP Proxy Server to WorkBench,  Right click WorkBench > Add > Non Test Element > HTTP Proxy Server
  5. Configure HTTP Request Defaults: IP Address is the address of your CQ instance, and Port Number is it's port.  Leave implementation empty, and use "http" in the Protocol textbox.  Set Content Encoding to UTF-8.
  6. Configure HTTP Proxy Server: use an open port value (over 1000) for Port, for Target Controller select "Test Plan > Thread Group > Recording Controller" and leave everything else alone.  Click the "start" button at the bottom.

Setting the HTTP proxy server that a browser uses varies from OS to OS.  A quick Google search will net you a bunch of articles on how to do this, if you don't know how already.  Set your HTTP proxy host to 'localhost' and the port value to the one you selected in step 6 above.  Now login to your CQ instance, using its IP address and port number.  You will quickly see the "Recording Controller" fill up with elements.  Browse through these, in fact look for the login request.  This one will have as a Name: /libs/cq/core/content/login.html/j_security_check - you now know (maybe already knew) how to script a login to CQ.  Try other operations, like creating a tag, moving a page, deleting a page, go crazy.

I hope you get as much enjoyment and use out of this incredibly simple approach to transparently interacting with CQ.  I know I am still dreaming of the possibilities of using this for testing, troubleshooting, debugging, scripting....


Share this post


comments powered by Disqus