August 06, 2002

Properties grouping

Anteater
Jeff Turner finished implementing property groups in Anteater. These allow properties to be grouped and referred to as a whole in all the places they are needed.

In Anteater you define the behavior of a test by specifying various properties which affect the tasks which are part of the test. Up until property groups, you'd have to specify these properties each time you were using a particular task. With groups, you specify these properties in one place, and refer to all of them in your tasks. You can define specialized groups which inherit from a common set of properties, and modify or add new property definitions.

Here is Jeff's description of this feature:

Groups

Groups are like containers for Anteater objects, allowing reuse of definitions:

<group id="mygroup">
  <session/>
  <logger type="xml"/>
  <property name="host" value="localhost"/>
</group>

<!-- Each member task inherits the group's logger and session -->
<httpRequest group="mygroup" path="/a.html" .. />
<httpRequest group="mygroup" path="/b.html" .. />

Group Properties

Anteater tasks' behaviour is now configured through properties of the group to which the task belongs. Currently recognised properties are 'host', 'port', 'debug', 'timeout', 'protocol', 'haltonerror' and 'usetidy'. So if we had:

<group id="cocoontests">
  <property name="host" value="myhost.com"/>
  <property name="port" value="8080"/>
  <property name="debug" value="0"/>
</group>
<httpRequest group="cocoontests" ... />
<httpRequest group="cocoontests" ... />

Then those tasks would run against myhost.com:8080, with debug level 0, unless overridden by attributes on the httpRequest object.

Group properties can also be set from outside a group:

<property name="cocoontests.debug" value="2"/>

This allows group values to be specified in properties files outside the test script, or from the command-line, eg:

anteater -Dcocoontests.host=localhost -Dcocoontests.debug=2 -f tests.xml

Group Inheritance

Since a Group object is an Anteater object, a Group can belong to another Group, either by nesting:

<group id="a">
  <property name="host" value="myhost.com"/>
  <group id="b"/>
</group>

or by the 'inherits' attribute ('group' also works):

<group id="a">
  <property name="host" value="myhost.com"/>
</group>
<group id="b" inherits="a"/>

Group elements are inherited in what I hope seems a natural manner. Properties are passed through unless overridden, so 'b' in the above example has host 'myhost.com'. Loggers are passed through, unless any loggers are defined in the child group. Same with sessions.

The Default Group

There is an implicit 'default' group, to which all tasks belong unless otherwise indicated. If the default group were written out, it would look like this:

  <group id="default">
  <session/>
  <logger type="minimal"/>
  <property name="host" value="localhost"/>
  <property name="debug" value="0"/>
  <property name="port" value="BUILTIN,8080"/>
  <property name="timeout" value="30s"/>
  <property name="protocol" value="HTTP/1.0"/>
  <property name="haltonerror" value="false"/>
  <property name="usetidy" value="false"/>

  <!-- Declare all other groups as children of 'default' here -->
  <group refid=".."/>
  ...
</group>

So by default, all tasks get a session, and a logger that prints to stdout, plus a bunch of properties used to configure the default Anteater behaviour.

The default group can be overridden by the user, by declaring a group with id 'default'. This way, we can override specific properties for all tasks:

<group id='default'>
  <property name="host" value="myhost.com"/>
  <property name="port" value="8080"/>
</group>

All other items are inherited from the 'default' defaults.

And of course the 'default' group properties can be overridden at the command-line, eg -Ddefault.host=myotherhost.com.

Putting it all together

The purpose of grouping has been to make simple things easier, and complicated things possible. Some scenarios, from simple to complex:

  • With the advent of the default group, most users need never bother with loggers, sessions, groups or properties. They just rely on the defaults, maybe occasionally overriding them, eg -Ddefault.debug=5.
  • For users for whom the defaults need modifying, that can easily be done by overriding the 'default' group, and otherwise not touching the script. Want to log to XML as well as the console? Redefine the default group:
      <group id="default">
        <logger type="minimal"/>
        <logger type="xml" todir="${log.dir}"/>
      </group>
      
  • Users with somewhat large scripts, who want to break it up into sections can do so, by defining a hierarchy of groups:
      <group id="mytests">
        <property debug="0"/>
      </group>
      <group id="livesite" inherits="mytests">
        <property name="host" value="www.mysite.com"/>
        <logger type="xml" todir="{docs.dir}"/> <!-- HTML report -->
      </group>
      <group id="devsite" inherits="mytests">
        <property name="host" value="www.mysite-dev.com"/>
        <property name="debug" value="1"/> <!-- devsite a bit unstable -->
        <property name="failonerror" value="true"/> <!-- Don't waste time testing whole site -->
    
        <group id="devsite-brokenbit">
          <!-- Very broken bit of devsite -->
          <property name="debug" value="10"/>
      </group>
    
      <httpRequest group="section1" ... />
      ...
    

So we define a hierarchy of groups at the top of the script, and then use it in the subsequent tests.

Posted by ovidiu at August 06, 2002 04:21 PM |
 
Copyright © 2002-2016 Ovidiu Predescu.