meeeehhh

when everything is just meh…
Twitter
Follow me on Twitter

Selenium + JMX Conclusion

So I kind of “finished”… well I just got bored with the topic :P you can see the results at github.

Above all I can just say that the combination of selenium with jmx works fine although i havent tested very complex test cases and the data i injected was kind of trivial. However the setup was easy, so was the handling in the tests, as you just use the same api as you application. writing the page objects is a little pain but there are some solutions for that out there…

However there are some limitation to this construct using jmx. It looks like you are just using your api on your objects but for example the objects you want to use as method arguments have to implement Serializable. This kind of ugly if you actually don’t want them to be or there is no other reason for them to be serializable. Also if you make changes on the given objects in your api methods, those are not transmitted back to the test client through jmx. So if you need some values returned, you actually need them to be returned (see PersonService.save() in the example app). I also had to add api methods my app usually would not need (deleteAll method). So it is not actually just activating jmx and the fun can start… you have to adapt your app in order to make this construct work.

 

Open Questions:

  • Whats up with the performance? In the simple tests the test execution was way faster than even starting the browser. But what if you need to insert masses of data
  • This works fine for simple apps that have not too much data (a simple jdbc/jpa or something app that is actually just a crud app). What about apps that have more complex data or data storages? for example a coremedia content repository that might contains gigabytes of data, the data also contains application configuration and you do not even know how the content storage works internally… or what if your data need further processing or analyzing for your app to work
  • what happens to sessions that depend on the test data that you might trash on each test. is there in selenium some kind of reset? other than restarting the browser?

More remarks:

  • for complex data you would need more than a “deleteAll” method. You would probably create data initialization spring beans either in your app or your test client
  • In the example, all test cases use the same spring configuration. If you have different test suites each would use another configuration including spring beans for data intialization
  • in the example app i raped the maven test fork (src/test) for the selenium tests. in a real setup i would have created a new app just for the selenium tests. the test fork is just for actual unit test (at least in my option). you then have to include your app as a dependency in your test app or create a maven modules for your app code (the api you want to use) and include this one
  • ….

The first test

So I wrote the first test… As I want to access the app using jmx later i used spring to setup my unit tests. meaning i wanted to instantiate my WebDriver (in this case firefox) and my page objects with spring. I configured the spring beans using xml, but that is just annoying, at least using the architecture i chose….

I read the Page Objects wiki page from selenium (here). At first it all makes sense: you use the page objects to hide selenium from your actual tests in order to make them more readable and easier to write. Also the DSL stuff makes sense (however i dont like that for now as my tests are just plain simple without much clutter). But they are also suggesting to return other page objects when you are changing to another page by using new PageObject(). And that seems a little gross to me as you might have many page objects and you have to instantiate all of the by hand? lame…

public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;
    }

    public HomePage loginAs(String username, String password) {
        driver.findElement(By.id("username")).sendKeys(username);
        driver.findElement(By.id("passwd")).sendKeys(password);
        driver.findElement(By.id("login")).submit();

        return new HomePage(driver);
    }
}

So I thought it might be better to instantiate them all using spring and inject all sites / page objects that a site can refer to into that page object. And when a change to another site happens the correct page object is returned.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/config/spring-config.xml")
public class AddTest {

	@Autowired
	private ListPage listPage;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
	}

	@Test
	public void test() {
		listPage.open();

		AddPage addPage = listPage.clickAddPage();

		addPage.setFirstname("Peter");
		addPage.setLastname("Pan");
		addPage.submitForm();

	}

}
public class ListPage extends Page {

	private AddPage addPage;

	private final String path;

	/**
	 * @param addPage
	 *            the addPage to set
	 */
	public void setAddPage(AddPage addPage) {
		this.addPage = addPage;
	}

	public ListPage() {
		path = "/list";
	}

	public AddPage clickAddPage() {

		WebElement link = driver.findElement(id("addLink"));
		link.click();

		return addPage;
	}

	public void open() {
		driver.get(baseUrl + path);
	}

}

