Wednesday, September 17, 2014

Running transmission as a different user

Sometimes things should just be easier. One config file, restart, done. This time I faced quite a different daemon so I though I'll share since it took me a while to figure it out. It's about the transmission-daemon running as a different user.

The why?
I need to download files from the Internet using BitTorrent protocol (like Ubuntu ISO for example) and I'd like to do that using a computer that's serving as my home server.

What's difficult?
First of all there's no place in any of the configuration files to tell you which user is it going to be that's running the daemon. That secret is safely guarded inside /etc/init.d/transmission-daemon. You'll find this kind of line:

USER=debian-transmission

So you'd think that's all then. We change it to something like

USER=nobody:nogroup

and life's easy. Well, not exactly. If you try to do this you'll see that transmission-daemon tries to start but fails rapidly. To diagnose what's wrong you'll want to use this daemon in foreground mode like this

transmission-daemon -f --config-dir /var/lib/transmission-daemon/info --log-debug

But that'll only tell you that there are permission issues and that some files that apparently may even have permissions like 666 on folders that will have 777 permissions will still not be out of reach. The problem lies in the default configuration of the daemon. It keeps it's configuration data in /var/lib/transmission-daemon/info however it's customary to store such information in /etc which Ubuntu and Mint do. And so there's a /etc/transmission-daemon/settings.json with the ownership of debian-transmission and it's then linked to the place where Transmission awaits it (/var/lib/transmission-daemon/info/settings.json)

The solution
So here's what I did. I first stopped the deamon or else my configuration file would get overwritten. Then I changed the ownership of the entire structure of /var/lib/transmission-daemon to nobody:nogroup like so

chown -R nobody:nogroup /var/lib/transmission-daemon

Then I removed the /var/lib/transmission-daemon/info/settings.json link and replaced it with the /etc/transmission-daemon cusine:

sudo mv /etc/tranmission-daemon/settings.json /var/lib/transmission-daemon

and I updated the ownership of that file again:

chown -R nobody:nogroup /var/lib/transmission-daemon/info/settings.json

That's it! Transmission now runs as user nobody:nogroup creating new files and folders as nobody:nogroup and life is easier again

Monday, September 8, 2014

Migrating a project from Google Code to GitHub

Recently I've grown very impatient to the progress being made to psi-probe. I use it at work and wherever else I can because it is a fantastic piece of software but the fact that the last commit was around 6 months ago leads me to understand that the project is simply dead.

The original author assured me that he's got major interest in keeping this project alive but it seems he's got no time to do so. Also keeping the project maintained with Subversion these days seems a bit too vintage for me. And so I decided to migrate the whole thing to GitHub.

Migrating the repository itself is quite simple and there's more than one tutorial on the Internet to help you out with it. The major thing that needs to come out at the end is a repository with git tags (not Subversion ones), git branches (same as Subversion ones) and an .gitignore file containing the set of things you'd like to not care for.

Migrating issues is also not very difficult once you have all the tools in place. https://github.com/arthur-debert/google-code-issues-migrator is your biggest friend. As with any friend there's love and there's hate involved. Basically the tool does everything properly up until some damn comment contains some god forsaken character in which case the whole thing blows up in your face.

Traceback (most recent call last):
  File "./migrateissues.py", line 387, in
    process_gcode_issues(existing_issues)
  File "./migrateissues.py", line 288, in process_gcode_issues
    add_comments_to_issue(github_issue, issue)
  File "./migrateissues.py", line 120, in add_comments_to_issue
    body = u'_From {author} on {date}_\n\n{body}'.format(**comment)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 362: ordinal not in range(128)

There are 2 places where a similar problem causes the tool to stop working. The other one is at the addition of an issue. I've worked around by catching that error and providing some dummy text like "Unable to import comment". I'll later on modify that comment by hand and using the Copy/Paste method I'll bring it on the level.

To keep the numbering of issues the same as on Google Code I needed to create some dummy issue because someone deleted issue nr 1 and the importer doesn't recognize this fact and skips the creation of the first, missing issue. Fortunately enough it's quite easy what the first issue should contain in a migration project like that so I used that to my advantage :)

