sensors_sommerville-software-engineering-stages-of-testing.png
Stages in software testing from old edition of Software Engineering by Ian Sommerville (redrawn).

The essence of the diagram is testing small parts of the code in isolation and gradually assembling them into increasingly larger components until the application runs in a environment representative of how it will be used for real for the integration tests.

Testing can also be segmented into:

  • tests which check whether the application meets the requirements of the users and
  • tests which look for defects.

The latter often use unusual, boundary or erroneous inputs to check the behaviour is still acceptable.

Acceptance testing differs in that the participants are either the final users or a proxy for them. There may also be other groups of users like alpha and beta testers. Microsoft's Windows Insider program and "early access" in certain parts of the video games industry are variants on this.

TemperaturePlotSource class

The code below is theTemperaturePlotSource class. Objects are created in Python with the __init__(self) method. The current program only creates one object for Celsius and another for Fahrenheit leaving the conversion to Kelvin unused. The code looks reasonable at a quick glance.

Download: file
class TemperaturePlotSource(PlotSource):
    def _convert(self, value):
        return value * self._scale + self._offset

    def __init__(self, my_clue, mode="Celsius"):
        self._clue = my_clue
        range_min = 0.8
        if mode[0].lower() == "f":
            mode_name = "Fahrenheit"
            self._scale = 1.8
            self._offset = 32.0
            range_min = 1.6
        elif mode[0].lower == "k":
            mode_name = "Kelvin"
            self._scale = 1.0
            self._offset = -273.15
        else:
            mode_name = "Celsius"
            self._scale = 1.0
            self._offset = 0.0
        super().__init__(1, "Temperature",
                         units=mode_name[0],
                         abs_min=self._convert(-40),
                         abs_max=self._convert(85),
                         initial_min=self._convert(10),
                         initial_max=self._convert(40),
                         range_min=range_min,
                         rate=24)

    def data(self):
        return self._convert(self._clue.temperature)

Code Review

In this case, the code below is simple enough to mentally check the output from _convert() and data(). A close inspection reveals a difference in the way lower is being used. A code review is one way to discover bugs where another person checks the code. This is a very effective technique if the reviewer has sufficient review time, authority to reject the code and joint liability for the code.

The current program only creates one object for Celsius and another for Fahrenheit leaving the conversion to Kelvin unused. The CGP GCSE OCR Computer Science Revision Guide Book covers test plans and states:

A test plan will outline exactly what you're going to test and how you're going to test it. It should cover all the possible paths through a program.

A human tester cannot test the Kelvin code with the program as it stands. A programmatic approach to this is to write some code which tests this small piece of code in isolation. This is referred to as unit testing. The percentage of paths tested is known as code coverage and can be reported by software tools.

sensors_Le_Garcon_au_gilet_rouge-Paul_Cezanne-NG-1200x900.png
“New employee learns that his team’s codebase has no unit tests” from Classic Programmer Paintings. Also known as Boy in a Red Waistcoat (1888-1890) by Paul Cezanne.

Unit Testing

The unit test framework is not supported by CircuitPython but the code has excellent compatibility with Python allowing the tests to be executed on another computer and making that testing highly equivalent.

The same physical temperature sensor is unlikely to be present on another computer but this is not really a disadvantage as the real sensor gives an unpredictable temperature and one that probably lies in a very limited range most of the time.

Mocking

The sensor can be emulated in code for testing - this technique is referred to as mocking. Python has a mock object library which helps to do this.

The following pages explore using these techniques to find bugs in the code above.

This guide was first published on Apr 01, 2020. It was last updated on Apr 01, 2020.
This page (Testing) was last updated on Jun 14, 2020.