however this creates too much logic in the page object. For now it does not seem that way but if you have a bigger site with many links and what ever you will have some pain maintaining your page objects to return the correct next page object (maybe depending on the given input). and also i configured everything with xml… so that is even more pain…. i like having xml in the application itself for reasons of configuration with maven and everybody in the team knows where to look when there is a problem with spring. however i will refactor the test to using annotations and autowiring as much as possible just because its easier….
back to topic: i think returning page objects other than this when using them DSLstyle makes maintaining your tests much harder later as they grow. I will inject my page objects directly into my test case and just use them as i need them. this way i reduce dependencies between the page objects and i can work more freely in my tests as i can do whatever i like and do not depend on whatever the page objects dictate.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">

		<!-- Scan for page objects -->
		<context:component-scan base-package="us.getit.hitlist.page" />

		<!-- our "browser" -->
		<bean id="driver" class="org.openqa.selenium.firefox.FirefoxDriver" destroy-method="close" />

		<util:map id="configData" key-type="java.lang.String" value-type="java.lang.String">
			<entry key="baseUrl" value="http://localhost:8080/hitlist" />
			<entry key="listPage" value="/list" />
			<entry key="addPage" value="/add" />
			<entry key="showPage" value="/show" />
		</util:map>

</beans>
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/config/spring-config.xml")
public class AddTest {

	@Autowired
	private ListPage listPage;

	@Autowired
	private AddPage addPage;

	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
	}

	@Test
	public void test() {
		listPage.open();

		listPage.clickAddPage();

		addPage.setFirstname("Peter");
		addPage.setLastname("Pan");
		addPage.submitForm();

	}

}
@Component
public class ListPage extends Page {

	@Value("#{configData.listPage}")
	private String path;

	public void clickAddPage() {

		WebElement link = driver.findElement(id("addLink"));
		link.click();

	}

	public void open() {
		driver.get(baseUrl + path);
	}

}

There is one downside to this approach: I will have to create a method on each page object to check that i am actually on the given page right now… but as i think about it i might dont even need that… my test will just fail when i am not on the correct page… so no need for that… or is there? we’ll see….

On the other hand they also said that you should individual page objects for your tests. I am too lazy to do that for now… so that argument doesnt count

The Hitlist

So in order to do the slenium jmx test thingy i talked about in the last post i needed to have some simple test app. so i thought just take 1 hour and do it… out of 1 hour (like usually) became like 5 hours… thanks to eclipse and maven (again, like usually) and the hideous of trying out spring 3.1 with java based configuration instead of using a web.xml… more on that topic later…

first: here is the awesome app https://github.com/suicide/hitlist (yeah using git… how awesome is that? not at all…)

The app is basically a simple crud app with 1 “entity” and one service. The entity is not stored in a database but in a map within the service… best if you take a look yourself… just like 5 classes. however this should suffice to test the selenium + jmx test setup.

So why did it take so fucking long to setup this this time?

