Chapter 4. Extending QMTest

Table of Contents

1. Extension Classes
2. Field Classes
3. Writing Test Classes
4. Writing Resource Classes
5. Writing Database Classes
6. Registering and Distributing Extension Classes

If the built-in functionality provided with QMTest does not serve all of your needs, you can extend QMTest. All extensions to QMTest take the form of Python classes. You can write new test classes, resource classes, or database classes in this way.

The contents of the class differ depending on the kind of extension you are creating. For example, the methods that a new test class must implement are different from those that must be provided by a new database class. In each case, however, you must create the class and place it in a location where QMTest can find it. The following sections explain how to create extension classes. The last section in this chapter explains how to register your new extension classes.

1. Extension Classes

All extensions to QMTest are implemented by writing a new Python class. This new Python class will be derived from an appropriate existing QMTest Python class. For example, new test classes are derived from Test while new test database classes are derived from Database.

The classes from which new extensions are derived (like Test) are all themselves derived from Extension. The Extension class provides the basic framework used by all extension classes. In particular, every instance of Extension can be represented in XML format in persistent storage.

Every Extension class has an associated list of parameter attributes. When an Extension instance is written out as XML, the value of each parameter is encoded in the output. Similarly, when an Extension instance is read back in, the parameter values are decoded. Conceptually, two Extension instances are the same if they are instances of the same derived class and their parameters have the same values.

Each parameter has a type. For example, every Test has a parameter called target_group. The target group is a string indicating on which targets a particular test should be run.

Each parameter is represented by an instance of Field. A Field instance can read or write values in XML format. A Field can also produce an HTML representation of a value, or an HTML form that allows a user to update the value of the field. It is the fact that all Extension parameters are instances of Field that makes it possible to represent Extension instances as XML. Smilarly, it is the use of the Field class that allows the user to edit tests in the QMTest GUI.

Each class derived from Extension may contain attributes that are instances of Field.

For example, after the following class definitions:

    class A(Extension):
        x = TextField()

    class B(A):
        y = IntegerField(default_value = 42)
        z = TextField(default_value = "a value")
  

A has one parameter (x) and B has three parameters (x, y, and z).

During construction of extensions you may provide arguments to set the values of these parameters (and thus overriding default values):

    a = A(x = "argument")
    b = B(x = "another argument", z = "value")
  

The serialized form of A will be equivalent to

<extension class="__main__.A">
  <argument name="x"><text>argument</text></argument>
</extension>
  

and for B

<extension class="__main__.B">
  <argument name="x"><text>another argument</text></argument>
  <argument name="y"><integer>42</integer></argument>
  <argument name="z"><text>value</text></argument>
</extension>
  

Extension instances hold appropriately typed attributes for all fields. A TextField translates to a str instance, while a IntegerField translates to an int, etc.

> a = A(x = "argument")
> print type(a.x), a.x
<type 'str'> argument