Python vs TTCN-3

Some time ago computing scientists Bernard Stepien and Liam Peyton from the University of Ottawa compared Python with TTCN-3. TTCN-3 means Testing and Test Control Notation and it is domain specific language specifically designed for writing tests in the domain of telecommunication. In almost any category poor Python just loses in comparison.

A few things of the presentation are just odd. At several places it contains Python code that is not even consistent. Examples: on slide 42 an “else if” construct is used instead of the correct “elif”. On slide 13 fields are not assigned to self which leads to code that fails to run. But leaving this carelessnes aside there is something important that estranges an experienced Python programmer. Take slide 12 for example. Here the authors state:

TTCN-3 templates to Python

  • TTCN-3 templates could be mapped to Python object instances.
  • However, there are serious limitations using the above technique with Python.
  • Python objects are practically typeless.

Then the presentation goes over 18 slides just to explain how bad plain Python classes are for serving the same purposes as TTCN-3 templates. Although this is correct why should anyone care? If you want to experience an exhilarating effect you have to turn grapes into wine and do not expect the same fun from grape juice. Then you can compare cheap wine with premium one. That’s also why people are used to compare Django to Ruby On Rails and not Django to Ruby or Rails to Python. That’s why libraries and frameworks exist in the first place.

So what about modeling a `Template` class that has same functionality as a TTCN-3 template? Here is a first attempt:

class Template(object):
    def __init__(self):
        self._frozen = False
        self._fields = []        
 
    def __setattr__(self, name, value):
        if name in ('_fields', '_frozen'):
            object.__setattr__(self, name, value)
            return
        if self._frozen:
            raise RuntimeError("Cannot set attribute value on a frozen template")
        if name not in self._fields:
            self._fields.append(name)
        object.__setattr__(self, name, value)
 
    def __eq__(self, other):
        if len(self._fields)!=len(other._fields):
            return False
        else:
            for f_self, f_other in zip(self._fields, other._fields):
                val_self  = getattr(self, f_self)
                val_other = getattr(self, f_other)
                if val_self != val_other:
                    return False
            return True
 
    def __ne__(self, other):
        return not self.__eq__(other)
 
    def freeze(self):
        self._frozen = True
 
    def clone(self):
        T = Template()
        T._fields = self._fields[:]
        for field in T._fields:
            setattr(T, field, getattr(self, field))
        return T

The `Template` class manages an internal `_fields` attribute that contains the attribute names created by `__setattr__` dynamically. This is done to preserve the sequential order of the fields on template comparison. In the current implementation there aren’t any fields marked as optional and it will take additional effort to introduce them and modify `__eq__`.

It is now easy to demonstrate the behavior of wildcards. First we have to introduce another class for this purpose:

class Wildcard(object):
    def __eq__(self, other):
        return True
 
    def __ne__(self, other):
        return False

For any object `X` which is compared to `wildcard` it is always `X == wildcard == True`. So following template instances are equal:

templ_1 = Template()
templ_1.field_1 = wildcard
templ_1.field_2 = "abc"
 
templ_2 = Template()
templ_2.field_1 = "xyz"
templ_2.field_2 = wildcard
 
assert templ_1 == templ_2

A `Pattern` class can be created in the same way as the Wildcard class:

class Pattern(object):
    def __init__(self, regexp):
        self.pattern = re.compile(regexp)
 
    def __eq__(self, other):
        try:
            return bool(self.pattern.match(other))
        except TypeError:
            return True
 
    def __ne__(self, other):
        return not self.__eq__(other)

An `’==’` comparison of a `Pattern` instance with a string will match the string against the pattern and yield `True` if the string could be matched and `False` otherwise.

So it is perfectly possible to reproduce most aspects of TTCN-3 templates by just a few lines of Python code. On the downside of `TTCN-3` it isn’t possible to do things the other way round. No matter how hard you work in TTCN-3 it is impossible to create new TTCN-3 types showing interesting behavior. Pythons expressiveness is miles ahead.

This entry was posted in DSL, Python, Testing. Bookmark the permalink.

4 Responses to Python vs TTCN-3

  1. As a tester/developer I’ve always wondered why people want to separate testing and development in general, but having a separate testing language is just insane. A general purpose language with testing related modules/tools is so much better idea.

    About the comparison: The example on page 21 with trying to use two __init__s and complaining that only the latter is used makes it obvious that these guys don’t know any Python. Default values for methods are explained pretty early in any tutorial — and they are so much easier to use and clearer than having multiple methods with different signatures.

    A simple solution for ‘‘ and ‘?’ wildcards in Python is using fnmatch module (with a caveat that ‘‘ doesn’t match newlines).

  2. Ionel Maries says:

    I would dismiss the comparison on the spot. It’s full of misconceptions about python and typing theory.
    Take for example this outrageous statement in the pdf slides: “Known limitations of Python: OO language but not strongly typed” – python IS strongly typed AND duck typed. I wonder if the authors took any classes on typing theory.

  3. Joseph Lisee says:

    They also said that python has no Eclipse plugin which is just not true. Pydev is a great eclipse plugin for Python and I use it all the time.

  4. kay says:

    Pekka, the predecessor of TTCN-3 can be tracked back to the late 80s. TTCN-3 can be considered as a pre-OO and pre-UML attempt to define something like “model based testing” and it is still widely used for conformance tests in some industries. It is obvious that the authors are biased and try to promote TTCN-3 and there wouldn’t be anything wrong about it if their arguments weren’t just flawed.

Comments are closed.