Munchkin – Walking Skeleton and the initial stories
Tue, 10/08/10 – 15:00 | 3 Comments

What is a Walking Skeleton?
A “walking skeleton” is an implementation of the thinnest possible slice of real functionality that we can automatically build, deploy, and test end-to-end [Cockburn04]. It should include just enough of the automation, the major components, and communication mechanisms to allow us to start working on the first feature. We keep the [...]

Read the full story »
More posts from this section »
More posts from this section »
General

Everything I was lazy to categorize

Music

Candy for the mind

Personal

Personal thoughts of the authors

PHP

Tutorials, Code, Patterns

Work

Work specific content.

Headline, Munchkin, PHP, Testing, Work »

Munchkin – Walking Skeleton and the initial stories
Tue, 10/08/10 – 15:00 | 3 Comments

What is a Walking Skeleton?

A “walking skeleton” is an implementation of the thinnest possible slice of real functionality that we can automatically build, deploy, and test end-to-end [Cockburn04]. It should include just enough of the automation, the major components, and communication mechanisms to allow us to start working on the first feature. We keep the skeleton’s application functionality so simple that it’s obvious and uninteresting, leaving us free to concentrate on the infrastructure. For example, for a database-backed web application, a skeleton would show a flat web page with fields from the database.

via Nat Pryce and Steve Freeman – Growing Object-Oriented Software, Guided by Tests on page 32

This means that in order to start writing acceptance tests we need an environment that we can run them against. Of course we can consider them failing test if the skeleton doesn’t exist and the expected features don’t work but that’s not our point. We need to agree on several issues to start working. What language will we be using? What platforms do we want to work on? How will we utilize a continuous integration server? What SCM will we use? What metrics will guide us?

Language: PHP5.3
Platforms: Linux, OsX, Windows
CI server: Hudson @ http://hudson.alternateillusion.com/job/Munchkin/
Build manager: ANT
Package manager: PEAR
SCM: Git git clone git://git.assembla.com/munchkin.git more info
Metrics: CodeStyle, Code coverage, PMD, Duplicate Code, Open tasks
Domain: http://alternateillusion.com/munchkin - for now
Ticketing: assembla
Iteration length: 4 weeks

We still don’t have a clue about what kind of data-backend we’ll be using. Right now we only know that we should be considering some NoSQL solutions besides MySQL. For our current phase the database is irrelevant and abstract. One golden rule in agile development is do the simplest possible thing to achieve your goal. We won’t go into writing a bunch of requirement specification and the usual waterfailistic documents.

Let the fun beign!

From this point we’ll start to manifest our project. We’re going to utilize Git and Ant to kick-off our evolving code. We’ll create an empty repository and a simple build.xml to drive our current (and further) development cycles (test, deploy, package). You’ll learn how to have basic tests without any extra software, how to use Git submodules and how to jail the functionality of pear into a custom project directory.

Project init – what do we need?

So we have come to a point where the spark ignites.

To kick-off the skeleton we first need a working web-server with PHP5.3 and PEAR and an Ant ( >= 1.7) installation. We believe you can handle these by yourself.

The code we’ll be writing from now on will be available in our Git repository. If you’d like to create the code parallel to us, then do the following steps:

  1. navigate to your development directory
  2. issue the command: git init Munchkin (this will create a local repository for yourself)
  3. Change the directory to the newly created Munchkin dir.
  4. Create an empty master branch git commit --allow-empty -m'Master init'
  5. If you’d like to track our repository then add it as a remote repository
    git remote add ai git://git.assembla.com/munchkin.git
    git fetch ai
    git checkout -b ai remotes/ai/master

You’ll get an ai branch that will hold the current state of the assemble repository with the actual codebase.

Whenever you’d like to see the state of the assembla branch, you have to do the following steps:

  1. Change to the ai branch
    git checkout ai
  2. Pull the current version
    git pull ai master:ai
    This tells Git to pull in the state of the master branch of the ai remote to your local ai branch.
  3. Don’t forget to change back to the master when done
    git checkout master

So first thing’s first, we need an environment. We’ve found that a project-based deployable environment is much more manageable than documentations about “build yourself a system that can run our software” so we’ll add all further dependencies in our build/deploy mechanism. This means that for the project to emerge, we’ll only need a build.xml that Ant could use. Let’s create the first file in the repository. Let’s switch to the master branch (which will hold your local version of the project)
git checkout master should do the trick. You could verify the switch with git branch which should show a

