Dashboard > GreenPepper Open Documentation Refactoring > ... > Developer Guide > 7. Advanced developer guide
  GreenPepper Open Documentation Refactoring Log In View a printable version of the current page.  
  7. Advanced developer guide
Added by Laurent Cobos, last edited by Francois Denommee on Oct 29, 2009  (view change)
Labels: 
(None)

7. Advanced developer guide

Defining a custom system under development

Why ?

The system under development is a bridge between your Fixtures and the system your testing.
If you want to change the way is finding/instanciating your fixtures, or if you need to hook the document execution then you can define a Custom System Under Development.

To change the system under development :

Using custom types

All the examples in the documents are in strings, but fixtures want to process and return other data types.

provides a mechanism to help conversion from String to other data types and back again.

so an example that look likes
rule for SomeFixture with parameter 100$
color someBool answer
255,55,10 yes 14%
235,5,0 no 21%

Will match a class with the following method

public class SomeFixture {
   public SomeFixture(Ammount ammount) {...}

   public setColor(RGB color) ...
   public someBool(boolean yesNo)..
   public Ratio answer()...
}

Lets look at how will match these.

Converters

Converters are class implementing the interface com.greenpepper.converter.TypeConverter in java or GreenPepper.Converters.ITypeConverter in C#

public interface TypeConverter
{
    boolean canConvertTo( Class type );

    Object parse( String value, Class type );

    String toString( Object value );
}

namespace GreenPepper.Converters
{
    public interface ITypeConverter
    {
        bool CanConvertTo(Type type);

        object ValueOf(string value, Type type);

        string ToString(object value);
    }
}

provides out of the box type converters for the following types

  • Integer
  • Long
  • Float
  • Double
  • Date
  • Boolean
  • Array
  • String

or their simpler form int, long ...

(order is important see adding a new type converter below)

The ArrayConverter calls recursively the other converters depending on the component type the array holds.

Adding a new type converter

The com.greenpepper.GreenPepper class provides a method to add your own type converter

In Java
public static void register( TypeConverter converter)
"In C#"
public static void Register( ITypeConverter converter)

The better place to register your custom type is in a custom system under developement :

public static class CustomSystemUnderDevelopment extends DefaultSystemUnderDevelopment
    {
        public CustomSystemUnderDevelopment( String... params )
        {
           GreenPepper.register(new MyCustomTypeConverter());
        }
    }

The converters are always check in an LIFO manners. If two converters can process a data type the last one that has been register will be used. That way, you can provides your own converters in place of the standard converters.

Self conversion

Instead of registering a TypeConverter, you can uses self converting types.

Self converting type implies that you add a static parse method to your class.

Java

public static T parse(String val);

And then to revert back to a string,

public static String toString(T value)

C#

public static T ValueOf(string text)

And then to revert back to a string,

public static String ToString(T value)

Your class does not have to provides both of them.

Rules of conversion

From example to fixture

1 First will verify if the type is can self convert (ie public static T parse(String) or public static T ValueOf(string))
2 If not, look for a registered TypeConverter that can handles the type.
3 An UnsupportedOperationException will be thrown

From fixture return value to String

1 First will verify if the type is can self revert (ie public static String toString(T) or public static T ToString(string))
2 If not, look for a registered TypeConverter that can handles the type.
3 Use the toString() or ToString() method on the data itself.

Customizing GreenPepper fixture resolution

Prerequisite

To change fixtures resolutions you need to define a custom system under development

Changing how is finding your Fixtures

This could be useful when you are using for example an IOC, like Spring or just when you want to add locations (packages in java, namespaces in .Net) for can resolve your fixtures.

Only for specifying location to resolve fixtures (packages in java, namespaces in .Net)

public static class CustomSystemUnderDevelopment extends DefaultSystemUnderDevelopment
    {
        public CustomSystemUnderDevelopment( String... params )
        {
           super.addImport("com.mycompany.fixtures");
           super.addImport("com.mycompany.specials.fixtures");
        }
    }