Anyways.. If you'd like to see the Psi Probe flurish again you can always post me a thank you card for all the hard work I'm doing :) Or better yet post a pull request with fix to one of the 100+ issues imported from the original project - the choice is yours!

Happy coding!

Sunday, August 10, 2014

Selenium tests - a couple of loose thoughts...

Recently I've blogged about how to employ fluent interface when creating a framework for Selenium-based integration tests. After a few talks I gave I think I have a some grasp of what the major concerns for taking this approach are. Let's go quickly through what I observed was the top 5 questions.


Assertions shall be done in tests - not in page objects

This is probably the numero uno questions/concern voiced during the presentations. Let's assume for a second that we're not doing fluent interface in our Selenium tests and force ourselves to write assertions in tests, because the original documentation says so.
It turns out pretty quickly that there's more than one of the same assertion in more than one test. You may ask why that's the case? If you try to keep your scenarios separated and isolated you will end up either navigating to the page in question more than once (and verifying if the navigation succeeded). That's just one example but you get the idea.
For me personally the page object being the right place to define the assertion has more to do with scoping and avoiding unnecessary getter just to be able to assert a state on a given page. I know that for years we've been taught the POJO paradigm and the JavaBean convention, that most of us have that already in our DNA, so to speak. There are even things to spice up your life in this regard and have the compiler generate getters and setters for you. Hell, there are even languages like Groovy (my very favorite one) that will generate those things for you without you even asking for it. I actually like the idea because it takes completely away the POJO bloated boilerplate and gives you a sane way to express your intent. All that does not mean that we are allowed to turn off thinking and follow the convention like rats followed the pied piper. When you need an action on an object you don't create a separate friend/utility class for it but you embed that inside that object. I don't know if that's already domain-driven design or whatever but it is just plane sanity dictating it. The lack thereof can be easily observed in the Java Collection API (Collections.sort(people, comparator) instead of simply calling people.sort()). We've been fed this pulp for years - no wonder we take it for caviar.

I already have an existing suite of tests - what shall I do?

