Table of Contents

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.

image

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

  1. 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).

  2. Testsuites are function blocks implementing IUnitTest

    FUNCTION_BLOCK <POU>Test EXTENDS <POU> IMPLEMENTS Testbench.IUnitTest
    

    If 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.

  3. 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_VAR
    

    where assertions gives 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_VAR
    

    where <TYPE> can be any IEC61131-3 compatible type like DINT, INT, WORD, BOOL, (...)

    image

  4. Test may be parametrized by using the DataRow attribute. 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

image image