ai
* master

Your current branch is the one where the asterisk is.

build.xml

Open your favorite php editor and create a new file in the project root, named build.xml. Add a few rows as shown below.

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<project name="Munchkin" default="build">
    <description>
        http://www.alternateillusion.com/munchkin-articles
    </description>

    <target name="build" description="Build the project"/>

</project>

Save the file and try issuing an ant command in your project root. You should see something like this:

Buildfile: build.xml

build:

BUILD SUCCESSFUL
Total time: 0 seconds

If all is right:

git add build.xml – add the files to the repo

git commit -s -m'Empty version of build.xml' – commit your work

What is the -s flag?

-s represents “sign-off”. The meaning is found after a bit of searching:

Sign-off is a requirement for getting patches into the Linux kernel and a few other projects, but most projects don’t actually use it.

It was introduced in the wake of the SCO lawsuit, (and other accusations of copyright infringement from SCO, most of which they never actually took to court), as a Developers Certificate of Origin. It is used to say that you certify that you have created the patch in question, or that you certify that to the best of your knowledge, it was created under an appropriate open-source license, or that it has been provided to you by someone else under those terms. This can help establish a chain of people who take responsibility for the copyright status of the code in question, to help ensure that copyrighted code not released under an appropriate free software (open source) license is not included in the kernel.

via Stack Overflow

Munchkin will use sign-offs!

PEAR

As mentioned above we’ll use pear as package manager. There is a usage mode of pear that is not as commonly known as it should be. You can create custom configuration files to drive pear commands with which enables you to handle project based dependencies. You wouldn’t need to litter your global space with packages that only one project needs. From our point of view we’ll utilize this feature via our build script. In order to achieve that we’ll need a 3rd party tool that enhances ant’s task-base with some neat macros.

To set up these files you need to add them as a Git submodule:

git submodule add git://github.com/meza/ant-helpers.git ant-helpers

This will create an ant-helpers directory in your root and a .gitmodules file which holds the Git specific information about this module. You need to commit these files too:

git commit -s -m'Added ant-helpers to the project'

More on Git submodules on progit.org

Your project root should look like:

.git/
ant-helpers/
.gitmodules
build.xml

We need to include the ant-helper files in order to use the pear related features. Modify your build.xml to look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<project name="Munchkin" default="build">
    <description>
        http://www.alternateillusion.com/munchkin-articles
    </description>

<!-- import ant-helpers -->
    <import file="${basedir}/ant-helpers/shell.xml" />
    <import file="${basedir}/ant-helpers/pear.xml" />

    <target name="build" description="Build the project"/>

</project>

This will enable us to use the <pear-generate-config>, pear-install and the <pear> tasks. We need to define a directory where we’ll hold the vendor files and we must exactly know what the pear config file will be. We define some top-level properties that all targets will be able to reach.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="UTF-8"?>
<project name="Munchkin" default="build">
    <description>
        http://www.alternateillusion.com/munchkin-articles
    </description>

<!-- set default properties -->
    <property name="vendor.dir"  location="${basedir}/vendor"/>
    <property name="pear.config" location="${basedir}/.pearrc"/>

<!-- import ant-helpers -->
    <import file="${basedir}/ant-helpers/shell.xml" />
    <import file="${basedir}/ant-helpers/pear.xml" />

    <target name="build" description="Build the project"/>

</project>

With all utilities present we can write all initially known targets.

build” is the main target in the file. It has a depends attribute which tells Ant that the comma separated other existing targets must be called before this one could be executed. We’ve cerated a “check-pear” task which checks for the ${pear.config} file to be present. If it can’t be found the build fails informing us that the task init must be issued before any further steps. “init” depends on two other tasks. It first removes all left-over files (if any) with “distclean” task, and generates the pear config file with “pear-generate-config“.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>
<project name="Munchkin" default="build">
    <description>
        http://www.alternateillusion.com/munchkin-articles
    </description>

<!-- set default properties -->
    <property name="vendor.dir"  location="${basedir}/vendor"/>
    <property name="pear.config" location="${basedir}/.pearrc"/>