This is probably going to hit everyone who'd like to try the fluent interface in Selenium tests. Let me quote an old saying: "No pain, no gain". Things will not evolve by themselves - you need to take matters into your own hands and make the world a better place. I know that for many of you those tests are more of a pain in the ass that the boss/tech lead/company policy brutally makes you do but if you don't change your mindset how can you even begin to expect to start changing how others operate?
I say start small. Write one or two tests, create a handful of page objects, make a presentation, get others excited. The hard part is already done in all your other (for the sake of it I'm just going to call them legacy) tests and all that's left is just changing the outfit.

How do I allow writing custom assertions?

I brought this up as a separate concern because it's been made very clear for me that sticking with what the regular assertion framework gives you is far from optimal. Although AssertJ or just the assertions from org.junit.Assert class give a certain amount of flexibility it'd be nice to have some common patterns baked in into some custom assertion class.
Let's make one thing crystal clear: there are 2 reasons why you'd want to do it. One, when you want to have for example strongly-typed assertions that compare domain objects, maybe you parse and assert strings in a peculiar way throughout your test suite - that's the generic extension and it is perfectly legit. However there is a whole group of other reasons why people do it: to write custom assertions that access the state of your page objects and assert if a given action gave proper results. Well that's precisely the Collections.sort(people, comparator) vs people.sort(comparator) thing and if you do it that old dumb way you're just going to have to stick with it while the whole galaxy moves forward.
That being said there's absolutely nothing (besides sanity) preventing you from writing a separate custom assertion and calling it from a wrapper inside a page object to continue the fluent interface.

Does it work for you?

It's been almost a year when this pattern has been used in our product. During that time we went from near-no-tests to around 60% coverage of a very legacy system which in my opinion counts as a great success. But the best part of it is that it doesn't stop! Developers simply love the way they create tests. It's easy and now that we have a lot of the page objects already created writing new tests is really simple. Even simple bug fixes begin with a selenium test and it takes mare minutes to write them.
And above all I love the way it translates from steps to reproduce to steps in a test - it is plain awesome! Please bear in mind we're talking about things in one of the most constrained languages out there that a moderately sober student can learn in a week!

Are there any drawbacks?

Yes, there are! Since creating data for tests is so extremely easy developers tend to prepare that data every time they write a test and that tends to make those tests run slowly. So if speed is what you're craving for you need to be smart about it. We tend to create separate database migrations that run before selenium tests and that way if we already have part of the functionality covered in other tests we can speed things up.

How long runs your test suite?

Around 5 hours. That being said doing the same thing manually takes a week so I say we're well on the safe side. Please bear in mind that we're executing those tests sequentially and that doesn't need to stay this way. Since most of our tests have data specific for them created before each test that makes it very much possible to run them in parallel. Initial tests show that running the whole system on developer's notebook and executing 20 tests in parallel cuts the time to 20 minutes which is well within the realm of modern continuous deployment scenarios.

Well, that's it! Happy coding!

Wednesday, April 16, 2014

Short and to the point - BrightTalks meetup

I gave a presentation for the BrightTalks meetup about how I envision writing selenium tests. Read more about it here (http://www.meetup.com/Bright-Talks/events/174660312/)

Saturday, March 29, 2014

Are Spock and others dead?

I've been looking for a good alternative to writing unit tests, maybe in a more BDD-like form, or just to get some fresh perspective on how one could do unit tests. I think it's because me getting old and the middle-life crisis hitting on me :) And so I examined a few of the usual suspects in the Java space...

Spock

Some time ago I was extremely inspired by Spock. It was The Way to do unit tests. The introduction of a table-like construct to do multiple data-driven tests, labels for given/when/then template - that was awesome! I was hoping Peter Niederwieser would keep working on it forever but since he joined Gradelware his talent seems to be occupied elsewhere and Spock seems to be discontinued.

Fest Assert

I remember the time when Szczepan showed us fest-assert framework in action. Szczepan was well known for his passion for fluentization of all possible interfaces - which I strongly admire - but this, this was the real deal, the perfect combination of why and how to do things. I fell in love with this library, even started to create a .NET port of it and I'm still a fan. But it's been discontinued too. Luckily it's been picked up by Joel Costigliola and is being developed further as AssertJ. I sure hope this will keep being maintained!

TestNG

Now that's a fresh start I'm going to try to pursue. New annotations, a bit dangerous in what it tries to accomplish with the dependency on tests (I always hated that) but I'll try to give it a shot. And it's still maintained which is makes it stand out among other frameworks.

Geb

Now that's a good example of something one should never had created - a DSL to tackle a DSL. Wrr... I thought it couldn't get any worse but then I found...

Fluentlenium

Well,... It seems like someone tried to kind of repeat the success of fest-assert and got it wrong. I tried it and it is just... wrong.

Conclusion

From what I've been able to figure out in a few hours it seems like only TestNG is the only actively developed alternative to JUnit and one of the very few frameworks in the testing space that actually makes any advancements. But hey - I might very well be wrong. If you can share a link to something revolutionary in the testing space drop me an email ad padcom (at) gmail (dot) com or leave a comment below.

Happy testing!


Thursday, February 20, 2014

Selenium and reusable scenarios

In my last post I've shown you how to structure your code describing the application under test so that it allows for easier construction of more readable integration tests. Today I'll try to complement that with the concept of reusable blocks of tests - scenarios.

Let me give you an example of a scenario that everyone can relate to: logging in to an application. Let's consider what does it actually take to perform this task:

  • navigation to the login page
  • entering proper credentials
  • clicking the "Login" button

Doing that in every test every time will soon make the tests unmaintainable. For example changing username and/or password or adding language to the login page when you do this 200 times is just going to be a huge pain in the neck.

Scenario concept to the rescue.

Let's imagine our base Page object contains this kind of method:

public <I extends Page, O extends Page> O run(Scenario<I, O> scenario) {
    return scenario.run(this);
}

Having defined this let's see the Scenario interface:

public interface Scenario<I extends Page, O extends Page> {
    O run(I entry);
}

The I generic parameter is the type of the page that you'd like to start the scenario on. The O generic parameter is the resulting page the scenario ends on.

Now the definition of the login scenario from the last post would look something like this (extended with language selector):

public class LoginScenario implements Scenario<LoginPage, HomePage> {
    private final String username;
    private final String password;
    private String language = "english";

    public LoginScenario(String username, String password) {
        this.username = username;
        this.password = password;
    }

    @Override
    public HomePage run(LoginPage entry) {
        return entry
            .assertHasProperUsernameLabel()
            .assertHasProperPasswordLabel()
            .enterCredentials(username, password)

            .selectLanguage(language)
            .clickLogin()
            .assertPageTitleIs("Welcome to this cool application!");
    }


    public LoginScenario language(String language) {
        this.language = language;
        return this;
    }
}

There are 2 types of parameters for this scenario: required (username and password) and optional with default values (language). The usage of fluent interface in setting up the scenario plays very nicely with the overall style of the integration tests. The fancy-looking generic Scenario interface allows to chain the execution of this reusable block of code in a fluent interface of the actual test:

public class LoginTest {
    @Test
    public void will_login_and_logout() {
        new LoginPage("http://localhost/myapp")
            .run(new LoginScenario("johndoe", "secret").language("german"))
            .logout();
    }
}

I hope this will help you keep your integration tests code DRY and maintainable!

Happy coding!

Tuesday, January 28, 2014

Writing selenium tests with style!

I know it's been more that a while sine I last blogged but there's actually a good reason for it: I've been reviving a legacy application sentenced to death by decommission for the better part of the last year. With success I might add :) Now everybody wants a piece of it - but that's not what I wanted to talk about...

During this exercise beside obvious technology updates like switching to Tomcat from a God forsaken version of some other application server and making the project actually compile in a continuous integration environment, yata yata yata,  I've fiddled a little bit with selenium tests to make them at least do a sanity check while doing all those naughty changes. In doing so I've realized that actually Selenium can be a real beauty if used properly.

Without further due let's jump into the meat!

The problem

Selenium tests are integration tests and they are hard to write and maintain

The solution

This is actually not so hard and if you structure your tests properly, apply some rules and enforce a couple of design decisions then writing those tests is actually extremely easy and fun!

Let's see how we can turn the beast into a beauty!

Originally the recipe that you get when you arrive to Selenium's getting started page presents you with the basics (and for a good reason): create the driver, navigate to a page, search for an element, interrogate the element for some information. This works really nicely if all you want to do is automate Google's search engine and nothing else.

If you want to build some structure around the pages you test the Page Object design pattern comes to the rescue. Unfortunately the original documentation fails to mention the @FindBy annotation which is crucial for making the code look good and perform as expected.

Let's take a look at the following: we have an application (a hello-world style one) that presents one heading on the page with the text "Hello, world!". To describe the page using the @FindBy annotation simply declare the field as a WebElement and annotate it with @FindBy(id = "greeting")

public class HomePage {
    @FindBy(id = "greeting")
    public WebElement greeting;
}

Now to initialize such a page object instantiate it as you'd normally do

HomePage page = new HomePage();

and later on use the PageFactory.initElements(driver, page) method to initialize a set of proxies to elements. The "proxies" element is crucial: they don't need to appear on the page up front and you get all the usual stuff like waiting for them to load absolutely for free! It's like magic - only better :)

