diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f417b6a443ca325a46580645212eaccca5c1c95a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+IMAGE_NAME = codecentric/springboot-maven3-centos
+
+build:
+	docker build -t $(IMAGE_NAME) .
+
+.PHONY: test
+test:
+	docker build -t $(IMAGE_NAME)-candidate .
+	IMAGE_NAME=$(IMAGE_NAME)-candidate test/run
diff --git a/test/run b/test/run
new file mode 100755
index 0000000000000000000000000000000000000000..224f80895fa27cbf5485ce52889e1a0273eff8f5
--- /dev/null
+++ b/test/run
@@ -0,0 +1,147 @@
+#!/bin/bash
+#
+# The 'run' performs a simple test that verifies that STI image.
+# The main focus here is to excersise the STI scripts.
+#
+# IMAGE_NAME specifies a name of the candidate image used for testing.
+# The image has to be available before this script is executed.
+#
+IMAGE_NAME=${IMAGE_NAME-codecentric/springboot-maven3-centos-candidate}
+
+test_dir="$(readlink -zf $(dirname "${BASH_SOURCE[0]}"))"
+image_dir=$(readlink -zf ${test_dir}/..)
+scripts_url="file://${image_dir}/.sti/bin"
+cid_file=$(mktemp -u --suffix=.cid)
+
+# Since we built the candidate image locally, we don't want STI attempt to pull
+# it from Docker hub
+sti_args="--forcePull=false -s ${scripts_url}"
+
+# TODO: This should be part of the image metadata
+test_port=8080
+
+info() {
+  echo -e "\n\e[1m[INFO] $@...\e[0m\n"
+}
+
+image_exists() {
+  docker inspect $1 &>/dev/null
+}
+
+container_exists() {
+  image_exists $(cat $cid_file)
+}
+
+container_ip() {
+  docker inspect --format="{{ .NetworkSettings.IPAddress }}" $(cat $cid_file)
+}
+
+run_sti_build() {
+  sti build ${sti_args} file://${test_dir}/test-app ${IMAGE_NAME} ${IMAGE_NAME}-testapp
+}
+
+prepare() {
+  if ! image_exists ${IMAGE_NAME}; then
+    echo "ERROR: The image ${IMAGE_NAME} must exist before this script is executed."
+    exit 1
+  fi
+  # TODO: STI build require the application is a valid 'GIT' repository, we
+  # should remove this restriction in the future when a file:// is used.
+  info "Build the test application image"
+  pushd ${test_dir}/test-app >/dev/null
+  git init
+  git config user.email "build@localhost" && git config user.name "builder"
+  git add -A && git commit -m "Sample commit"
+  popd >/dev/null
+  run_sti_build
+}
+
+run_test_application() {
+  docker run --rm --cidfile=${cid_file} -p ${test_port} ${IMAGE_NAME}-testapp
+}
+
+cleanup() {
+  info "Cleaning up the test application image"
+  if [ -f $cid_file ]; then
+    if container_exists; then
+      docker stop $(cat $cid_file)
+    fi
+  fi
+  if image_exists ${IMAGE_NAME}-testapp; then
+    docker rmi ${IMAGE_NAME}-testapp
+  fi
+  rm -rf ${test_dir}/test-app/.git
+}
+
+check_result() {
+  local result="$1"
+  if [[ "$result" != "0" ]]; then
+    info "TEST FAILED (${result})"
+    cleanup
+    exit $result
+  fi
+}
+
+wait_for_cid() {
+  local max_attempts=10
+  local sleep_time=1
+  local attempt=1
+  local result=1
+  info "Waiting for application container to start"
+  while [ $attempt -le $max_attempts ]; do
+    [ -f $cid_file ] && break
+    attempt=$(( $attempt + 1 ))
+    sleep $sleep_time
+  done
+}
+
+test_usage() {
+  info "Testing the 'sti usage' command"
+  sti usage ${sti_args} ${IMAGE_NAME} &>/dev/null
+}
+
+test_connection() {
+  info "Testing the HTTP connection (http://$(container_ip):${test_port})"
+  local max_attempts=10
+  local sleep_time=1
+  local attempt=1
+  local result=1
+  while [ $attempt -le $max_attempts ]; do
+    response_code=$(curl -s -w %{http_code} -o /dev/null http://$(container_ip):${test_port}/)
+    status=$?
+    if [ $status -eq 0 ]; then
+      if [ $response_code -eq 200 ]; then
+        result=0
+      fi
+      break
+    fi
+    attempt=$(( $attempt + 1 ))
+    sleep $sleep_time
+  done
+  return $result
+}
+
+# Build the application image twice to ensure the 'save-artifacts' and
+# 'restore-artifacts' scripts are working properly
+prepare
+
+info "Testing STI incremental build"
+run_sti_build
+check_result $?
+
+# Verify the 'usage' script is working properly
+test_usage
+check_result $?
+
+# Verify that the HTTP connection can be established to test application container
+run_test_application &
+
+# Wait for the container to write it's CID file
+wait_for_cid
+
+test_connection
+check_result $?
+
+cleanup
+
+info "All tests finished successfully."
diff --git a/test/test-app/pom.xml b/test/test-app/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3a3c5b5cf30e4ed5c6d734ffcb8add14634d9b88
--- /dev/null
+++ b/test/test-app/pom.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project
+  xmlns="http://maven.apache.org/POM/4.0.0"
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.springframework.boot</groupId>
+    <artifactId>spring-boot-starter-parent</artifactId>
+    <version>1.3.3.RELEASE</version>
+  </parent>
+  <dependencies>
+    <dependency>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-web</artifactId>
+    </dependency>
+  </dependencies>
+</project
diff --git a/test/test-app/src/main/java/de/codecentric/springbootmaven3centos/App.java b/test/test-app/src/main/java/de/codecentric/springbootmaven3centos/App.java
new file mode 100644
index 0000000000000000000000000000000000000000..fc277c16217b39de548eaab180bbe6a45f3a02bc
--- /dev/null
+++ b/test/test-app/src/main/java/de/codecentric/springbootmaven3centos/App.java
@@ -0,0 +1,21 @@
+package de.codecentric.springbootmaven3centos;
+
+import org.springframework.boot.*;
+import org.springframework.boot.autoconfigure.*;
+import org.springframework.stereotype.*;
+import org.springframework.web.bind.annotation.*;
+
+@Controller
+@EnableAutoConfiguration
+public class App {
+
+    @RequestMapping("/")
+    @ResponseBody
+    String home() {
+        return "Hello World!";
+    }
+
+    public static void main(String[] args) throws Exception {
+        SpringApplication.run(App.class, args);
+    }
+}