Examples¶
Simple Production Test¶
The standard production test consists of running the same test consistently on
every start()
of the TestSequence. In this sequence,
the hardware is allocated on-the-fly within each test.
from time import sleep
from random import choice, random
from mats import Test, TestSequence, ArchiveManager
from my_lib import Device, FlowSensor
# A simple communications check with a device
class CommunicationTest(Test):
def __init__(self):
super().__init__(moniker='communications test',
pass_if=True)
def setup(self, is_passing):
# initialize hardware communications
self._device = Device()
# wait for communication to begin...
while not self._device.is_communicating:
sleep(0.1)
# overriding the execute method
def execute(self, is_passing):
# should return a the results of the test
return self._device.is_communicating
def teardown(self, is_passing):
# de-allocate the hardware
self._device.close()
# The FlowTest implements the `setup' and `teardown` methods
# as well in order to demonstrate what that may look like
class FlowTest(Test):
def __init__(self):
super().__init__(moniker='pump flow test',
min_value=5.6, max_value=6.4)
def setup(self, is_passing):
# initialize hardware
self._flow_sensor = FlowSensor()
# wait for flow sensor to begin pulling values
while self._flow_sensor.value is not None:
sleep(0.1)
def execute(self, is_passing):
return self._flow_sensor.value
def teardown(self, is_passing):
# again, simulating another long-running process...
self._flow_sensor.close()
if __name__ == '__main__':
# create the sequence of test objects
sequence = [CommunicationTest(), FlowTest()]
# create the archive manager
am = ArchiveManager()
# create the test sequence using the sequence and archive manager
# objects from above
ts = TestSequence(sequence=sequence,
archive_manager=am,
auto_run=False)
# start the test as many times as you wish!
for _ in range(3):
ts.start()
sleep(2.0)
Simple Production Test (revisited)¶
The production test could also be done by allocating the hardware at the beginning of the sequence and realizing some time-saving on each test execution of the test.
from time import sleep
from random import choice, random
from mats import Test, TestSequence, ArchiveManager
from my_lib import Device, FlowSensor
# A simple communications check with a device
class CommunicationTest(Test):
def __init__(self, device: Device):
super().__init__(moniker='communications test',
pass_if=True)
self._device = device
# overriding the execute method
def execute(self, is_passing):
# should return a the results of the test
return self._device.is_communicating
class FlowTest(Test):
def __init__(self, flow_sensor: FlowSensor):
super().__init__(moniker='pump flow test',
min_value=5.6, max_value=6.4)
self._flow_sensor = flow_sensor
def execute(self, is_passing):
return self._flow_sensor.value
if __name__ == '__main__':
# hardware allocated one time during program initialization, no
# need to re-allocate during CommunicationTest and FlowTest
device = Device()
flow_sensor = FlowSensor()
while not device.is_communicating and flow_sensor.value is not None:
sleep(0.1)
# create the sequence of test objects
sequence = [
CommunicationTest(device=device),
FlowTest(flow_sensor=flow_sensor)
]
# create the archive manager
am = ArchiveManager()
# create the test sequence using the sequence and archive manager
# objects from above
ts = TestSequence(sequence=sequence,
archive_manager=am,
auto_run=False)
# start the test as many times as you wish!
for _ in range(3):
ts.start()
sleep(2.0)
Production Test with Burn-In¶
This test is similar to the above production test. We use the setup method to provide a burn-in and provide a count.
from time import sleep
from random import choice, random
from mats import Test, TestSequence, ArchiveManager
# The CommunicationTest class shows the minimum test structure
# that might be reasonably be implemented. Only the `execute()`
# method is implemented.
class CommunicationTest(Test):
def __init__(self):
super().__init__(moniker='communications test',
pass_if=True)
# overriding the execute method
def execute(self, is_passing):
# a normal test would set `test_is_passing` based on
# real conditions, we are implementing a random value
# here simply for illustrative purposes
is_communicating = choice([True] * 3 + [False])
# should return a (key, value) which are the results of
# the test
return is_communicating
# The FlowTest implements the `setup' and `teardown` methods as
# well in order to demonstrate what that may look like
class BurnIn(Test):
def __init__(self):
super().__init__(moniker='burnin', min_value=5.6, max_value=6.4)
def setup(self, is_passing):
# just wait for a while, maybe display a bit of a countdown...
seconds = 0
while seconds < 10:
seconds += 1
self._logger.info(f'burning in count: {seconds}s')
sleep(1.0)
def execute(self, is_passing):
# check to see if the device is still communicating
is_communicating = choice([True] * 3 + [False])
# should return a (key, value) tuple which are the results
# of the test
return is_communicating
if __name__ == '__main__':
# create the sequence of test objects
sequence = [CommunicationTest(), BurnIn()]
# create the archive manager
am = ArchiveManager()
# create the test sequence using the sequence and archive
# manager objects from above
ts = TestSequence(sequence=sequence,
archive_manager=am,
auto_run=False)
# start the test as many times as you wish!
ts.start()
Life Test¶
A test that simulates on-off cycles and keeps chugging… forever… and ever…
from random import choice
from time import sleep
from mats import Test, TestSequence, ArchiveManager
class LifeTest(Test):
def __init__(self):
super().__init__(moniker='life test', pass_if=True)
def setup(self, is_passing):
# do_something_to_setup()
sleep(0.1)
def execute(self, is_passing):
sleep(0.5)
# simulate the collection of some data, then return it so
# that the 'pass-if' condition may be applied
result = choice([True] * 2 + [False])
return result
def teardown(self, is_passing):
# do_something_to_teardown()
sleep(0.1)
if __name__ == '__main__':
from datetime import datetime
logger = logging.getLogger(__name__)
ts = TestSequence(
sequence=[LifeTest()],
archive_manager=ArchiveManager(path='.'),
auto_run=3, # run the test automatically after every iteration
)
# allow the test to run until it has completed
start_dt = datetime.now()
while ts.in_progress:
sleep(0.1)
logger.info(f'test time: {datetime.now() - start_dt}')