By this custom system under development you tell to look in "com.mycompany.fixtures" and "com.mycompany.specials.fixtures" to resolve fixtures in specfications that your are running.

Changing Fixture instanciation mechanism (Spring example)

The Spring container system under development

Spring is an Inversion Of Control (IOC) container get more information about it on Spring website

SpringSystemUnderDevelopment code can be found in greenpepper-extensions-spring: SpringSystemUnderDevelopment.java

package com.greenpepper.extensions.spring;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;

import com.greenpepper.reflect.DefaultFixture;
import com.greenpepper.reflect.Fixture;
import com.greenpepper.systemunderdevelopment.DefaultSystemUnderDevelopment;

public class SpringSystemUnderDevelopment extends DefaultSystemUnderDevelopment
{
    private BeanFactory beanFactory;

    public SpringSystemUnderDevelopment(String... applicationCtxes)
    {
        this.beanFactory = new GreenPepperXMLAplicationContext(applicationCtxes).getBeanFactory();
    }
	
    public SpringSystemUnderDevelopment(BeanFactory beanFactory)
    {
        this.beanFactory = beanFactory;
    }

    @Override
    public Fixture getFixture(String fixtureName, String... params) throws Throwable
    {
		Fixture fixture;
		if (params.length != 0)
        {
		    // When params are used, we use the PlainOldSystemUnderDevelopment to instantiate the fixture
			// these params are passed to the constructor
            fixture = super.getFixture(fixtureName, params);
        }
		else
		{
	        try
	        {
	            fixture = new DefaultFixture(beanFactory.getBean(fixtureName));
	        }
	        catch (NoSuchBeanDefinitionException e)
	        {
	            fixture = new DefaultFixture(instantiateAsAutowiredBean(fixtureName));
	        }
		}
		
		return fixture;
    }

    private Object instantiateAsAutowiredBean(String fixtureName) throws Exception
    {
        Class fixtureClass = loadType(fixtureName).getUnderlyingClass();

        BeanDefinition beanDef = new RootBeanDefinition(fixtureClass, RootBeanDefinition.AUTOWIRE_AUTODETECT);
        
        DefaultListableBeanFactory fallFactory = new DefaultListableBeanFactory(beanFactory);
        fallFactory.registerBeanDefinition(fixtureName, beanDef);

        return fallFactory.getBean(fixtureName);
    }
}

Hooking document execution

To hook a document execution, you need to define a custom sytem under development

 public static class CustomSystemUnderDevelopment extends DefaultSystemUnderDevelopment
    {
        public CustomSystemUnderDevelopment( String... params )
        {
           
        }

       public void onStartDocument(Document document)
       {
          //this method is called before GreenPepper execute a document
       }

       public void onEndDocument(Document document)
       {
          //this method is called after GreenPepper has executed the document              
       }
    }

Execute specifications with command line

Introduction

This page describes how to execute a specification using the command line interface that comes with .

Features

provides a command line interface to execute specifications captured in HTML files. The command line interface has the following features:

  • Execution of a single specification file
  • Execution of a suite of specifications stored in a directory tree

GreenPepper command line

.NET command line options (GreenPepper Open Documentation Refactoring )
Customizing GreenPepper fixture resolution (GreenPepper Open Documentation Refactoring )
Defining a custom system under development (GreenPepper Open Documentation Refactoring )
Execute specifications with command line (GreenPepper Open Documentation Refactoring )
Hooking document execution (GreenPepper Open Documentation Refactoring )
Java command line options (GreenPepper Open Documentation Refactoring )
Using custom types (GreenPepper Open Documentation Refactoring )

DEMONSTRATION LICENSE - This Confluence site is for demonstration purposes only. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.4.3 Build:#705 Mar 21, 2007) - Bug/feature request - Contact Administrators