VCF Automation Blog

from Stefan Schnell

Basic explanations of unit tests can be found in the post Unit Test Library for Actions.

Using Unit Test Modules in Python Runtime Environment


Python offers in its standard library the doctest and unittest modules for unit testing. To run this kind of tests it is therefore not necessary to install third-party packages, which is very important for air-gapped environments. This post shows how these modules can be used in VCF Automation.

doctest

The Python doctest module is a standard library that makes it possible to use docstrings as unit tests, bases on the output from the standard Python interpreter shell. With doctest unit tests can be written directly in the code with minimal overhead.
doctest uses a primary prompt >>> which is followed by the tested commands. It is possible to use a secondary prompt ... when continuing commands on multiple lines. The expected result of the executing command is on the following line. A line starting with the primary prompt marks the end.
doctests are good for simple tests and simplifies the documentation, because test cases and examples are directly included in the code.

"""
@author Stefan Schnell <mail@stefan-schnell.de>
@license MIT
@version 1.0

@runtime python:3.11

@outputType Properties

Checked with Aria Automation 8.18.1 and VCF Automation 9.0.0
"""

import doctest
import json
import os

def add(summand1: int, summand2: int) -> int:
    """ Addition

    >>> import os, sys; sys.path.append(os.getcwd())
    >>> from handler import *
    >>> add(3, 2)
    5
    >>> add(16, 26)
    42
    >>> add(1, 1)
    3
    >>>

    """

    sum: int = summand1 + summand2
    return sum

def handler(context: dict, inputs: dict) -> dict:
    """ Aria Automation standard handler.
    """

    result: dict = {}
    outputs: dict = {}

    try:

        doctest.testfile(os.path.basename(__file__))

        outputs = {
            "status": "done",
            "error": None,
            "result": result
        }

    except Exception as err:

        outputs = {
            "status": "incomplete",
            "error": repr(err),
            "result": None
        }

    return outputs

Hint: It is necessary to add the import statement and the sys.path.append method in the docstring. The Python shell, which runs the doctest, needs this information to find and load the script. As far as known is the name of the generated Python script always handler.py.

vcf automation example usage of python doctest module for unit test

unittest

The Python unittest module is a standard library which contains a unit testing framework. It supports test automation and many features to write unit tests. It includes assertion methods that check specific conditions in tests and setup and teardown methods to manage the test environment.
unittests are good for not so simple tests. The difference to doctest is that the test cases are defined outside of the program code, program documentation and test description are separated, but this is of secondary importance for the use in VCF Automation. The clarity of the tests through the assert method names helps to quickly understand the purpose and expected behavior of a test.

"""
@author Stefan Schnell <mail@stefan-schnell.de>
@license MIT
@version 1.0

@runtime python:3.11

@outputType Properties

Checked with Aria Automation 8.18.1 and VCF Automation 9.0.0
"""

import json
import unittest

class addTest(unittest.TestCase):

    def testAdditions(self):
        self.assertEqual(add(3, 2), 5)
        self.assertEqual(add(16,26), 42)
        self.assertEqual(add(1, 1), 3)

def add(summand1: int, summand2: int) -> int:
    """ Addition
    """

    sum: int = summand1 + summand2
    return sum

def handler(context: dict, inputs: dict) -> dict:
    """ Aria Automation standard handler.
    """

    result: dict = {}
    outputs: dict = {}

    try:

        tests: list = [
            addTest("testAdditions")
        ]

        suite = unittest.TestSuite(tests = tests)
        runner = unittest.TextTestRunner(verbosity = 2)
        runner.run(suite)

        outputs = {
            "status": "done",
            "error": None,
            "result": result
        }

    except Exception as err:

        outputs = {
            "status": "incomplete",
            "error": repr(err),
            "result": None
        }

    return outputs

Hint: The unit test is executed here in the form of a test suite. The use of unittest.main() is not possible because the __main__ method originates from the caller index.py, which is created by VCF Automation to call handler.py.

vcf automation example usage of python unittest module for unit test

Conclusion

In principle both unit test modules of the Python standard library can be used in VCF Automation. However, the Python call stack of VCF Automation must be taken into account to enable its usage.
The actions built here are the unit tests. Of course, other actions can also be called in the tested functions. doctest is a good choice for simple tests, while unittest are more suitable for more complex applications.



