Posts Tagged ‘Testing’

Http-only session cookie

Wednesday, May 20th, 2009

In my last post i explained, how to test session protected resources with selenium rc and ruby. While we were migrating to Rails 2.3 all such tests suddenly stopped working because the JavaScript didn’t return the session cookie anymore. After some research we found out that you can control accessibility to the session cookie through the browser by sending a little flag in the HTTP response header for Set-Cookie.

response.setHeader("Set-Cookie", "cookie_name=cookie_value; HTTPOnly=");

By setting this flag you basically prevent any JavaScript from accessing the session cookie. Rails now sets this flag by default which makes it less vulnerably against cross scripting attacks.
You can find all information you need including a list of supporting browsers here

Testing session protected resources with Selenium RC

Wednesday, March 11th, 2009

Consider the following scenario: We book or buy some stuff through a web application and at the end of the process the application generates a receipt in form of a pdf for us. The pdf contains personal information so we make it only accessible to the current session.
We’d like to test the success scenario end-to-end, making sure that whatever we enter through the web application appears in the pdf. How to access the pdf from our Selenium RC test?

Grab the session cookie by calling:

session_cookie = @selenium_driver.get_eval('window.document.cookie')

Then grab the resource through a http request within the selenium rc test:

resource = Net::HTTP.new(host, port).start { |http|
   get = Net::HTTP::Get.new(path_to_resource)
   get['Cookie'] = session_cookie
   response = http.request(get)
   response.body
}

It works fine for a Rails app and i guess this principle should be applicable for any other server with cookie based session handling.

Direct field dependency injection

Saturday, July 19th, 2008

At almost any project i have been on there was a discussion whether to use constructor or setter injection. Sometimes it tends to be a religious war between developers and either side has good arguments for both approaches. With constructor injection you make sure that all dependencies are available on creation time of the object. Setter injection on the other hand gives you a little bit more flexibility. Especially if a class has more than 3 constructor parameters it’s getting a bit clunky with constructor injection.
I personally tend more to constructor injection but since the auto-wiring capabilities of the Spring frameworks there is a third way to do your dependency injection: inject a dependency directly into the field of a class. Of course this approach has a downside if the class is used outside the Spring container, but for most Spring-based projects this is quite unlikely. Let’s look at some code to see how field injection works.

@Service
public class HelloService {
 
    public String sayHello() {
        return "Hello! I'm a service";
    }
}
 
@Component
public class SomeComponent {
 
    @Autowired
    private HelloService service;
 
    public String saySomething() {
        return service.sayHello();
    }
}

It’s as simple as that. The classes are annotated with @Service and @Component to be considered as candidates for auto-detection as i prefer to have as little XML configuration as possible. Thus the applicationContext.xml is quite simple:

<?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 
    <context:annotation-config/>
    <context:component-scan base-package="org.playground.di"/>
</beans>

Of course we usually would start out by writing tests first. But how can we write unit tests for SomeComponent when we don’t have access to the field and inject a mock object? Luckily the developers of Spring thought of that and provide us with a class called ReflectionTestUtils which is available since Spring 2.5. For this unit test i’ll use Mockito to mock out HelloService.

public class SomeComponentUnitTest {
 
    @Mock
    private HelloService mockService;
 
    @Before
    public void initMocks() {
        MockitoAnnotations.initMocks(this);
    }
 
    @Test
    public void shouldUseMockService() {
 
        SomeComponent component = new SomeComponent();
        ReflectionTestUtils.setField(component, "service", mockService);
 
        String expectedMessage = "I'm from a mock";
        Mockito.stub(mockService.sayHello()).toReturn(expectedMessage);
 
        String actualMessage = component.saySomething();
 
        verify(mockService).sayHello();
 
        Assert.assertEquals(actualMessage, expectedMessage);
    }
}

To complete our testing we also gonna write an integration test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class SomeComponentIntegrationTest {
 
    @Autowired
    private SomeComponent consumer;
 
    @Test
    public void shouldSaySomething() {
 
        String expectedMessage = "Hello! I'm a service";
 
        String actualMessage = consumer.saySomething();
 
        Assert.assertEquals(expectedMessage, actualMessage);
    }
}

It’s done when it’s done!

Sunday, June 15th, 2008

To define a user story as done can be a tricky task. It’s about negotiating with the customer and setting the right expectations. A common tool we use in our projects is defining Acceptance Criteria for user stories. Using Acceptance Criteria is great because we set expectations on the application’s behavior right from the start before implementing the story. We can drive the expectations of the customer on what will be delivered at the end of an iteration. Furthermore we can translate those Acceptance Criteria into executable and automated tests (more on that later). Thus we make sure that we do not break any existing functionality as we move on in the project. If a story passes all Acceptance Criteria it can be considered as done.

So how does an Acceptance Criteria look like? Let’s say we have a simple user story called “Login”:

As a registered user i want to log in so that i can view my personalized report

Acceptance Criteria are then described as scenarios. As an expample let’s look at a typical main success scenario for the user story above:

Given a registered user u
When entering username FooFoo and password BarBar
And logging in
Then the personalized report for user u is shown.

A story can have as many Acceptance Criteria as necessary to consider it as done. Don’t be fooled to believe you can define every Acceptance Criteria upfront. As the team gains more and more knowledge while proceeding in an iteration more Acceptance Criteria may be discovered. Your initial set of Acceptance Criteria should be enough to make everyone comfortable to deliver that story.

So why this format of “Given” “When” “Then”? On my current project we use RSpec, a Behavior Driven Development framework for Ruby. You start by writing your stories with the scenarios in plain text files:

Story: Login
  As a registered user
  I want to log in
  So that i can view my personalized report
 
  Scenario: login successful
    Given a registered user u
    When entering username FooFoo and password BarBar
    And logging in
    Then the personalized report for user u is shown.

Each Given, When, Then is a step and i can define these steps in Ruby:

steps_for(:login) do
  Given("a registered user $user") do | user |
    user.should exsist
  end
  When("entering username $username and password $password") do | username, password |
    page.type(username, account)
  end
  When("logging in") do
    page.login
  end
  Then("the personalized report for user $user is shown") do | user |
    page.should be_personalized_for(user) 
  end
end

The great thing about this is that you can reuse the steps for other scenarios and hook up the RSpec framework with functional testing tools like Selenium or Frankenstein to have real end-to-end testing. In addition you can integrate the tests into the Continuous Integration server to have automated regression testing. The effort the team puts into fledging out Acceptance Criteria is directly translated into automated test code producing minimal waste.