<!-- import ant-helpers -->
    <import file="${basedir}/ant-helpers/shell.xml" />
    <import file="${basedir}/ant-helpers/pear.xml" />

<!-- Remove all generated content -->
    <target name="distclean" description="Remove all generated content">
        <delete dir="${vendor.dir}"/>
        <delete file="${pear.config}"/>
    </target>

<!-- Clean and prepare the first build -->
    <target name="init" depends="distclean, generate-pear-config"/>

<!-- Generate the pear config file -->
    <target name="generate-pear-config" depends="distclean">
        <pear-generate-config peardir="${vendor.dir}"/>
    </target>

<!-- Check if the pear config file is present and fail if not -->
    <target name="check-pear">
        <fail message="Run ant init">
            <condition>
                <not>
                    <available file="${pear.config}"/>
                </not>
            </condition>
        </fail>
    </target>

<!-- Build the project -->
    <target name="build" description="Build the project"
       depends="check-pear"/>

</project>

In order to build your project you’ll have to execute the following commands in your project root:

ant init

ant

You’ll notice here that there are some extra generated files that we you wouldn’t like to see in the repository. This could be avoided by not adding it via git add, but there’s a much more sophisticated way. Create a file called .gitignore and add the following contents:

vendor
.pearrc

This will tell Git to simply ignore these entries for good. To make this final you have to add it to your repo:

git add .gitignore

We’re done with our buildfile for now, so we can add that too:

git add build.xml – add the files to the repo

git commit -s -m'Utilizing ant-helpers and ignore file' – commit your work

Bring on some TDD!

So we’ve managed to create a nice little build file, but this is still not a ‘walking skeleton’. What do we need for that? A test! A test that proves us right. A test that can ensure us that our skeleton really walks. But what could be tested inn such early state? Does the domain exist? Is it giving us what we expect? But what do we expect from it? The solution is much more easier than you’d think. We expect it to give us a 200 OK response (means the url is existing).  But how do we test it? We could use Selenium / PHPUnit or some custom php script to verify the url exists. Luckily we have already created an Ant buildfile which is just suitable for our needs and as this step is vital for our project, the test should fail the build if the url is not present.

We’ll add a new property describing the url:

<property name="project.url" value="http://alternateillusion.com/munchkin_unexisting"/>

And we add a new target that will fail if the url is not found:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
<?xml version="1.0" encoding="UTF-8"?>
<project name="Munchkin" default="build">
    <description>
        http://www.alternateillusion.com/munchkin-articles
    </description>

<!-- set default properties -->
    <property name="vendor.dir"  location="${basedir}/vendor"/>
    <property name="pear.config" location="${basedir}/.pearrc"/>
    <property name="project.url" value="http://alternateillusion.com/munchkin_unexisting"/>

<!-- import ant-helpers -->
    <import file="${basedir}/ant-helpers/shell.xml" />
    <import file="${basedir}/ant-helpers/pear.xml" />

<!-- Remove all generated content -->
    <target name="distclean" description="Remove all generated content">
        <delete dir="${vendor.dir}"/>
        <delete file="${pear.config}"/>
    </target>

<!-- Clean and prepare the first build -->
    <target name="init" depends="distclean, generate-pear-config"/>

<!-- Generate the pear config file -->
    <target name="generate-pear-config" depends="distclean">
        <pear-generate-config peardir="${vendor.dir}"/>
    </target>

<!-- Check if the pear config file is present and fail if not -->
    <target name="check-pear">
        <fail message="Run ant init">
            <condition>
                <not>
                    <available file="${pear.config}"/>
                </not>
            </condition>
        </fail>
    </target>

<!-- Check if the project's url returns a 200 -->
    <target name="test-project-url">
        <fail message="Project url does not exist">
            <condition>
            <not>
                <http url="${project.url}"/>
            </not>
            </condition>
        </fail>
    </target>

<!-- Build the project -->
    <target name="build" description="Build the project"
       depends="check-pear, test-project-url"/>

</project>

If you run ant now you’ll get

Buildfile: build.xml

check-pear:

test-project-url:

BUILD FAILED
build.xml:43: Project url does not exist

Total time: 0 seconds

We just wrote a failing test!

That is the first goal of TDD. And when you have a failing test, make it pass. In our case we’ll write the correct url to the property.