1. eclipse  + maven: so i used indigo for the first time for something “bigger” with a “propper” setup. So after installing all my plugins (spring tools, more unit, [m2e was already there as it is not part of eclipse], git, subclipse…. blah) i created the app and wanted it to start in tomcat 7 (yeah servlet 3.0 … :( ). but there was no “run on server”. Where was it? last week i had the same problem at work and accused our student worker of being stupid :P (so even it was not his fault… still…)… so now i have the same problem… but i am not stupid… so something must be horribly wrong with eclipse and maven. so some google magic… voila: http://stackoverflow.com/questions/6356421/maven-tomcat-projects-in-eclipse-indigo-3-7 apparently wtp is not installed by default… you have to get it through the awesome market place… ok… lame…
so after “update project configuration” i got it up and running

2. java configuration instead of web.xml: so with spring 3.1 and servlet 3.0 you can use java configuration instead of the web.xml. so worth a try… so some reading and some copy pasta from the javadoc almost ready…. some changes in the pom and some try and error and just giving up because i was bored (as you can see in the code) and it was not important right now…. so actually not much of a problem

hmm ok as i think about it… i dont know why it took so long… maybe shouldnt have watched tv and lurked the web… damn

 

so whats up next? write some selenium test and use jmx to add test data to the system…

The Pain of Test Data in Integration Tests

I must be a geniusSo imagine you have some kind of a web app that you’d like to test using selenium or canoo webtest… well you better do not use webtest because it looks great at first… but its a fucking pain later… especially if you created your tests using the xml definitions. You have no way to validate if your configuration is valid… and you just have hundreds of those files…

however selenium is different… you can run the tests using junit… so its easy to integrate them into your nightly build. But there are enough posts around that cover how you can use selenium…

I’d like to think about test data… the data you want to inject into your application for your tests to run on.

There are some requirements towards test data that are not easy to fulfill:

  • Sometimes you need large masses of test data (for example if u want to test your paging)
  • Sometimes you just need a small set of data
  • your test data has to be valid
  • the data needs to be easy to handle
  • the data needs to be easy to extend
This is all that i could think of right now… but we also have different roles we need to consider if we want to design our test data: developers and testers…. damn testers…
As a developer i want to write my selenium test as fast and easy as possible… just like a unit test. but that is not so easy as we are trying to do an integration test… so there are so damn mocks… just the real thing… at least somehow. And a real tester does have a big concept for his tests and his test data… well at least i hope he does… and he probably has masses of test data that is specified to the last bit so he can test each use case with this data set. (Thats just what i imagine from a test… so prove me wrong…)
So is there a way to bring these to worlds together? I dont know… but as a developer i’d like to follow the KISS principle… for you dummies: keep it simple stupid
First of all: I create test suites for each component of my application and each test suite is provided with its own set of test data… well maybe there is some basic data each test needs that we need to provide globally but thats up to the app. So this way we keep the test data sets simple. we only provide the data we need for the test just as you would do in a unit test. for some tests we just need 1 or 2 test object and others need 20 objects but not the same as other tests. This way we keep the data sets from interfering with each other (changing data for test A will cause test B to fail because the some fucking objects pop up and we have to just change some counter from 8 to 9 just because of that without any sense of knowing if this is even ok..)
Ok but what if we need like 100 similar test objects to do something? – well first i am thinking of creating them just in java… we’ll see…
And how to insert the data into the system? and how can we guarantee that the data is valid? SQL inserts? But what if we do now have a SQL DB? – How a about providing an API to insert the data through the application itself… maybe a REST api or a webservice… but if our app does not have one? build one?…. what about JMX? we can export out service interfaces to the tests and insert the data directly through our services. and with Spring it is just some small configuration we need to add and voila… our selenium test client can access the services and insert data and even use the applications entities or model objects. and if the application is not in test mode we just do not load this configuration.
Sounds easy? yep… thats what i am thinking… so lets try it… I will build a simple web app and test it via selenium and inject data through jmx

Solr, MS SQL Server and the damn date format

So I thought I had a simple task at work for the last couple of days: get the delta import feature of Solr to work!

And of course everything took just 10 times longer than expected, but I should be used to that by now. After all I am already in this business for like 5 years… whatever.

After upgrading our Solr installation the delta update was working fine on my local mysql datasource. So I upgraded and reconfigured one of our test installations using MS SQL server and voila -> indexing failed, SqlException. Ok the date format was not correct. Well who would have guessed that sql server is doing everything different from everybody else…

So a little googling on how to change the accepted date format in sql server -> no luck here (well actually there was so much stuff to read that I just gave up at once). Next step: check the !awesome Solr documentation. Ok there is a formatDate function that just uses SimpleDateFormat (yay). So just hack everything in that awesome sql query (${dataimporter.functions.formatDate(dataimporter.last_index_time, ‘yyyy-dd-MM HH:mm:ss’)} or something like that [but check that stupid dateformat sql server seems to get]) and go! meh…. a god damn null pointer (as if i didnt have enough of those bastards before upgrading Solr) [It seems like the functions "namespace" is empty or does not exist... whatever i dont care anymore]. And after hours of searching the internets, the great documentation and even reading the code… nothing.

So back to sql server and doing some quick and dirty (t-)sql shit coding… CONVERT(datetime, ‘${dataimporter.last_index_time}’, 120)

Ok thats it… just wanted to blow off some steam… just spend almost a complete day on this… just to do things properly… damn

Workmeter – Track your working hours

Over the last year some friends and I had been working on a little project we called workmeter. You can find it at http://workmeter.net

The idea for the project came to us when each of us had to track his working hours manually either to figure out how much money he made busting tables or how much overtime he made by sitting at work all night lurking the internetz “working”. So we were like: lets do a quick software project (lol what fools we were back then…) on just one weekend without a concrete concept (we actually called that “agile”) with that cool php framework symfony 1 (no judging here… well maybe a little bit). Ok that kind of a shitty idea… as I said earlier it did not take us one weekend but a little more than a year to finish it up and release a “stable” alpha version. And after releasing a second alpha version it really works just great without any complaints now for months.

So what does it do? It tracks your working hours and can either show you how much money you have earned on a day, within a week, month or year if you are paid by the hour. If you like to track your overtime, it can do that for you. You just write down from when to when you worked on a day and workmeter will show you some statistics how much you worked and if you worked enough. You can also write down what you did in that time and copy that into your company’s internal time tracking tool. It has so many great features (thats why it took so long to finish and why it was so hard to do in php because testing this stuff was just horrible and symfony was not fitting for complicated stuff like crunching numbers on masses of data and stuff)… ok so many features I cannot write the all down here, but here are some more: great statistics (yes, there are DIAGRAMS!) planing your vacations and your sick days…

Ok I hope you go an checkout workmeter.net

At last a screenshot of this fine webapp:

Started that object rendering taglib

So I started writing my own object oriented rendering JSP taglib as I could not find anything like that anywhere. Ok I just played around with taglibs in general because I had no idea how to write Java tags, I only did JSP tags before.

I asked google and stackoverflow and came up with this little sample tag class:

public class SampleTag extends TagSupport {

	private Object o;

	@Override
	public void setPageContext(PageContext pageContext) {
		super.setPageContext(pageContext);

	}

	@Override
	public int doStartTag() throws JspException {

		try {
			pageContext.getOut().flush();
			ServletRequest req = new HttpServletRequestWrapper((HttpServletRequest) pageContext.getRequest()) {
				private final Map wrappingAttributes = new HashMap();

				@Override
				public void setAttribute(String name, Object o) {
					wrappingAttributes.put(name, o);
				};

				@Override
				public Object getAttribute(String name) {
					Object o = wrappingAttributes.get(name);
					if (o != null) {
						return o;
					}
					return super.getAttribute(name);
				};

			};
			req.setAttribute("something", o);
			pageContext.getRequest().getRequestDispatcher("/WEB-INF/jsp/blubb.jsp")
					.include(req, pageContext.getResponse());
		} catch (ServletException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			throw new JspException(e);
		}

		return SKIP_BODY;
	}

	public void setSomething(Object o) {
		this.o = o;
	}

}

I must admit it is not very pretty (yet) but it does some stuff. For now I am able to pass a variable something through the tag to another JSP (blubb.jsp). And as I put the object in my request wrapper it can be used in the blubb.jsp. I used the wrapper because I did not want to write in my actual request (who the fuck knows what will happen if I mess with that :P ). But the question is what happens if I use the tag within my blubb.jsp again? Is a new instance of the tag class created on each use and will there be problems with the wrapped request then?

Also is this the best way to include a JSP? you might wonder why I need to flush the out at the beginning of the method… well if I don’t do that it my included jsp is rendered first before the jsp using my tag… but this flush causes the site being transfered to the browser before it is completely rendered which kind of gives me cancer. I cunt pasted that bloody dirty piece of code from here

Also here is the tld of my little taglib (copy pasta from JSTL core):



	Sample taglib
	1.0
	sample
	http://meh.get-it.us/taglib/sample
	
		sample
		agagagag.SampleTag
		empty
		
			something
			true
			true
		
	

Object rendering JSP Taglib

As of now I am a super awesome CoreMedia developer! Well ok I am not quite there yet, but I attended the Web Application Developer, Advanced Web Application Developer and the CAE Caching training over the last couple of weeks. I still have to prove myself in a real CoreMedia project, which might be happening sooner than later (at least I am told so).

Anyway, one thing that is quite nice in the CoreMedia CAE is the object oriented view dispatcher and the cm taglib, especially the cm:include tag. This whole mechanism makes use of the document model inheritance hierarchy (which is kinda gross for a poor web developer who is used to work with Pojos). If you dont know what I am talking about: all your Content Beans (you can roughly think of them as your entities) are related to each other through this inheritance hierarchy. The following awesome almost UML diagram (I used openOffice drawing for the first time) will make everything much more clear:
Document Model

Ok when you use the object oriented view dispatcher it looks up JSP templates for your objects. So if you return an instance of an Article in your Spring controller it would try to find a Article.jsp. If it cannot find such a template the dispatcher will continue by searching for a Teasable.jsp and further to Document.jsp and at last try to find an Object.jsp. So it tries to find a JSP template that is named after the class of your object, an interface your object implements or a super class (just in that order). After i heard this I was like: ok that nice but I can also just return the name of my jsp… that is not much of an improvement.

Now come the trick: the cm:include tag works kind of the same way. Meaning you pass a object to the tag and it includes the appropriate template. Combined with with “views” you can easily create huge template structures (by passing a view string “render” the tag would look for a “Article.render.jsp”). So you can say tiles and its gross configuration and structure good bye!

So my question now is: Is there such a object include taglib or even a view dispatcher out there that works kind of the same?

Language conditional caching in symfony

So I finally found a topic that was worth writing about: language conditional caching in symfony 1.4!

The symfony tutorial (Practical symfony) desribes i18n and caching in detail. So I thought: this is gonna be a piece of cake -> but NO ITS NOT :( . In their tutorial they set the language through a parameter in the url, like http://somewhere.com/en/something for english and http://somethere.com/de/something for german. But what if you keep you culture setting stored in the session?! Well then you get a little fucked.

Without caching everything works just fine. You can switch between languages and everything. But if you activate caching on an action or a partial everything is still ok on the first request. But if you change the language, something weird happens: you still see the FIRST language. Ok you think… maybe the browser cache… WRONG! its symfony’s cache. Just look in the cache folder of your project. There it is: all in english or whatever.

So what now? Ditch caching? that would be the easy way… I like the hard way… if you know what I am thinking about :P … ok first some google (or reading symfony documentation)… what do we find? Something to fix the whole thing for partials and components at least. You can do something like this in your template:

include_component('news', 'latestPosts', array('sf_cache_key' => $sf_user->getCulture()));

Ok what does that do? It changes the key symfony uses to cache that component. So you don’t use that generated key anymore… big deal eh? Nice and easy… just great… NO! its not… I’d like to keep as much of the caching stuff as possible out of the templates. That way no damn templating idiot can break the caching.

NOW THE INTERESTING PART

So I took a closer look at the sfCache and the sfFileCache class: They use prefixes on the caches that usually contain parts of the url like the server, app, module, action, partial and component. YEAH! gotcha! ok but how do I change the prefix? Well the cache is configured in the factories.yml and there is also an option to change the prefix! Almost done! but again NO! FUCK… I can change the prefix but how do i change it dynamically with the user language? With spring I’d have an idea on that… but symfony… humpf… but then an IDEA popped! FILTERS

The symfony documentation showed how to configure the cache with a filter to do some weird caching stuff (didn’t read it all… but its in the gentle introduction thing). So I created a LanguageCacheFilter class (awesome name… right?!)… So lets have a look at it. This is the execute method:

	public function execute(sfFilterChain $filterChain) {

		if ($this->isFirstCall()) {
			$context = $this->getContext();
			$user = $context->getUser();

			// if cache is disabled (dev environment) this object does not exist
			if ($context->getViewCacheManager() != null) {
				$cache = $context->getViewCacheManager()->getCache();

				$cache->setOption('prefix', $cache->getOption('prefix') . '/'.$user->getCulture());

				// works only for sfFileCache
				$cache->setOption('cache_dir', $cache->getOption('cache_dir') . '/'.$user->getCulture());
			}
		}

		// execute next Filter in chain
		$filterChain->execute();
	}

Pretty simple… I just change the prefix and the cache_dir for sfFileCache (because it is initialised sometime before the filter is executed) and add the language from the current user object. If you use sfApcCache or something you would prolly not need the cache_dir option, but maybe something else… okn ow just add it to the filter et voila!

language:
  class: LanguageFilter

languageCache:
  class: LanguageCacheFilter

cache:     ~

So i execute the languageCache before the cache itself is executed… because… you know… and after I get the language from another languageFilter from the cookie. Ok its maybe not the perfect solution, because that filter is executed on every damn request… and that sucks… but this is the place for me because i have the language and the cache at the same time and pretty much at the beginning of the whole execution.

Ok that was my solution to the problem… IF YOU HAVE A BETTER ONE… GIVE IT TO ME! :)

Hello world!

hai guise!

this is the first auto-generated post… so i will just write some nonsense in here… ok well thats it :D