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
Tags: Add new tag, Testing
Posted in Agile Software Development, ThoughtBlog | No Comments »
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.
Tags: Testing
Posted in Agile Software Development, ThoughtBlog | No Comments »
February 9th, 2009
In most of the project i’ve been working in we used a light-weight database like HSQLDB or H2 in the local development environment. It’s easy to set up in the build and you make yourself independent from the setup of the dev machines. Just check out the trunk and off you go.
It’s usually fine to run a file-based database but in case you have to do your development on a windows machine a file based database is really annoying. Once a process has a connection to the database it locks the file. Can’t run the app in the web server and inspect the database with squirrel at the same time.
The good thing is that HSQLDB allows you to run a memory-only database in server mode (haven’t checked H2). Start your server like this:
java -cp ./hsqldb.jar org.hsqldb.Server -database.0 mem:mydb -dbname.0 aliasdb
Instead of passing the database setup as parameters you can put them into a server.properties file which has to be in the same directory where you execute the command.
Then use this url to connect to your database:
jdbc:hsqldb:hsql://localhost/aliasdb
Tags: Build
Posted in Agile Software Development, ThoughtBlog | No Comments »
August 3rd, 2008
From discussions over the last few months i realized that quite a lot of agile teams have a high emphasis on task estimation. So far i am very much in doubt of the benefits task estimations will give to a team. In fact i come to believe that a high emphasis on task estimation will do more harm than good and is the first step into micromanagement. Especially if your team does full blown task estimation including reporting on time spent on task and estimating the time remaining. That does not mean teams shouldn’t do task estimations but they should have a clear idea why they are doing it and what they want to get out of it. Teams usually try to get out two things from task estimation: capacity (velocity) of the team and tracking iterations (eg. iteration burn down charts). But both things can be achieved by other agile concepts which an agile team (should) apply anyways: velocity through story estimation and iteration tracking through a physical story wall. Hence it is questionable if task estimation is needed at all.
Deriving team velocity out of task estimation is very dangerous and gives a wrong impression of real velocity over all iterations. The concept of velocity only works if the team sticks with the initial estimates and has a common base line and scale for all iterations. Estimating in time does not give the team a common base line regardless if the team uses hours, days or ideal days. What is an ideal day? Did i really spend the same amount of hours for the last four-hour-task? How do i take pairing or pair swapping into account? Estimating in time is flawed and is raising many questions as people interpret time quite differently.
In addition there is a hidden effect when estimating with time. As the team progresses through the project it acquires more and more knowledge. This knowledge is reflected in better estimates which is of course positive. But it also means that velocity from iteration N is not comparable with iteration N-1 because there is no common base line. What is achievable in one ideal day/hour shifts with the increasing knowledge of the team. This effect does not happen if estimation is done relatively and the team sticks to the base line from the first estimation session of the project. Estimation still gets more accurate with gained knowledge but with a relative scale a task will be inserted more accurately within this scale.
Would it help to estimate your tasks relatively by size like stories (and call it gummy bear points)? It might work if you stick to the base line you created in your first iteration. A one gummy bear point task from iteration one is always the same size as a one gummy bear point task from any other iteration. I’ve never been on a team where tasks were estimated relatively so i can’t really tell if this approach would work.
The other purpose of task estimation is tracking the progress of an iteration. Though it is important to track iteration progress it is much more important to track project progress. A completed story is the unit that delivers value to the product. Hence the focus should be to find out how much stories a team can finish in one iteration instead of tasks (the real velocity). Tracking completed stories on a project scale (via a story burn down chart) together with story velocity will give a team the ability to predict the projects end date. Task estimation simply fails to add visibility of progress on a project scale. Don’t get me wrong here. I still think that breaking down stories into tasks in iteration planning can still be valuable. But why putting in the extra effort to estimate tasks when the stories are already estimated? Especially if the team operates in short (and prefered) two week iterations.
A key success factor for task estimation to become redundant is to follow the INVEST principle for all stories by heart. Teams can introduce N-1 analysis iterations to have stories as close as possible to INVEST before they are played in an iteration.
For iteration tracking a physical story wall including all current tasks is absolutely sufficient. With a short look every team member can see if progress of the current iteration is healthy or not.
One very bad thing i experienced when emphasizing to much on tasks is that the team loses sight of stories as a whole. Particularly if tasks are split into the horizontal architectural layers of the software. There is a high risk that integration problems will arise and tasks will bounce more often between “test ready” and “testing failed” then they need to. Every team member should understand the vertical slice of the system which the story represents and see it as a whole.
I strongly believe we can live very well without task estimation in agile projects. Most of the estimation effort should be put into story estimation to enable project tracking. Thus in alignment to the pattern of the agile manifesto:
Project and story tracking over iteration and task tracking
Tags: Estimation
Posted in Agile Software Development, ThoughtBlog | 4 Comments »
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);
}
}
Tags: Dependency Injection, Mocks, Spring, Testing
Posted in Agile Software Development | No Comments »
June 30th, 2008
If you ask ten people for what Agile is about, you will probably get ten different answers. In this post i don’t want to create my own definition but instead discuss two basic drivers for doing Agile.
A common response i get to this question is: Agile will make us deliver faster. Though possibly true if you are a mature Agile organization i don’t think this is what Agile is about in the first place. Is going fast really what you’re after?
In my opinion the most basic driver is to generate business value as early as possible by delivering working software. This is different from just going fast as you can deliver quickly but not the right thing to produce value. Generating early business value is only possible if the team works on the most important things first. It requires high involvement from the business and continuous collaboration throughout the project to make sure the team generates value. Apparently this is often neglected by traditional organizations through their functional structure and thinking in silos.
Another basic driver for Agile is removing pain points and obstacles in the delivery process. This driver is highly influenced by Lean thinking. You look at your delivery process and ask the question: What is our biggest problem in delivering high quality, working software. You identify the biggest problem, look at the root cause, fix it and look for the next biggest problem. You do this continuously and you actually will go faster as you are removing your obstacles step by step. Typical examples for pain points and obstacles are functional teams rather than cross-functional teams, manual testing rather than automated testing or communication through documentation rather than face-to-face communication and finding placeholders for conversation.
Having these basic drivers is great but there is a tension between these two drivers. If you only go for business value you will end up with heaps of technical debt. Technical debt can be generated by a change of direction to tackle the most important things first. Or by the simple fact that the team gains more and more knowledge about the system and domain from iteration to iteration. Technical debt also tends to have a high interest rate and the longer you wait to remove technical debt the higher the interest rate will get. On the other hand if you concentrate your effort purely on removing technical debt you will lose focus on business value or won’t deliver business value at all.
Hence the trick is to find the right balance between the two drivers when you plan your iterations. Deliver business value but also allocate time to tackle your biggest problem. I can’t really tell you the right balance but if you are new to Agile i would recommend to favor removing your biggest problem over delivering business value as it will have a long term effect on your overall delivery.
Tags: Basics
Posted in Agile Software Development | 1 Comment »
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.
Tags: Testing, User stories
Posted in Agile Software Development | 1 Comment »