E2E Python solution in DevOps – Part 6: Add test cases to project

In this serie I show you how you can create a PyPi ready solution which is stored on GitHub and has fully automatized build-test-deploy CI/CD pipeline in Azure DevOps. Furthermore you will be able to use it from command line like azure-cli or aws-cli.

Table of content

In Part 5 more or less we reached our goal. Nevertheless several integrated test cases (unittest) are recommended in a well built code. Therefore Today we add a unittest to our project.

Before we start we need to know some facts about unittests in Python:

  • Unittest implementation is not a rocket science, merely we have to follow the best practices
  • During unittest the functions are really executing. This means when you test a function in unittest it will call in live not only for testing.
  • Prepare your unittest for modular usage.

Then recommended to know the background of unittests:

We use the Python 2.7 related unittest in our project.

1. We create unittest for our Core module. Therefore the simplest thing if we put our unittest next to core module files inside core directory (<project directory>/pypiproject/core). Name if this file in our example is: pypiproject_core_unittest.py

2. Content of the file is very simple.

  • unittest package import
  • core module import for testing
  • TestCase moduile class which contains the required test cases
  • TestCase runner function – this is required because we won’t run unittest from __main__.
# Import unittest
import unittest

# Import core module main file for testing
from .pypiproject_core import *

# Test case Class
class TestCoreModule(unittest.TestCase):
    currentResult = None # holds last result object passed to run method

    def setUp(self):

    # teardown for manage test case results
    def tearDown(self):
        ok = self.currentResult.wasSuccessful()
        errors = self.currentResult.errors
        failures = self.currentResult.failures
        print ('All tests passed so far!' if ok else \
                ' %d errors and %d failures so far' % \
                (len(errors), len(failures)))

    def run(self, result=None):
        self.currentResult = result # remember result for use in tearDown
        unittest.TestCase.run(self, result) # call superclass run method

    # Test Case 01 - Write out text in string format with default value
    def test_input(self):
        self.assertEqual(getText("test text"), "test text")

    # Test Case 02 - Write out text in string and json format
    def test_output(self):
        self.assertEqual(getText("test text", "string"), "test text")
        self.assertEqual(getText("test text", "json"), {"text": "test text"})

# Test runner function
def runUnittests():
    suite = unittest.TestSuite()
    # Check test cases in TestCoreModule class
    for method in dir(TestCoreModule):
        # Add test collection tests which start with "test"
        if method.startswith("test"):
    # Return with execution and result of testcases
    return unittest.TextTestRunner(verbosity=3).run(suite)

3. How can you run the test cases?

It is pretty easy and simple to automatize

Start a Python shell where our project is installed then execute the following commands:

from pypiproject.core.pypiproject_core_unittest import *
testResult = runUnittests()

and the result is awesome:

test_input (pypiproject.core.pypiproject_core_unittest.TestCoreModule) ... All tests passed so far!
test_output (pypiproject.core.pypiproject_core_unittest.TestCoreModule) ... All tests passed so far!

Ran 2 tests in 0.003s


Additionally the testResult variable contains the detailed result of execution.

It was easy and I hope make sense. If you have any further questions feel free to get in touch with your questions.

Be the first to comment on "E2E Python solution in DevOps – Part 6: Add test cases to project"

Leave a comment

Positive SSL