For the purposes of this article I will follow a fake company "Common Motors" and the evolution of testing software for each of their three product lines: Vans, Cars, & Trucks.
In the dark ages, before the days of hardware in the loop testing, it was a test engineer or technician's job to test everything. This means that with every release of software they had to sit down and validate all of the features in the software that was released.
For example, in the case of our CM Truck line, a software checkout will have started with an engineer sitting in the "CM Truck 101" following a simple checklist:
- Flash Software
- Key On
- [] Start Engine
- [] Check Idle
- [] Check Red Line
- [] Test Turn
- [] Left
- [] Right
- [] Brake Lights
- [] ...
As time went on managers and engineers both realized this was time consuming and expensive. You had to schedule time to get on a prototype vehicle, the vehicle was unable to do other testing to do a software checkout, etc.
Then along came bench testing.
In most cases hardware in the loop testing grew organically and in parrallel over time. For most hardware grou
in the loop testing grew organically and often in parallel.
In most instances this meant
keyswitch.py
:
import rtplib2
import CANape
platformIdentifier = "SCALEXIO"
applicationPath = r"C:\TurnSignal_SCALEXIO\BuildResult\turnlamp.sdf"
appl = rtplib2.Appl(applicationPath, platformIdentifier)
canape = canapy.CANape(a2l="turnlamp.a2l",
channels=["TurnSignalLevel"])
...
turnSignalLeverValue = appl.Variable("Model Root/TurnSignalLever[-1..1]/Value")
for turn_value in [0.0, 0.5, 1.0]:
turnSignalLeverValue.Write(turn_value)
assert canape.TurnSignalLevel == turn_value
...
app.close()
del app
pytest
is a mature full-featured Python testing tool that helps you write better programs. - pytest.org
A software test fixture sets up the system for the testing process by providing it with all the necessary code to initialize it, thereby satisfying whatever preconditions there may be. - Wiki: Software Test Fixture
conftest.py
:
import pytest
@pytest.fixture(scope="module",)
def app(request):
platformIdentifier = "SCALEXIO"
applicationPath = r"C:\TurnSignal_SCALEXIO\BuildResult\turnlamp.sdf"
app = rtplib2.Appl(applicationPath, platformIdentifier)
yield app
app.close()
del app
@pytest.fixture(scope="module")
def canape(request):
yield canapy.CANape(a2l="turnlamp.a2l",
channels=["TurnSignalLevel"])
test_turnsignal.py
:
def test_left(app, canape):
turnSignalLeverValue = appl.Variable("Model Root/TurnSignalLever[-1..1]/Value")
for turn_value in [0.0, 0.5, 1.0]:
turnSignalLeverValue.Write(turn_value)
assert canape.TurnSignalLevel == turn_value
- EuroPython 2014
- codebasics
- Python unit testing - pytest introduction
- [Python unit testing - pytest fixtures(https://www.youtube.com/watch?v=IVrGz8w0H8c)
- Python unit testing - pytest parameters
- Why I use py.test and maybe you should too - PyCon Australia
- What is Jenkins | Jenkins Tutorial for Beginners | Jenkins Continuous Integration Tutorial
- Introduction to using Jenkins CI to test your Python code
- Introduction to using Jenkins CI with your Python code
- Episode 16 – Holger Krekel [author of Py.Test] on Py.Test [mp3]
- Test & Code: pytest with Raphael Pierzina [mp3]
- Continuous Delivery with Jenkins Creator Kohsuke Kawaguchi [mp3]
- How to Achieve Continuous Software Delivery Using DevOps Tools and Methodologies
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.