The Problem

Applications have structure and I need to repeat lots of elements

The Solution

Applications have structure. Their individual pages are not disconnected from each other, each presenting a totally different content. Usually pages are contained in some form of layout that'll act as a common experience for the user. Luckily for us we have decided to describe pages as classes and classes can do ... inheritance!

Let's say the HomePage is of some system that has a layout with logout button for the users to take a leave if they get bored using it.

public abstract class ApplicationPage {
  @FindBy(id = "logout")
}

Next we declare our HomePage as before, only denoting the application structure using inheritance:

public class HomePage extends ApplicationPage {
    @FindBy(id = "greeting")
    public WebElement greeting;
}

And you instantiate it as usual:

HomePage page = new HomePage();
PageFactory.initElements(driver, page);

This way we're expressing an "is-a" relation between the layout page and the actual page: The home page is an application page. In Java 8 we'll be able to put some of the stuff directly into interfaces and have even more capability to construct pages from functional bits and pieces. Until now for most cases this is more than enough.

The Problem

My integration tests are unreadable because of all the fiddling with Selenium.

The Solution

This is actually a huge problem, not only with Selenium or any other integration/unit tests. At least in Unit tests we have the universal layout ("given/when/then" or if you're more a Microsoft type guy then it'd be "arrange/act/assert"). But what about integration tests? They are expected to have assertions in the middle, they are expected to manipulate our application in many ways and verify the state in the middle because that's what the user would do!