<property name="project.url" value="http://alternateillusion.com/munchkin"/>

If all is right:

git add build.xml – add the files to the repo

git commit -s -m'First acceptance test' – commit your work

We’re almost done! Because we wouldn’t like to have any rough dependencies we’ll allow every user to define their own values of the properties in our buildfile without modifying anything in the repository. Ant has a sophisticated feature that handles this problem. You can define a file that will hold  key=value pairs defining properties. If you read this file after the default props are set, they will be overwritten by the ones in the file. So our final build.xml looks like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?xml version="1.0" encoding="UTF-8"?>
<project name="Munchkin" default="build">
    <description>
        http://www.alternateillusion.com/munchkin-articles
    </description>

<!-- set default properties -->
    <property name="vendor.dir"  location="${basedir}/vendor"/>
    <property name="pear.config" location="${basedir}/.pearrc"/>
    <property name="project.url" value="http://alternateillusion.com/munchkin"/>
    <property file="${basedir}/build.properties"/>

<!-- import ant-helpers -->
    <import file="${basedir}/ant-helpers/shell.xml" />
    <import file="${basedir}/ant-helpers/pear.xml" />

<!-- Remove all generated content -->
    <target name="distclean" description="Remove all generated content">
        <delete dir="${vendor.dir}"/>
        <delete file="${pear.config}"/>
    </target>

<!-- Clean and prepare the first build -->
    <target name="init" depends="distclean, generate-pear-config"/>

<!-- Generate the pear config file -->
    <target name="generate-pear-config" depends="distclean">
        <pear-generate-config peardir="${vendor.dir}"/>
    </target>

<!-- Check if the pear config file is present and fail if not -->
    <target name="check-pear">
        <fail message="Run ant init">
            <condition>
                <not>
                    <available file="${pear.config}"/>
                </not>
            </condition>
        </fail>
    </target>

<!-- Check if the project's url returns a 200 -->
    <target name="test-project-url">
        <fail message="Project url does not exist">
            <condition>
            <not>
                <http url="${project.url}"/>
            </not>
            </condition>
        </fail>
    </target>

<!-- Build the project -->
    <target name="build" description="Build the project"
       depends="check-pear, test-project-url"/>

</project>

If you add project.url=http://my.url.com to the build.properties file (which you may need to create if you’d like to use it), the next run will test that url.

To make sure the build.properties file doesn’t get into the repository, add it to the .gitignore file so that it would look like:

vendor
.pearrc
build.properties

Commit the changes:

git add .gitignore – add the ignore file

git add build.xml – add the files to the repo

git commit -s -m'First acceptance test with per-user config' – commit your work

What have we done?

We’ve created a project skeleton that is suitable for Munchkin, but still abstract enough to use it almost anywhere. You only need to modify the project name Ant url to apply this to any web project of your own. There’s no big magic and we didn’t quite use pear yet also. That will be the part of the next article. So what do we have? We have a deliverable software. It does nothing, and that’s the precise feature we expect it to do just now. There is a domain active for it. We’re sure it works. We can build the project and we have an end-to-end acceptance test.

Where to read on?

  • GIT: There is a great book about Git which you can read on-line at: http://progit.org/book
  • Ant: Ant is a tougher one. I haven’t found “one good source” to learn from, but google can be at help.
  • Nat Pryce and Steve Freeman’s book is also a great resource on testing.

The next Munchkin

In the next episode we’ll add pear dependencies through Ant and create our first PHPUnit driven end-to-end tests. With these present we’ll be able to hook the project to a Hudson job that will verify each and every repository updates. We’ll be introducing phpcpd, phpcs, phpmd, phploc and learn what the trends of these reports show us.

Though the title mentions initial stories, we’re holding them for the next post where we’ll start the first sprint!

Until then, you can get familiar with the global (we’ll use the pear project jail in Munchkin) setup of these tools at my post about code quality here!

Happy coding!

Other Munchkin articles

Clean Tdd Cheat sheet
Tue, 3/08/10 – 12:02 | No Comment
Clean Tdd Cheat sheet

Just found this great cheatsheet on twitter by @nickfloyd.
Use it wise and be the proud creator of lots of nice clean code!
download pdf

Selenium 2.0 Framework
Mon, 2/08/10 – 22:18 | No Comment
Selenium 2.0 Framework

