Test Explorer
Test Explorer is a tool provided by the Zeugwerk Creator developed to enhance the testing experience for TwinCAT projects. Tailored specifically for Beckhoff's TwinCAT automation platform, this tool seamlessly integrates with Visual Studio, providing a user-friendly interface to discover and execute tests directly within the TwinCAT development environment.
The primary goal of Test Explorer is to simplify the testing workflow for PLC developers by offering clear visibility into test results, test case organization, and execution status—all from within the IDE. Whether you are building complex automation systems or verifying critical control logic, TwinCAT Test Explorer helps ensure that your code remains robust, reliable, and easy to maintain.
Usage
Testexplorer automatically discovers tests, which are implemented with the Testbench library. This is a lightweight library designed to provide a unified interface for various PLC unittest framework implementations. It acts as a bridge, allowing developers to write consistent test logic while supporting multiple underlying test frameworks. It reduces the overhead to write tests and therefore lower the hurdle for writing unittests, to a bare minimum!
Implement Unittests
Add Testbench to your PLC by including it as a dependency. The simplest way todo this is by using Twinpack Package Manager, alternatively you can grab the latest release from GitHub and install it manually in the TwinCAT XAE).
Testsuites are function blocks implementing IUnitTest
FUNCTION_BLOCK <POU>Test EXTENDS <POU> IMPLEMENTS Testbench.IUnitTestIf prefered, it is of course also possible to add the
<POU>as an instance to the function block. However, due to limitations of structured text, it can be helpful to actually extend from the object to get access protected methods of the POU.Tests are implemented as method for each testsuite. Methods, which are considered unittests follow the following signature.
METHOD Test_<NAME OF THE TEST> VAR_INPUT assertions : Testbench.IAssertions; END_VARwhere
assertionsgives access to a large variety of checks (EqualsDint,IsTrue,EqualsArray2dLreal, ...).Alternatively, for more simple tests with only 1 assertion
METHOD Test_<NAME OF THE TEST> VAR_OUTPUT expected : <TYPE>; actual : <TYPE>; message : STRING(255); END_VARwhere
<TYPE>can be any IEC61131-3 compatible type likeDINT,INT,WORD,BOOL, (...)Test may be parametrized by using the
DataRowattribute. When generating the unittest, every datarow will be its own test. The signature for using paramtrized tests looks as follows.{attribute 'DataRow(<PARAMETER_1 VALUE>, <PARAMETER_2 VALUE>, ..., <PARAMETER_N VALUE>)'} {attribute 'DataRow(<PARAMETER_1 VALUE>, <PARAMETER_2 VALUE>, ..., <PARAMETER_N VALUE>)'} // ... {attribute 'DataRow(<PARAMETER_1 VALUE>, <PARAMETER_2 VALUE>, ..., <PARAMETER_N VALUE>)'} METHOD Test_<NAME OF THE TEST> VAR_INPUT assertions : IAssertions; <PARAMETER_1> : <PARAMETER_1 DATATYPE> <PARAMETER_2> : <PARAMETER_2 DATATYPE> // ... <PARAMETER_N> : <PARAMETER_N DATATYPE> END_VAR
Execute Unittests
- Navigate to
Tools > Zeugwerk Creator > Test Explorer - In the new pane, click on
Run All Tests, this will- Compile your PLC and check all objects
- Install it as a local library
- In the background create a new PLC containing the code generation for all tests (
tests/Tests.sln) - Compile the Testing PLC
- Activate it on a target
You can check the Examples PLC in this repository for a demonstration