No worry! There's this perfect little design pattern called fluent interface that we can easily employ to nicely structure our tests and to have cool, reusable place for everything! Let's start with the description of the test we're about to write:

- the user navigates to the login page
- verify that the login prompt actually says "Username" and "Password"
- upon entering the proper credentials and clicking "Login" the user lands on the home page
- verify that the login succeeded by checking the page's header or some other element

I suggest you take the description and follow it to the letter using fluent interface which might look something like this:

public class LoginTest {
    @Test
    public void will_login_properly() {
        new LoginPage("http://localhost/myapp")
            .assertHasProperUsernameLabel()
            .assertHasProperPasswordLabel()
            .enterCredentials("johndoe", "secret")
            .clickLogin()
            .assertPageTitleIs("Welcome to this cool application!");
    }
}

As you can see I've deliberately shifted all the specifics to the page objects, including navigation which is especially neat if you're working in an IDE and if you already have a set of page objects to work with. That way the IDE will actually tell you what you can do after you have "executed" a particular action (clickLogin for example).

Constructing such page objects isn't anything extremely sophisticated. Let's take a look at the LoginPage:

public class LoginPage {
    private final WebDriver driver;

    @FindBy(id = "username")
    WebElement username;

    @FindBy(id = "username-label")
    WebElement usernameLabel;

    @FindBy(id = "password")

    WebElement password;

    @FindBy(id = "password-label")
    WebElement passwordLabel;

    @FindBy(id = "login-button")
    WebElement loginButton;

    public LoginPage(WebDriver driver, String url) {
        this.driver = driver;
        if (url != null && url.length() > 0) {
            driver.navigate().to(url);
        }
    }

    public LoginPage assertHasProperUsernameLabel() {
        Assert.assertEquals("Username:", usernameLabel.getText());
        return this;
    }

    public LoginPage assertHasProperPasswordLabel() { ... }


    public LoginPage enterCredentials(...) { ... }

    public HomePage clickLogin() {
        loginButton.click();
        return new HomePage(driver);
    }
}

As you can see the assertions are contextual and can be re-used at will in any test scenario. The same goes for any operation you'd normally run on pages like filling in the login form and clicking on the login button and you can reuse them as many times as you want. If you combine that with inheritance you'll get a extremely powerful way to describe your application in an object-oriented way. With the fluent interface you'll get a chance to exercise that model in a way that will not make your eyes bleed when you'll get back to the code to fix that one button's location that has moved and all of the sudden all integration tests are failing.

The Problem

My integration tests run every time I build the project using Maven and it takes to much time

The Solution

The solution lies in proper Maven project configuration. Maven has this nice idea of profiles. I'm using a profile called "integration-test" to actually run everything integration-test-related only if that profile is enabled.

It's quite a lot of XML as you can probably imagine so I've prepared an example project that demonstrates the configuration. The crucial part in all this is the configuration of surefire, failsafe and tomcat7 plugins. You can grab the example here. If you do a mvn clean install then no integration tests will get executed but with mvn clean install -Pintegration-test you'll see Tomcat starting for the duration of tests and all the Selenium tests executed against that it.

Epilogue

We've been using this way of writing unit tests with great success for more than a few months now. It works great if you have regular web applications (request/response) and adopting it to any dynamic pages isn't all that difficult mainly because the @FindBy annotation does such an amazing job of hiding the complexity of Selenium.

Happy integration testing!