Hi guys!
Here is a framework project. It consists of selenium 2.0 and object repository and user repository.
Use it wisely and give us credit.
https://sourceforge.net/projects/webauthfw/

We’re not superheroes – Invisible to the eye
Mon, 2/08/10 – 15:48 | No Comment
We’re not superheroes – Invisible to the eye

We’re not superheroes
I was reading bits of Coders at work, a book of interviews to famous programmers. I didn’t like it very much: here’s why.
The first thing I noticed is that many questions are biographical. I do not care about knowing if Ken Thompson, which built Unix, worked on a PDP-10 or a PDP-11 or [...]

Just read: Elisabeth and Eric Freeman – Head First Design Patterns
Mon, 2/08/10 – 7:32 | No Comment
Just read: Elisabeth and Eric Freeman – Head First Design Patterns

Product Details

Paperback: 688 pages
Publisher: O’Reilly Media; 1 edition (October 25, 2004)
Language: English
ISBN-10: 0596007124
ISBN-13: 978-0596007126
Product Dimensions: 9.2 x 8 x 1.4 inches
Shipping Weight: 2.8 pounds

Not as bad as it may look by the cover! Elisabeth Freeman relies on the feminine way of association. There are a lot of pictures, arrows, speech bubbles, acts and [...]

Munchkin – Planning – User types
Mon, 26/07/10 – 8:00 | 2 Comments
Munchkin – Planning – User types

We sat down today with @fqqdk to have a user modeling workshop. In this session we aimed to produce a set of stereotypes that the users of our product will have. We had a hard time because the use-cases are not so distinguished from each other. Most of the people who aggregate feeds are constant [...]

Just read: Mike Cohn – User Stories Applied
Sun, 25/07/10 – 16:26 | No Comment
Just read: Mike Cohn – User Stories Applied

Product Details

Paperback: 304 pages
Publisher: Addison-Wesley Professional (March 11, 2004)
Language: English
ISBN-10: 0321205685
ISBN-13: 978-0321205681
Product Dimensions: 9.1 x 7 x 0.7 inches
Shipping Weight: 1.2 pounds

I was holding this book in my hands a few times before I actually started reading it. I didn’t believe that a book can actually get me into a mood that extreme [...]

Munchkin a.k.a. learn greenfield TDD with PHP
Thu, 22/07/10 – 13:00 | 7 Comments
Munchkin a.k.a. learn greenfield TDD with PHP

In gaming, a Munchkin is a player who plays what is intended to be a non-competitive game (usually a role-playing game) in an aggressively competitive manner. A munchkin seeks within the context of the game to amass the greatest power, score the most “kills,” and grab the most loot, no matter [...]

PimpMyCode launched
Wed, 21/07/10 – 8:11 | No Comment
PimpMyCode launched

We’re proud to announce, that our PimpMyCode project has finally been launched. It’s purpose is to help all fellow PHP coders out there spending tons of time surfing for examples of testing their code. We know that how easy it is to find help in the Java world, and it’s the exact opposite with PHP.
With [...]

Just read: Chris Snyder & Michael Southwell – Pro PHP Security
Tue, 20/07/10 – 16:16 | No Comment
Just read: Chris Snyder & Michael Southwell – Pro PHP Security

Product Details

Paperback: 528 pages
Publisher: Apress; 1st ed. 2005. Corr. 2nd printing edition (August 29, 2005)
Language: English
ISBN-10: 1590595084
ISBN-13: 978-1590595084
Product Dimensions: 9.2 x 7.4 x 1.2 inches
Shipping Weight: 2 pounds

I was expecting to have much heureka moments reading this book, but I was let down. Being good in encryption doesn’t mean you’re good at [...]

Just read: Leonard Richardson & Sam Ruby – RESTful web services
Fri, 9/07/10 – 9:46 | One Comment
Just read: Leonard Richardson & Sam Ruby – RESTful web services

Product Details

Paperback: 448 pages
Publisher: O’Reilly Media; 1 edition (May 8, 2007)
Language: English
ISBN-10: 0596529260
ISBN-13: 978-0596529260
Product Dimensions: 9.1 x 7 x 1 inches

I didn’t really like the way were too over-descriptive. The knowledge inside the book is definitely makes it worth to read it. It made me actually get thinking the way of RESTful services. [...]