Archive

Posts Tagged ‘testing’

Geb goodness

09/02/2014 Leave a comment

Recently I’ve been playing around with Spock and a bit with Geb. I’m under big impression so today let’s check out what Geb is.

Version for managers -> It’s a technology that will make your developers test and allow you to cut costs. Now go send email to dev team that they should check it out, shoo.

Version for devs -> It’s a sexy framework with jQuery like DSL over Webdriver/Selenium allowing easy use of Page Objects and wiring it all up with Groovy. Those of you that had chance to work with Selenium and write traditional functional web tests in Java, most likely are now wondering what sexy can be in Webdriver.

Well, most importantly, Geb takes away all the boilerplate code and Java ceremony, leaving for you to fill only the important parts with simple syntax, that all of jQuery users know already (most of the examples are taken from Geb site).

$("div.some-class p:first[title='something']")
$("h1", 2, class: "heading")
$("p", text: contains("Geb"))
$("div").find(".b")
$("div").filter(".c").parents()
//Manipulating forms
$("form").name = "Geb"
assert $("form").name == "Geb"

Well, for me it looks like a jQuery. When you get out of syntax and reach test context, it’s even better. Regardless of what testing framework you’re currently using, Geb will work out of the box with it. Personally I’ve been using it with Spock, but it has support for JUnit, TestNG, EasyB and Cucumber. So you don’t have to be concerned about learning another tool.

Let’s check out example below where it’s used with Spock

class LoginSpec extends GebSpec {
    def "login to admin section"() {
        given:
        to LoginPage

        when:
        loginForm.with {
            username = "admin"
            password = "password"
        }

        and:
        loginButton.click()

        then:
        at AdminPage
    }
}

As you can see, it’s just a standard Specification. Only difference is that you use one of Geb spec classes.

Big win in Geb are Page Objects. I haven’t used them in Selenium, however as I understand they are available there. What is a Page Object? As name suggests, it’s an object representation of a page :) To be bit more specific: it’s a class inheriting from geb.Page class which role is to encapsulate all the interaction with the HTML page.

class SignupPage extends Page {
    static url = "http://izawody.pl/signup"
    static at = { title == "Logowanie | iZawody" }
    static content = {
        loginField { $("input#login") }
        passwordField { $("input#password") }
        loginButton(to: DashboardPage) { $("input#loginButton") }
    }

    void login(String login. String password) {
        loginField.value login
		passwordField.value password
        loginButton.click()
    }
}

class DashboardPage extends Page {
    static at = { waitFor { title.endsWith("| iZawody dashboard") } }
}

//Test script
Browser.drive {
    to SignupPage
    login("admin", "admin")
    at DashboardPage
}

It helps as you create a lot of reusable code that encapsulate a lot of moving parts, like text on pages, id’s, HTML structure. So after updating page template you need to only update page object in order to fix dozens of failing unit tests! That’s just a huge win! As a side bonus, all the elements specified in the content section, are reachable in test script, so each element may have an abstraction layer :)

As Geb is just an more readable abstraction layer over Webdriver, as a bonus you get a full support for all the browsers that selenium uses, so you may run your tests in FF, Chrome, Opera, IE and there is experimental support for mobile browsers. If you’re running on a server there is a driver for headless browser, so all covered :)

Only place where Geb falls short is if you aim for job security. Even with code obfuscator you’re going to fail. Code is just damn too simple :(  Other than that Happy coding!

Advertisements
Categories: English Tags: ,

End of the world post mortem

28/12/2012 5 comments

As we all know, on last Friday world was supposed to end.

Luckily your friendly neighbor Java programmer found in the internet a piece of code responsible for running that, left by Evil Mayans, which looked like this:

public class World {

	private WorldDestroyer worldDestroyer;

	public void end(){
		Date endOfTheWorldDate = worldDestroyer.getApocalypseDate();
		if(endOfTheWorldDate.equals(new Date())){
			worldDestroyer.run();
		}//no need for ending bracket as the world ends :D But Java compiler does not know that :( Feathered Snake damn you holy Sun!
	}
}

So what our hero could do?

First of all he could delete the if check or even remove whole World class, however that would most likely fail some tests and would result in alarm raised by Evil Mayan CI server. They would know that something is wrong,  fix the code, hence the world would end!

So he had to be smarter. Our hero sat and thought for some time, but not for so long, remember The End Of The World is coming! Using all his Java knowledge and team work experience he did the change!

public void end(){
		Date endOfTheWorldDate = worldDestroyer.getApocalypseDate();
		endOfTheWorldDate.setYear(20);
		if(endOfTheWorldDate.equals(new Date())){
			worldDestroyer.run();
		}
	}

So what he did? He used one of biggest flaws of java.util.Date MutabilityYes, you may change internal state of Date using one of it’s method. No need for some sophisticated techniques.

I’m doing all of Java interviews in DC, and it astonishes me how many people don’t know that this class is Mutable. Yes, after instantiating it, you may change it internal value freely, which may lead to a lot of problems.

It surprises me how many people does not know about it. During last interview, right before Christmas, Senior Java Dev (with >5yrs of experience) tried to convince me that the class is immutable and that may be one of it flaws.

And what’s the big deal?

You should never trust in Date object, you’ve shared or received from external World (in OO terms -> outside your class).

It is possible to build anything on top of java.util.Date. In most cases, no one will try to harm you, but I would not build large application / framework on top of that assumption. So while working with Date, you’re going to learn everything about defense programming. Quick enough you’ll understand that it’s not enough to just copy input parameters, but you also have to return defense copies while returning values.

But okay, let’s stop bashing Date class for a moment. If you want to learn more about techniques that may be useful to work with it, please check the book that EVERY Java programmer should read: Effective Java by Joshua Bloch. It may not have anything about Date class, but it for sure shows how to achieve immutability and how to work with mutable code.

Other good solution is to use 3rd party library, like e.g. JodaTime It will solve a lot of your problems. It’s also quite popular, so most of the frameworks will provide support for it’s classes.

Ok, let’s investigate second flaw of this code. It’s not testable.

You just can’t test code that is dependent on time. It has to fail from time to time, raising false alarm. If you assert based on year, it may fail at midnight every 5-8 years. If you assert on month, it may fail before payday, etc. But don’t worry, the battle is not lost yet. The solution is trivial: create an external class called Clock / TimeService / TimeManager / DateFactory or something along the line, consistent with you’r project naming convention, and just move instantiation of Date there. What we achieve this way? You can switch implementation of that class for test purpose and you won’t get broken CI builds from time to time :)

So how it should look like in the end? (at least this variant of code)

public class World {

	private WorldDestroyer worldDestroyer;
	private Clock clock;

	public void end(){
		Date endOfTheWorldDate = worldDestroyer.getApocalypseDate();
		if(endOfTheWorldDate.equals(clock.now())){
			worldDestroyer.run();
		}
	}
}
Now much better. Good that evil Mayans did not know about it :)
Categories: English Tags: , , ,