This video shows how you can debug you code while running it under the QUTest unit testing
harness, both on the host computer as well as on deeply embedded targets.
I will start with the usual automatic execution of QUTest unit tests to review the setup.
Later, I will show what you need to change to debug the test fixture code on the host
computer.
And finally, I will show you how to debug the code on an embedded board.
So, starting with the setup, I will use a Windows host machine
and the simplest qutest-blinky example,
but the general process will apply also to Linux or MacOS hosts and more complex examples
as well.
I assume that you have downloaded and installed the QTools collection version 6.5.1 or higher.
And that you ran the QUTest installer for Windows, which adds the QTools binary directory
to your PATH and also defines the QTOOLS environment variable.
I also assume that you have downloaded the QP/C or QP/C++ real-time embedded frameworks
version 6.5.1 or higher
and you installed one of them on your machine.
In this video I will use the QP/C framework, but the discussion applies equally to QP/C++
as well.
To run the QUTest Blinky example, you open a command-prompt and verify your PATH and
the definition of the QTOOLS environment variable.
Next, you need to launch the QSPY host utility to mediate the communication between the target
and your test scripts.
The command-line option -u means that QSPY will open the UDP socket for communication
with the test scripts and -t means that QSPY will communicate with the Target via TCP/IP.
Next, you open another command-prompt and change the directory to the QUTest-Blinky-test
subdirectory.
Here, you simply type: make to run the provided Makefile.
As usual in TDD (Test Driven Development), the makefile both builds the test fixture
on the host and automatically runs the tests written in Python.
But the automatic process does not really support debugging of the code under test.
The problem is two-fold:
First, in the standard test run, the test fixture executable is automatically launched
multiple times by the test scripts, whereas for debugging the code must be started from
the debugger.
And second: the test script waits for the responses from the test fixture code for a
limited time only, whereas during debugging you typically halt the execution at various
breakpoints, which would cause the test scripts to time-out.
So, the process of debugging the QUTest fixture code needs to be different.
Here I will use Visual Studio Community edition to build the code for debugging, instead of
the command-line build with MinGW compiler that is used in the automatic build.
The blinky example conveniently provides a Visual Studio solution, which you can open
in Visual Studio 2013 or newer.
You build the code as usual,
and you can setup breakpoints for debugging.
For example, I set a breakpoint on the TIMEOUT transition in state off.
But before you actually start debugging, you go to the command-prompt and launch the makefile
with special target �debug�. This skips the build process, because the executable
is already built in Visual Studio.
Also, the debug target executes the test scripts in the special DEBUG mode, in which they attach
to QSPY, but don�t perform target reset and instead wait for the target to connect.
Now, while the test script is waiting, you start the target executable from the debugger.
As you can see, you hit the breakpoint in your code, while the test script patiently
waits.
You can continue debugging, at which point your first test finishes and the next test
starts.
This next test needs to reset the target, but in the debug mode it does not do this
automatically, but instead it patiently waits for YOU to reset the code from the debugger.
The code hits your breakpoint again.
And when you continue this time, all tests finish successfully.
One interesting aspect here is that you actually executed three tests, while you have reset
the target only twice: at the very beginning and once more in the middle.
As it turns out, the third test didn�t wait for the target reset and passed immediately.
The question is why?
Well, to understand it, you need to look at the test, which is included in the Python
module test_blinky.py.
When you scroll down to the third test, you can see that this is a NO-RESET test, which
means that it specifically does NOT reset the target.
So, that�s why this third test didn�t have to wait and finished so quickly.
So, this is how debugging with QUTest works on the host.
The last item for this video, is to show you you how you can debug with QUTest on an embedded
board.
Well, actually, the process is quite similar and there are only two differences.
First, you need to use a different development toolchain and debugger.
To this end, the blinky example provides the ARM-KEIL uVision project for the TivaC LaunchPad
board.
To use it, you need to have uVision installed on your machine. Here I use the free, size-limited
evaluation version.
And the second difference for working with an embedded board is that you need to re-launch
the QSPY host utility so that it communicates with the specific board
The QUTest test fixture for the TivaC LaunchPad uses the built-in virtual COM port to communicate
with QSPY.
To find out the port number, you open the Windows Device Manager...
You expand the Ports section, where you should see Stellaris Virtual Serial Port. You note
the COM port number, which happens to be COM3 in this case, but most likely will be different
on your machine.
Now, you go back to your QSPY command-prompt and instead of the -t option use -c with the
COM port you found out from the Device Manager.
Back in your Micro-Vision project, you open the blinky source code, which, by the way,
is exactly the same as you used on the host.
As before you set a breakpoint at the TIMEOUT transition in the Blinky-off state.
But before starting to debug the embedded code, you need to launch the test scripts
by issuing the make debug command. This step is identical as in the debugging on the host
and again, the exact same test scripts are used as well.
So, the test scripts start running and, as before, attach to QSPY and wait for the target.
Now you can start debugging the code on the target.
When the code stops at main, you continue and hit the breakpoint at the TIMEOUT transition.
You continue again and notice in the script window that the test passes and the next test
begins.
This next test requires target reset, and so it is waiting until YOU perform this reset
from the debugger.
After the reset, you hit the breakpoint again, at which point you can perform any usual debugging
activities, such as inspecting variables, the registers, or the memory.
Eventually, you continue which allows the tests to finish.
As you can see, the tests were not disturbed by the debugging activities, and all tests
have passed.
Also, the tests running in the debug mode can be skipped by pressing the Enter key.
This concludes this short tutorial about debugging with QUTest.
More information about the QUTest unit testing is available at state-machine.com, where you
can choose the Products|QUTest menu, or you can click
on the QUTest Unit Testing Harness link.
Thank you for watching.