Addendum

The following examples show how to use the doctest and unittest modules with an action call.

doctest

"""
@author Stefan Schnell <mail@stefan-schnell.de>
@license MIT
@version 1.0

@runtime python:3.11

@outputType Properties

Checked with Aria Automation 8.18.1 and VCF Automation 9.0.0
"""

from util.action import Action
import doctest
import json
import os

def getCompanyName(vcoUrl: str, bearerToken: str) -> str:
    """ getCompanyName

    >>> import os, sys; sys.path.append(os.getcwd())
    >>> from util.action import Action
    >>> from handler import *
    >>> action = Action()
    >>> action.invoke(
    ...     vcoUrl = vcoUrl,
    ...     bearerToken = bearerToken,
    ...     actionModule = "com.vmware.constants",
    ...     actionName = "getDefaultCompanyName",
    ...     parameters = []
    ... )["executionResult"]["value"]["string"]["value"]
    'VMware Inc.'
    >>>

    """

    action = Action()

    companyName: str = action.invoke(
        vcoUrl = vcoUrl,
        bearerToken = bearerToken,
        actionModule = "com.vmware.constants",
        actionName = "getDefaultCompanyName",
        parameters = []
    )["executionResult"]["value"]["string"]["value"]

    return companyName

def handler(context: dict, inputs: dict) -> dict:
    """ Aria Automation standard handler.
    """

    result: str = ""
    outputs: dict = {}

    try:

        vcoUrl: str = context["vcoUrl"]
        bearerToken: str = context["getToken"]()

        doctest.testfile(
            os.path.basename(__file__),
            globs = {
                "vcoUrl": vcoUrl,
                "bearerToken": bearerToken
            }
        )

        """
        result = getCompanyName(
            vcoUrl = vcoUrl,
            bearerToken = bearerToken
        )

        print(result)
        """

        outputs = {
            "status": "done",
            "error": None,
            "result": result
        }

    except Exception as err:

        outputs = {
            "status": "incomplete",
            "error": repr(err),
            "result": None
        }

    return outputs

vcf automation example usage of python doctest module for unit test with an action

unittest

"""
@author Stefan Schnell <mail@stefan-schnell.de>
@license MIT
@version 1.0

@runtime python:3.11

@outputType Properties

Checked with Aria Automation 8.18.1 and VCF Automation 9.0.0
"""

from util.action import Action
import json
import unittest

class actionTest(unittest.TestCase):

    def __init__(self, testname: str, vcoUrl: str, bearerToken: str):
        self.vcoUrl = vcoUrl
        self.bearerToken = bearerToken
        super().__init__(testname)

    def testAction(self):
        self.assertEqual(
            getCompanyName(self.vcoUrl, self.bearerToken),
            "VMware Inc."
        )

def getCompanyName(vcoUrl: str, bearerToken: str) -> str:
    """ getCompanyName
    """

    action = Action()

    companyName: str = action.invoke(
        vcoUrl = vcoUrl,
        bearerToken = bearerToken,
        actionModule = "com.vmware.constants",
        actionName = "getDefaultCompanyName",
        parameters = []
    )["executionResult"]["value"]["string"]["value"]

    return companyName

def handler(context: dict, inputs: dict) -> dict:
    """ Aria Automation standard handler.
    """

    result: dict = {}
    outputs: dict = {}

    try:

        vcoUrl: str = context["vcoUrl"]
        bearerToken: str = context["getToken"]()

        suite = unittest.TestSuite()
        suite.addTest(
          actionTest("testAction", vcoUrl, bearerToken)
        )
        runner = unittest.TextTestRunner(verbosity = 2)
        runner.run(suite)

        """
        result = getCompanyName(
            vcoUrl = vcoUrl,
            bearerToken = bearerToken
        )

        print(result)
        """

        outputs = {
            "status": "done",
            "error": None,
            "result": result
        }

    except Exception as err:

        outputs = {
            "status": "incomplete",
            "error": repr(err),
            "result": None
        }

    return outputs

vcf automation example usage of python unittest module for unit test with an action

References