├── .github └── ISSUE_TEMPLATE │ └── bug_report.md ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── TcUnit-Verifier ├── README.md ├── TcUnit-Verifier_DotNet │ ├── TcUnit-Verifier.sln │ └── TcUnit-Verifier │ │ ├── App.config │ │ ├── AutomationInterface.cs │ │ ├── Constants.cs │ │ ├── ErrorList.cs │ │ ├── FB_AdjustAssertFailureMessageToMax253CharLengthTest.cs │ │ ├── FB_AnyPrimitiveTypes.cs │ │ ├── FB_AnyToUnionValue.cs │ │ ├── FB_ArrayPrimitiveTypes.cs │ │ ├── FB_AssertCountExceedsMaxNumber.cs │ │ ├── FB_AssertEveryFailedTestTwice.cs │ │ ├── FB_AssertEveryFailedTestTwiceArrayVersion.cs │ │ ├── FB_AssertTrueFalse.cs │ │ ├── FB_CheckIfSpecificTestIsFinished.cs │ │ ├── FB_CreateDisabledTest.cs │ │ ├── FB_CreateFourTestsWithSameName.cs │ │ ├── FB_EmptyAssertionMessage.cs │ │ ├── FB_ExtendedTestInformation.cs │ │ ├── FB_MultipleAssertWithSameParametersInDifferentCyclesAndInSameTest.cs │ │ ├── FB_MultipleAssertWithSameParametersInDifferentCyclesButWithDifferentTests.cs │ │ ├── FB_MultipleAssertWithSameParametersInSameCycleWithSameTest.cs │ │ ├── FB_PrimitiveTypes.cs │ │ ├── FB_SkipAssertionsWhenFinished.cs │ │ ├── FB_TestDurationMeasurement.cs │ │ ├── FB_TestFileControl.cs │ │ ├── FB_TestFinishedNamed.cs │ │ ├── FB_TestNumberOfAssertionsCalculation.cs │ │ ├── FB_TestStreamBuffer.cs │ │ ├── FB_TestXmlControl.cs │ │ ├── FB_WriteProtectedFunctions.cs │ │ ├── LICENSE_NDesk_Options.txt │ │ ├── LICENSE_log4net.txt │ │ ├── MessageFilter.cs │ │ ├── Options.cs │ │ ├── Program.cs │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── TcUnit-Verifier.csproj │ │ ├── TestFunctionBlockAssert.cs │ │ ├── VisualStudioInstance.cs │ │ ├── log4net.config │ │ └── packages.config ├── TcUnit-Verifier_TwinCAT │ ├── TcUnit-Verifier_TwinCAT.sln │ └── TcUnit-Verifier_TwinCAT │ │ ├── TcUnit-Verifier_TwinCAT.tsproj │ │ ├── TcUnitVerifier │ │ ├── POUs │ │ │ └── FB_ProtectedVariables.TcPOU │ │ ├── PlcTask.TcTTO │ │ ├── TcUnitVerifier.plcproj │ │ ├── Test │ │ │ ├── FB_AdjustAssertFailureMessageToMax253CharLengthTest.TcPOU │ │ │ ├── FB_AnyPrimitiveTypes.TcPOU │ │ │ ├── FB_AnyToUnionValue.TcPOU │ │ │ ├── FB_ArrayPrimitiveTypes.TcPOU │ │ │ ├── FB_AssertCountExceedsMaxNumber.TcPOU │ │ │ ├── FB_AssertEveryFailedTestTwice.TcPOU │ │ │ ├── FB_AssertEveryFailedTestTwiceArrayVersion.TcPOU │ │ │ ├── FB_AssertTrueFalse.TcPOU │ │ │ ├── FB_CheckIfSpecificTestIsFinished.TcPOU │ │ │ ├── FB_CreateDisabledTest.TcPOU │ │ │ ├── FB_CreateFourTestsWithSameName.TcPOU │ │ │ ├── FB_EmptyAssertionMessage.TcPOU │ │ │ ├── FB_EmptyTestSuite.TcPOU │ │ │ ├── FB_ExtendedTestInformation.TcPOU │ │ │ ├── FB_MultipleAssertWithSameParametersInDifferentCyclesAndInSameTest.TcPOU │ │ │ ├── FB_MultipleAssertWithSameParametersInDifferentCyclesButWithDifferentTests.TcPOU │ │ │ ├── FB_MultipleAssertWithSameParametersInSameCycleWithSameTest.TcPOU │ │ │ ├── FB_PrimitiveTypes.TcPOU │ │ │ ├── FB_SkipAssertionsWhenFinished.TcPOU │ │ │ ├── FB_TestDurationMeasurement.TcPOU │ │ │ ├── FB_TestFileControl.TcPOU │ │ │ ├── FB_TestFinishedNamed.TcPOU │ │ │ ├── FB_TestFinishedNamedDoesNotExist.TcPOU │ │ │ ├── FB_TestNumberOfAssertionsCalculation.TcPOU │ │ │ ├── FB_TestStreamBuffer.TcPOU │ │ │ ├── FB_TestXmlControl.TcPOU │ │ │ ├── FB_WriteProtectedFunctions.TcPOU │ │ │ └── PRG_TEST.TcPOU │ │ └── Version │ │ │ └── Global_Version.TcGVL │ │ └── _Config │ │ └── PLC │ │ └── TcUnitVerifier.xti └── img │ └── TcUnit-Verifier_Concept_1280.png ├── TcUnit.libcat.xml ├── TcUnit.sln ├── TcUnit ├── TcUnit.tsproj ├── TcUnit │ ├── DUTs │ │ ├── E_AssertionType.TcDUT │ │ ├── E_XmlError.TcDUT │ │ ├── ST_AdsLogStringMessage.TcDUT │ │ ├── ST_AssertArrayResult.TcDUT │ │ ├── ST_AssertArrayResultInstances.TcDUT │ │ ├── ST_AssertResult.TcDUT │ │ ├── ST_AssertResultInstances.TcDUT │ │ ├── ST_TestCaseResult.TcDUT │ │ ├── ST_TestSuiteResult.TcDUT │ │ ├── ST_TestSuiteResults.TcDUT │ │ └── U_ExpectedOrActual.TcDUT │ ├── GVLs │ │ ├── GVL_Param_TcUnit.TcGVL │ │ └── GVL_TcUnit.TcGVL │ ├── ITFs │ │ ├── I_AssertMessageFormatter.TcIO │ │ ├── I_TestResultLogger.TcIO │ │ └── I_TestResults.TcIO │ ├── POUs │ │ ├── FB_AdjustAssertFailureMessageToMax253CharLength.TcPOU │ │ ├── FB_AdsAssertMessageFormatter.TcPOU │ │ ├── FB_AdsLogStringMessageFifoQueue.TcPOU │ │ ├── FB_AdsTestResultLogger.TcPOU │ │ ├── FB_AssertArrayResultStatic.TcPOU │ │ ├── FB_AssertResultStatic.TcPOU │ │ ├── FB_FileControl.TcPOU │ │ ├── FB_StreamBuffer.TcPOU │ │ ├── FB_TcUnitRunner.TcPOU │ │ ├── FB_Test.TcPOU │ │ ├── FB_TestResults.TcPOU │ │ ├── FB_TestSuite.TcPOU │ │ ├── FB_XmlControl.TcPOU │ │ ├── FB_xUnitXmlPublisher.TcPOU │ │ └── Functions │ │ │ ├── F_AnyToUnionValue.TcPOU │ │ │ ├── F_AnyTypeClassToString.TcPOU │ │ │ ├── F_AssertionTypeToString.TcPOU │ │ │ ├── F_GetCpuCounterAs64bit.TcPOU │ │ │ ├── F_GetTestSuiteNameFromTestInstancePath.TcPOU │ │ │ ├── F_IsAnyEqualToUnionValue.TcPOU │ │ │ ├── F_RemoveInstancePathAndProjectNameFromTestInstancePath.TcPOU │ │ │ ├── IS_TEST_FINISHED.TcPOU │ │ │ ├── RUN.TcPOU │ │ │ ├── RUN_IN_SEQUENCE.TcPOU │ │ │ ├── TCUNIT_ADSLOGSTR.TcPOU │ │ │ ├── TEST.TcPOU │ │ │ ├── TEST_FINISHED.TcPOU │ │ │ ├── TEST_FINISHED_NAMED.TcPOU │ │ │ ├── TEST_ORDERED.TcPOU │ │ │ └── WRITE_PROTECTED_ │ │ │ ├── WRITE_PROTECTED_BOOL.TcPOU │ │ │ ├── WRITE_PROTECTED_BYTE.TcPOU │ │ │ ├── WRITE_PROTECTED_DATE.TcPOU │ │ │ ├── WRITE_PROTECTED_DATE_AND_TIME.TcPOU │ │ │ ├── WRITE_PROTECTED_DINT.TcPOU │ │ │ ├── WRITE_PROTECTED_DWORD.TcPOU │ │ │ ├── WRITE_PROTECTED_INT.TcPOU │ │ │ ├── WRITE_PROTECTED_LINT.TcPOU │ │ │ ├── WRITE_PROTECTED_LREAL.TcPOU │ │ │ ├── WRITE_PROTECTED_LWORD.TcPOU │ │ │ ├── WRITE_PROTECTED_REAL.TcPOU │ │ │ ├── WRITE_PROTECTED_SINT.TcPOU │ │ │ ├── WRITE_PROTECTED_STRING.TcPOU │ │ │ ├── WRITE_PROTECTED_TIME.TcPOU │ │ │ ├── WRITE_PROTECTED_TIME_OF_DAY.TcPOU │ │ │ ├── WRITE_PROTECTED_UDINT.TcPOU │ │ │ ├── WRITE_PROTECTED_UINT.TcPOU │ │ │ ├── WRITE_PROTECTED_ULINT.TcPOU │ │ │ ├── WRITE_PROTECTED_USINT.TcPOU │ │ │ ├── WRITE_PROTECTED_WORD.TcPOU │ │ │ └── WRITE_PROTECTED_WSTRING.TcPOU │ ├── TcUnit.plcproj │ └── Version │ │ └── Global_Version.TcGVL └── _Config │ └── PLC │ └── TcUnit.xti ├── docs ├── .nojekyll ├── CNAME ├── LICENSE_USAGE ├── README.md ├── _sidebar.md ├── api.md ├── docsify │ ├── custom.css │ ├── language-st.css │ ├── language-st.js │ └── plugins │ │ └── docsify-plugin-flexible-alerts.js ├── download.md ├── faq.md ├── img │ ├── AssertAnyWithParameter.png │ ├── DiagnosticMessageDiagnosticCodeParser-1.png │ ├── TcUnit-Logo-Header-v2_2.jpg │ ├── TcUnit13Successful_2.png │ ├── TcUnit16Of17Failed_2.png │ ├── TcUnitAllSuccessful2.png │ ├── TcUnitElevenSuccessful_2.png │ ├── TcUnitFiveSuccessful_2.png │ ├── TcUnitManyFails.png │ ├── TcUnitNineSuccessful_2.png │ ├── add-library-reference.png │ ├── diagnosis-code-bytes.png │ ├── diagnosticmessageflagsparser.png │ ├── diagnosticmessageparser.png │ ├── diagnosticmessagetextidentityparser.png │ ├── diagnosticmessagetimestampparser.png │ ├── flagslayout.png │ ├── function-block-layout.png │ ├── functionblocklayout.png │ ├── hide-reference.png │ ├── iolink-tests-tcunit.png │ ├── library-repository-window.png │ ├── tc3_banner.jpg │ ├── tc3_banner2.jpg │ ├── tc3_banner4.jpg │ ├── tc3_banner5.jpg │ ├── tc3_banner6.jpg │ ├── tc3_banner7.jpg │ ├── tc3_banner97.jpg │ ├── tc3_banner98.jpg │ ├── tc3_banner99.jpg │ ├── tcunit-adslogstr-correct-order.png │ ├── tcunit-adslogstr-not-correct-order.png │ ├── tcunit-arch-example.png │ ├── tcunit-arch.png │ ├── tcunit-block-explanations.png │ ├── tcunit-example-click-description.png │ ├── tcunit-example-successful.png │ ├── tcunit-general.png │ ├── tcunit-increaseMaxNumberOfTestsForEachTestSuite.png │ ├── tcunit-logo.png │ ├── tcunit-results.png │ ├── tcunit-saveaslibraryandinstall-window.png │ ├── tcunit-timebetweentestsuitesexecution.png │ ├── tcunit_logextendedtestresults.png │ ├── tcunit_run_option1.png │ ├── tcunit_run_option2.png │ ├── tcunit_run_option3.png │ ├── tcunit_run_option4.png │ ├── test-fbs.png │ ├── test-results.png │ └── unit-test-structure-1.png ├── index.html ├── introduction-user-guide.md ├── programming-example-final-words.md ├── programming-example-implementation-part-one.md ├── programming-example-implementation-part-two.md ├── programming-example-introduction.md ├── programming-example-part-two.md ├── programming-example-test-cases-part-one.md ├── programming-example-test-cases-part-two.md ├── programming-example-the-function-blocks.md ├── programming-example.md └── unit-testing-concepts.md └── img └── tcunit-logo.png /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | What steps are necessary to reproduce the behavior? 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Screenshots** 20 | If applicable, add screenshots to help explain your problem. 21 | 22 | **Software versions** 23 | Which version of the applicable software did you use? (TcUnit library, TwinCAT XAE version, Visual Studio version etc) 24 | 25 | **Run environment** 26 | Under what environment did you run the software? PLC? Virtual machine? 27 | 28 | **Additional context** 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to TcUnit 2 | 3 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 4 | 5 | - Reporting a bug 6 | - Discussing the current state of the code 7 | - Submitting a fix 8 | - Proposing new features 9 | - Becoming a maintainer 10 | 11 | ## We Develop with Github 12 | 13 | We use github to host code, to track issues and feature requests, as well as accept pull requests. 14 | 15 | ## We Use [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow), So All Code Changes Happen Through Pull Requests 16 | 17 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://docs.github.com/en/get-started/quickstart/github-flow)). We actively welcome your pull requests: 18 | 19 | 1. Fork the repo and create your branch from `master`. 20 | 2. If you've added new functionality, it's necessary to add tests. For this there is a separate test project called [TcUnit-Verifier](https://github.com/tcunit/TcUnit/tree/master/TcUnit-Verifier). In that project there are several test suites defined to test the different functionality of TcUnit. Please read the [README.MD](https://github.com/tcunit/TcUnit/blob/master/TcUnit-Verifier/README.md) in that project for further instructions. **No new functionality will be accepted without any proper tests**. 21 | 3. Ensure the test suite passes. 22 | 4. If changes that affect the documentation have been made (such as API-changes), make sure to update the [documentation](https://github.com/tcunit/TcUnit/tree/master/docs). 23 | 5. Issue that pull request! 24 | 25 | ## Any contributions you make will be under the MIT Software License 26 | 27 | In short, when you submit code changes, your submissions are understood to be under the same [MIT License](http://choosealicense.com/licenses/mit/) that covers the project. Feel free to contact the maintainers if that's a concern. 28 | 29 | ## Report bugs using Github's [issues](https://github.com/tcunit/TcUnit/issues) 30 | 31 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/tcunit/TcUnit/issues/new); it's that easy! 32 | 33 | ## Write bug reports with detail, background, and sample code 34 | 35 | **Great Bug Reports** tend to have: 36 | 37 | - A quick summary and/or background 38 | - Steps to reproduce 39 | - Be specific! 40 | - Give sample code if you can. 41 | - What you expected would happen 42 | - What actually happens 43 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 44 | 45 | ## Use a Consistent Coding Style 46 | 47 | - Make sure to edit the project with the same version of Visual Studio as the master branch. All software (TcUnit and TcUnit-Verifier) has been developed using Visual Studio 2019. Note that the TwinCAT XAE Shell (provided with TwinCAT XAE installer) can't open the TcUnit-Verifier_DotNet (as it's a .NET/C# project). Instead it's recommended to use [VS2019 community edition](https://visualstudio.microsoft.com/vs/older-downloads/) which can be used both for TwinCAT and .NET/C# projects 48 | - Make sure to use TwinCAT XAE version 3.1.4024.44 or later 49 | - The prefixes of naming of function blocks/variables/etc such as the [Beckhoff TwinCAT 3 and PLCopen identifier/name conventions](https://sagatowski.com/posts/plc_naming_conventions/) are ignored as a modern integrated development environment (as Visual Studio) gives all the hints/information of data types etc 50 | - Make sure to set your TwinCAT development environment to use Separate LineIDs. This is available in the TwinCAT XAE under **Tools→Options→TwinCAT→PLC Environment→Write options→Separate LineIDs** (set this to TRUE, more information is available [here](https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_userinterface/18014403202147467.html&id=)) 51 | 52 | ## License 53 | 54 | By contributing, you agree that your contributions will be licensed under the MIT License. 55 | 56 | ## References 57 | 58 | This document was adapted from briandk's excellent [contribution guidelines template](https://gist.github.com/briandk/3d2e8b3ec8daf5a27a62). 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Jakob Sagatowski and contributors 4 | For a complete list of contributors, see https://github.com/tcunit/TcUnit/graphs/contributors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![TcUnit logo](https://github.com/tcunit/TcUnit/blob/master/img/tcunit-logo.png) 2 | [![GitHub license](https://img.shields.io/github/license/Naereen/StrapDown.js.svg)](https://github.com/tcunit/TcUnit/blob/master/LICENSE) 3 | [![Open Source? Yes!](https://badgen.net/badge/Open%20Source%20%3F/Yes%21/blue?icon=github)](https://github.com/TcUnit/TcUnit) 4 | 5 | # TcUnit - TwinCAT unit testing framework 6 | 7 | Welcome to the documentation TcUnit - an xUnit testing framework for [Beckhoff's TwinCAT 3](https://www.beckhoff.com/twincat3/). 8 | 9 | **Main documentation site is available on:** 10 | **[www.tcunit.org](https://www.tcunit.org)** 11 | 12 | **What is test driven development and unit testing?** 13 | Familiarize yourself with [the basic concepts and specifics for TcUnit](https://tcunit.org/#/unit-testing-concepts). 14 | 15 | **Want to know how to get started?** 16 | Read the [user guide](https://tcunit.org/#/introduction-user-guide). 17 | 18 | **Want to see a more advanced programming example?** 19 | Read the [programming example](https://tcunit.org/#/programming-example-introduction). 20 | 21 | **Want to download a precompiled version of the library?** 22 | Go to the [releases](https://github.com/tcunit/TcUnit/releases). 23 | 24 | **Want to contribute to the project?** 25 | That's fantastic! There are two ways to do this. 26 | 27 | 1. Contribute with your time and knowledge by fixing issues or adding new features. Please read the [CONTRIBUTING](CONTRIBUTING.md) first. 28 | 2. By [becoming a sponsor](https://github.com/sponsors/tcunit). 29 | 30 | **Have any questions? Found a bug or want to discuss an idea?** 31 | Check the [F.A.Q](https://tcunit.org/#/faq). 32 | Check the [open](https://github.com/tcunit/TcUnit/issues) and [closed](https://github.com/tcunit/TcUnit/issues?q=is%3Aissue+is%3Aclosed) issues. 33 | If your issue does not already exist, create a [new](https://github.com/tcunit/TcUnit/issues/new/choose). 34 | For general ideas/discussions, use the [discussions](https://github.com/tcunit/TcUnit/discussions). 35 | 36 | ## Star History 37 | 38 | [![Star History Chart](https://api.star-history.com/svg?repos=tcunit/tcunit&type=Timeline)](https://star-history.com/#tcunit/tcunit&Timeline) 39 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.33529.622 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TcUnit-Verifier", "TcUnit-Verifier\TcUnit-Verifier.csproj", "{13F197A8-6EF6-4799-A221-37B97BA42100}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {13F197A8-6EF6-4799-A221-37B97BA42100}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {13F197A8-6EF6-4799-A221-37B97BA42100}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {13F197A8-6EF6-4799-A221-37B97BA42100}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {13F197A8-6EF6-4799-A221-37B97BA42100}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/AutomationInterface.cs: -------------------------------------------------------------------------------- 1 | using TCatSysManagerLib; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | /// 6 | /// This class provides the functionality to access the TwinCAT automation interface, which 7 | /// is a complement to the VS DTE and that gives access to certain TwinCAT specific functions 8 | /// integrated into Visual Studio 9 | /// 10 | class AutomationInterface 11 | { 12 | private ITcSysManager10 sysManager = null; 13 | private ITcConfigManager configManager = null; 14 | private ITcSmTreeItem plcTreeItem = null; 15 | private ITcSmTreeItem routesTreeItem = null; 16 | 17 | public AutomationInterface(EnvDTE.Project project) 18 | { 19 | sysManager = (ITcSysManager10)project.Object; 20 | configManager = (ITcConfigManager)sysManager.ConfigurationManager; 21 | plcTreeItem = sysManager.LookupTreeItem(Constants.PLC_CONFIGURATION_SHORTCUT); 22 | routesTreeItem = sysManager.LookupTreeItem(Constants.RT_CONFIG_ROUTE_SETTINGS_SHORTCUT); 23 | } 24 | 25 | public AutomationInterface(VisualStudioInstance vsInst) : this(vsInst.GetProject()) 26 | { } 27 | 28 | public ITcSysManager10 ITcSysManager 29 | { 30 | get 31 | { 32 | return this.sysManager; 33 | } 34 | } 35 | 36 | public ITcSmTreeItem PlcTreeItem 37 | { 38 | get 39 | { 40 | return this.plcTreeItem; 41 | } 42 | } 43 | 44 | public ITcSmTreeItem RoutesTreeItem 45 | { 46 | get 47 | { 48 | return this.routesTreeItem; 49 | } 50 | } 51 | 52 | public string ActiveTargetPlatform 53 | { 54 | set 55 | { 56 | this.configManager.ActiveTargetPlatform = value; 57 | } 58 | get 59 | { 60 | return this.configManager.ActiveTargetPlatform; 61 | } 62 | } 63 | 64 | public string TargetNetId 65 | { 66 | set 67 | { 68 | this.sysManager.SetTargetNetId(value); 69 | } 70 | get 71 | { 72 | return sysManager.GetTargetNetId(); 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/Constants.cs: -------------------------------------------------------------------------------- 1 | namespace TcUnit.Verifier 2 | { 3 | static class Constants 4 | { 5 | public const int RETURN_SUCCESSFULL = 0; 6 | public const int RETURN_ERROR = 1; 7 | 8 | public const string RT_CONFIG_ROUTE_SETTINGS_SHORTCUT = "TIRR"; // Shortcut for "Real-Time Configuration^Route Settings" 9 | public const string PLC_CONFIGURATION_SHORTCUT = "TIPC"; // Shortcut for "PLC Configuration" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/ErrorList.cs: -------------------------------------------------------------------------------- 1 | using EnvDTE80; 2 | using System; 3 | using System.Globalization; 4 | using System.Collections; 5 | using System.Collections.Generic; 6 | using System.Text.RegularExpressions; 7 | 8 | namespace TcUnit.Verifier 9 | { 10 | class ErrorList : IEnumerable, IEnumerable 11 | { 12 | protected List _errors = new List(); 13 | 14 | public struct Error 15 | { 16 | public string Description; 17 | public vsBuildErrorLevel ErrorLevel; 18 | public DateTime Timestamp; 19 | 20 | public Error(ErrorItem item) 21 | { 22 | Description = item.Description.ToUpper(); 23 | ErrorLevel = item.ErrorLevel; 24 | Timestamp = ParseTimestampFromDescription(item.Description); 25 | } 26 | } 27 | 28 | static public DateTime ParseTimestampFromDescription(string description) 29 | { 30 | string pattern = @"^(.*?)\s+(\d+\s)ms\s+\|"; 31 | Match match = Regex.Match(description, pattern, RegexOptions.IgnoreCase); 32 | var parsedDate = DateTime.Parse(match.Groups[1].Value, CultureInfo.CurrentCulture).AddMilliseconds(double.Parse(match.Groups[2].Value)); 33 | return parsedDate; 34 | } 35 | 36 | public IEnumerable AddNew(ErrorItems errorItems) 37 | { 38 | int N1 = _errors.Count + 1; 39 | int N2 = errorItems.Count; 40 | for (int i = N1; i <= N2; i++) 41 | { 42 | var item = errorItems.Item(i); 43 | _errors.Add(new Error(item)); 44 | } 45 | return _errors.GetRange(N1 - 1, N2 + 1 - N1); 46 | } 47 | 48 | IEnumerator IEnumerable.GetEnumerator() { 49 | return _errors.GetEnumerator(); 50 | } 51 | 52 | IEnumerator IEnumerable.GetEnumerator() 53 | { 54 | return _errors.GetEnumerator(); 55 | } 56 | } 57 | } -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_AdjustAssertFailureMessageToMax253CharLengthTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_AdjustAssertFailureMessageToMax253CharLengthTest : TestFunctionBlockAssert 6 | { 7 | public FB_AdjustAssertFailureMessageToMax253CharLengthTest(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | TestInstancePath253CharsExpectTooLongTestInstancePath(); 11 | TestInstancePath221CharsExpectShortenedTestInstancePath(); 12 | TestInstancePath255CharsExpectTooLongTestInstancePath(); 13 | } 14 | 15 | private void TestInstancePath253CharsExpectTooLongTestInstancePath() 16 | { 17 | AssertDoesNotContainMessage("TestInstancePath253CharsExpectTooLongTestInstancePath", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 18 | } 19 | 20 | private void TestInstancePath221CharsExpectShortenedTestInstancePath() 21 | { 22 | AssertDoesNotContainMessage("TestInstancePath221CharsExpectShortenedTestInstancePath", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 23 | } 24 | 25 | private void TestInstancePath255CharsExpectTooLongTestInstancePath() 26 | { 27 | AssertDoesNotContainMessage("TestInstancePath255CharsExpectTooLongTestInstancePath", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_AssertCountExceedsMaxNumber.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace TcUnit.Verifier 5 | { 6 | class FB_AssertCountExceedsMaxNumber : TestFunctionBlockAssert 7 | { 8 | public FB_AssertCountExceedsMaxNumber(IEnumerable errors, string testFunctionBlockInstance = null) : base(errors, testFunctionBlockInstance) 9 | { 10 | string testName; 11 | string testMessage; 12 | 13 | testName = "Assert_SameEntryInOneCycle"; 14 | testMessage = "AssertResults.TotalAsserts invalid"; 15 | AssertDoesNotContainMessage(testName, testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 16 | 17 | testName = "Assert_SameArrayEntryInOneCycle"; 18 | testMessage = "AssertArrayResults.TotalArrayAsserts invalid"; 19 | AssertDoesNotContainMessage(testName, testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 20 | } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_AssertEveryFailedTestTwiceArrayVersion.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_AssertEveryFailedTestTwiceArrayVersion : TestFunctionBlockAssert 6 | { 7 | public FB_AssertEveryFailedTestTwiceArrayVersion(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | TwiceAssertCall_Arrays(); 11 | } 12 | 13 | private void TwiceAssertCall_Arrays() 14 | { 15 | string testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[2] = FALSE", "ARRAY[2] = TRUE", "Not equal BOOL"); 16 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 17 | 18 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[1] = 0xAA", "ARRAY[1] = 0xCD", "Not equal BYTE"); 19 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 20 | 21 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[4] = -2147483645", "ARRAY[4] = -2147483641", "Not equal DINT"); 22 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 23 | 24 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[-1] = 0xEFAA2346", "ARRAY[-1] = 0xEF012345", "Not equal DWORD"); 25 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 26 | 27 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[-7] = -23", "ARRAY[2] = 24", "Not equal INT"); 28 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 29 | 30 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[0] = -9223372036853775808", "ARRAY[5] = -9223372036854775808", "Not equal LINT"); 31 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 32 | 33 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[-1] = 7.88", "ARRAY[0] = 7.99", "Not equal LREAL"); 34 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 35 | 36 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[1,0] = 6.96", "ARRAY[1,0] = 6.68", "Not equal LREAL2D"); 37 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 38 | 39 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[1,0,1] = 6.0", "ARRAY[1,0,1] = 6.4", "Not equal LREAL3D"); 40 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 41 | 42 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[1] = 0xEDCBA09876543210", "ARRAY[1] = 0x01234567890ABCDE", "Not equal LWORD"); 43 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 44 | 45 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[2] = 2.44001", "ARRAY[2] = 2.44003", "Not equal REAL"); 46 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 47 | 48 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[1,1] = 7.7701", "ARRAY[1,1] = 7.7703", "Not equal REAL2D"); 49 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 50 | 51 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[0,1,1] = 4.01", "ARRAY[0,1,1] = 4.021", "Not equal REAL3D"); 52 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 53 | 54 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[0] = -128", "ARRAY[0] = 127", "Not equal SINT"); 55 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 56 | 57 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[-4] = 5", "ARRAY[1] = 4", "Not equal UDINT"); 58 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 59 | 60 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[3] = 99", "ARRAY[3] = 12", "Not equal UINT"); 61 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 62 | 63 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[1] = 9400000000000", "ARRAY[1] = 18446744073709551615", "Not equal ULINT"); 64 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 65 | 66 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[4] = 4", "ARRAY[4] = 5", "Not equal USINT"); 67 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 68 | 69 | testMessage = CreateFailedTestMessage("TwiceAssertCall_Arrays", "ARRAY[7] = 0x1133", "ARRAY[7] = 0x1122", "Not equal WORD"); 70 | AssertMessageCount(testMessage, 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 71 | } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_AssertTrueFalse.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_AssertTrueFalse : TestFunctionBlockAssert 6 | { 7 | public FB_AssertTrueFalse(IEnumerable errors, string testFunctionBlockInstance = null) : base(errors, testFunctionBlockInstance) 8 | { 9 | AssertThatINTsAreEqual(); 10 | AssertThatINTsAreNotEqual(); 11 | AssertThatWORDsAreEqual(); 12 | AssertThatWORDsAreNotEqual(); 13 | } 14 | 15 | private void AssertThatINTsAreEqual() 16 | { 17 | string testMessage = CreateFailedTestMessage("AssertThatINTsAreEqual", "FALSE", "TRUE", "INTs are equal"); 18 | AssertContainsMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 19 | } 20 | 21 | private void AssertThatINTsAreNotEqual() 22 | { 23 | string testMessage = CreateFailedTestMessage("AssertThatINTsAreNotEqual", "FALSE", "TRUE", "INTs are equal"); 24 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 25 | } 26 | 27 | private void AssertThatWORDsAreEqual() 28 | { 29 | string testMessage = CreateFailedTestMessage("AssertThatWORDsAreEqual", "TRUE", "FALSE", "WORDs are not equal"); 30 | AssertContainsMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 31 | } 32 | 33 | private void AssertThatWORDsAreNotEqual() 34 | { 35 | string testMessage = CreateFailedTestMessage("AssertThatWORDsAreNotEqual", "TRUE", "FALSE", "WORDs are equal"); 36 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_CheckIfSpecificTestIsFinished.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_CheckIfSpecificTestIsFinished : TestFunctionBlockAssert 6 | { 7 | public FB_CheckIfSpecificTestIsFinished(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | TestThatInstantlyFinishes(); 11 | } 12 | 13 | private void TestThatInstantlyFinishes() 14 | { 15 | string testMessage1 = CreateFailedTestMessage("CheckBeforeAndAfterFinishing", "FALSE", "TRUE", "Values differ before finishing"); 16 | AssertDoesNotContainMessage(testMessage1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 17 | 18 | string testMessage2 = CreateFailedTestMessage("CheckBeforeAndAfterFinishing", "TRUE", "FALSE", "Values differ after finishing"); 19 | AssertDoesNotContainMessage(testMessage2, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_CreateDisabledTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_CreateDisabledTest : TestFunctionBlockAssert 6 | { 7 | public FB_CreateDisabledTest(IEnumerable errors, string testFunctionBlockInstance = null) : base(errors, testFunctionBlockInstance) 8 | { 9 | TestEnabled(); 10 | TestDisabled(); 11 | } 12 | 13 | private void TestEnabled() 14 | { 15 | string testMessage = CreateFailedTestMessage("TestEnabled", "TRUE", "FALSE", "A does not equal B"); 16 | AssertContainsMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 17 | } 18 | 19 | private void TestDisabled() 20 | { 21 | string testMessage = CreateFailedTestMessage("DISABLED_ThisShouldNotExecute", "FALSE", "TRUE", "A does not equal B"); 22 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 23 | } 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_CreateFourTestsWithSameName.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_CreateFourTestsWithSameName : TestFunctionBlockAssert 6 | { 7 | public FB_CreateFourTestsWithSameName(IEnumerable errors, string testFunctionBlockInstance = null) : base(errors, testFunctionBlockInstance) 8 | { 9 | TestOne(); 10 | } 11 | 12 | private void TestOne() 13 | { 14 | AssertMessageCount("Test with name 'TestOne' already exists in test suite 'PRG_TEST.CreateFourTestsWithSameName'", 1, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_EmptyAssertionMessage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_EmptyAssertionMessage : TestFunctionBlockAssert 6 | { 7 | public FB_EmptyAssertionMessage(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | IntegerEmptyAssertionMessage(); 11 | } 12 | 13 | private void IntegerEmptyAssertionMessage() 14 | { 15 | string testMessage = CreateFailedTestMessageNoAssertionMessage("IntegerEmptyAssertionMessage", "-32000", "15423"); 16 | AssertContainsMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_MultipleAssertWithSameParametersInDifferentCyclesAndInSameTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_MultipleAssertWithSameParametersInDifferentCyclesAndInSameTest : TestFunctionBlockAssert 6 | { 7 | public FB_MultipleAssertWithSameParametersInDifferentCyclesAndInSameTest(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Assert_SeveralTimes(); 11 | } 12 | 13 | private void Assert_SeveralTimes() 14 | { 15 | string testMessage = CreateFailedTestMessage("Assert_SeveralTimes", "0x12345678", "0x90ABCDEF", "Values differ"); 16 | AssertMessageCount(testMessage, 9, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_MultipleAssertWithSameParametersInDifferentCyclesButWithDifferentTests.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_MultipleAssertWithSameParametersInDifferentCyclesButWithDifferentTests : TestFunctionBlockAssert 6 | { 7 | public FB_MultipleAssertWithSameParametersInDifferentCyclesButWithDifferentTests(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Assert_SeveralTimes(); 11 | Assert_SeveralTimesAgain(); 12 | Assert_SeveralTimesAgainAgain(); 13 | } 14 | 15 | private void Assert_SeveralTimes() 16 | { 17 | string testMessage = CreateFailedTestMessage("Assert_SeveralTimes", "0x12345678", "0x90ABCDEF", "Values differ"); 18 | AssertMessageCount(testMessage, 3, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 19 | } 20 | 21 | private void Assert_SeveralTimesAgain() 22 | { 23 | string testMessage = CreateFailedTestMessage("Assert_SeveralTimesAgain", "0x12345678", "0x90ABCDEF", "Values differ"); 24 | AssertMessageCount(testMessage, 3, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 25 | } 26 | 27 | private void Assert_SeveralTimesAgainAgain() 28 | { 29 | string testMessage = CreateFailedTestMessage("Assert_SeveralTimesAgainAgain", "0x12345678", "0x90ABCDEF", "Values differ"); 30 | AssertMessageCount(testMessage, 3, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_MultipleAssertWithSameParametersInSameCycleWithSameTest.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_MultipleAssertWithSameParametersInSameCycleWithSameTest : TestFunctionBlockAssert 6 | { 7 | public FB_MultipleAssertWithSameParametersInSameCycleWithSameTest(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Assert_SeveralTimes(); 11 | } 12 | 13 | private void Assert_SeveralTimes() 14 | { 15 | string testMessage = CreateFailedTestMessage("Assert_SeveralTimes", "0x12345678", "0x90ABCDEF", "Values differ"); 16 | AssertMessageCount(testMessage, 3, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_SkipAssertionsWhenFinished.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_SkipAssertionsWhenFinished : TestFunctionBlockAssert 6 | { 7 | public FB_SkipAssertionsWhenFinished(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Test_LongTest(); 11 | Test_ShortTest(); 12 | Test_AssertImmediatelyAfterFinished(); 13 | } 14 | 15 | private void Test_LongTest() 16 | { 17 | AssertDoesNotContainMessage("Test_LongTest", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 18 | } 19 | 20 | private void Test_ShortTest() 21 | { 22 | AssertDoesNotContainMessage("Test_ShortTest", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 23 | } 24 | 25 | private void Test_AssertImmediatelyAfterFinished() 26 | { 27 | AssertDoesNotContainMessage("Test_AssertImmediatelyAfterFinished", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_TestDurationMeasurement.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_TestDurationMeasurement : TestFunctionBlockAssert 6 | { 7 | public FB_TestDurationMeasurement(IEnumerable errors, string testFunctionBlockInstance = null) : base(errors, testFunctionBlockInstance) 8 | { 9 | TestNamedTest20msDurationMeasuredCorrectly(); 10 | TestOrderedTest30msDurationMeasuredCorrectly(); 11 | TestRegularTestDurationMeasuredCorrectly(); 12 | } 13 | 14 | private void TestNamedTest20msDurationMeasuredCorrectly() 15 | { 16 | AssertContainsResultSet("TestNamedTest20msDurationMeasuredCorrectly", "PRG_TEST.TestDurationMeasurement", "FAIL", 1, 0.02, 0.1); 17 | } 18 | 19 | private void TestOrderedTest30msDurationMeasuredCorrectly() 20 | { 21 | AssertContainsResultSet("TestOrderedTest30msDurationMeasuredCorrectly", "PRG_TEST.TestDurationMeasurement", "FAIL", 1, 0.03, 0.1); 22 | } 23 | 24 | private void TestRegularTestDurationMeasuredCorrectly() 25 | { 26 | AssertContainsResultSet("TestRegularTestDurationMeasuredCorrectly", "PRG_TEST.TestDurationMeasurement", "FAIL", 2, 0.0003, 0.001); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_TestFileControl.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_TestFileControl : TestFunctionBlockAssert 6 | { 7 | public FB_TestFileControl(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Test_Read(); 11 | Test_Open(); 12 | Test_Write(); 13 | Test_Close(); 14 | Test_Delete(); 15 | } 16 | 17 | private void Test_Read() 18 | { 19 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Read"; 20 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 21 | } 22 | 23 | private void Test_Open() 24 | { 25 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Open"; 26 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 27 | } 28 | 29 | private void Test_Write() 30 | { 31 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Write"; 32 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 33 | } 34 | 35 | private void Test_Close() 36 | { 37 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Close"; 38 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 39 | } 40 | 41 | private void Test_Delete() 42 | { 43 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Delete"; 44 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_TestFinishedNamed.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_TestFinishedNamed : TestFunctionBlockAssert 6 | { 7 | public FB_TestFinishedNamed(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Test_FinishedNamed(); 11 | } 12 | 13 | private void Test_FinishedNamed() 14 | { 15 | 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_TestNumberOfAssertionsCalculation.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_TestNumberOfAssertionsCalculation : TestFunctionBlockAssert 6 | { 7 | public FB_TestNumberOfAssertionsCalculation(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | TestMixed33SuccessulAnd9FailedAssertions(); 11 | TestWith43SuccessfulAssertions(); 12 | TestWith44FailedAssertions(); 13 | TestWith45SuccessfulArrayAssertions(); 14 | TestWith46FailedArrayAssertions(); 15 | } 16 | 17 | private void TestMixed33SuccessulAnd9FailedAssertions() 18 | { 19 | AssertContainsMessage("| Test status=FAIL, number of asserts=42, duration=%f", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelLow); 20 | } 21 | 22 | private void TestWith43SuccessfulAssertions() 23 | { 24 | AssertContainsMessage("| Test status=PASS, number of asserts=43, duration=%f", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelLow); 25 | } 26 | 27 | private void TestWith44FailedAssertions() 28 | { 29 | AssertContainsMessage("| Test status=FAIL, number of asserts=44, duration=%f", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelLow); 30 | } 31 | 32 | private void TestWith45SuccessfulArrayAssertions() 33 | { 34 | AssertContainsMessage("| Test status=PASS, number of asserts=45, duration=%f", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelLow); 35 | } 36 | 37 | private void TestWith46FailedArrayAssertions() 38 | { 39 | AssertContainsMessage("| Test status=FAIL, number of asserts=46, duration=%f", EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelLow); 40 | } 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_TestStreamBuffer.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_TestStreamBuffer : TestFunctionBlockAssert 6 | { 7 | public FB_TestStreamBuffer(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Test_BufferSizeDiffers(); 11 | Test_Length(); 12 | Test_Append(); 13 | Test_Clear(); 14 | Test_Find(); 15 | Test_Copy(); 16 | Test_CutOff(); 17 | Test_BufferOverflow(); 18 | } 19 | 20 | private void Test_BufferSizeDiffers() 21 | { 22 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_BufferSizeDiffers"; 23 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 24 | } 25 | 26 | private void Test_Append() 27 | { 28 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Append"; 29 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 30 | } 31 | 32 | private void Test_Clear() 33 | { 34 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Clear"; 35 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 36 | } 37 | 38 | private void Test_CutOff() 39 | { 40 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_CutOff"; 41 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 42 | } 43 | 44 | private void Test_Copy() 45 | { 46 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Copy"; 47 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 48 | } 49 | 50 | private void Test_Find() 51 | { 52 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Find"; 53 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 54 | } 55 | 56 | private void Test_Length() 57 | { 58 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_Length"; 59 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 60 | } 61 | 62 | private void Test_BufferOverflow() 63 | { 64 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_BufferOverflow"; 65 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/FB_TestXmlControl.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace TcUnit.Verifier 4 | { 5 | class FB_TestXmlControl : TestFunctionBlockAssert 6 | { 7 | public FB_TestXmlControl(IEnumerable errors, string testFunctionBlockInstance = null) 8 | : base(errors, testFunctionBlockInstance) 9 | { 10 | Test_NewTag(); 11 | Test_NewTagNested(); 12 | Test_NewParameter(); 13 | Test_NewComment(); 14 | Test_CloseOpenTag(); 15 | Test_CloseTag(); 16 | Test_NewTagData(); 17 | } 18 | 19 | private void Test_NewTag() 20 | { 21 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_NewTag"; 22 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 23 | } 24 | 25 | private void Test_NewTagNested() 26 | { 27 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_NewTagNested"; 28 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 29 | } 30 | 31 | private void Test_NewParameter() 32 | { 33 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_NewParameter"; 34 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 35 | } 36 | 37 | private void Test_NewComment() 38 | { 39 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_NewComment"; 40 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 41 | } 42 | 43 | private void Test_CloseOpenTag() 44 | { 45 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_CloseOpenTag"; 46 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 47 | } 48 | 49 | private void Test_CloseTag() 50 | { 51 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_CloseTag"; 52 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 53 | } 54 | 55 | private void Test_NewTagData() 56 | { 57 | string testMessage = "PRG_TEST." + _testFunctionBlockInstance + "@Test_NewTagData"; 58 | AssertDoesNotContainMessage(testMessage, EnvDTE80.vsBuildErrorLevel.vsBuildErrorLevelHigh); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/MessageFilter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.InteropServices; 3 | 4 | namespace TcUnit.Verifier 5 | { 6 | public class MessageFilter : IOleMessageFilter { 7 | // Class containing the IOleMessageFilter 8 | // thread error-handling functions. 9 | 10 | // Start the filter. 11 | public static void Register() { 12 | IOleMessageFilter newFilter = new MessageFilter(); 13 | IOleMessageFilter oldFilter = null; 14 | CoRegisterMessageFilter(newFilter, out oldFilter); 15 | } 16 | 17 | // Done with the filter, close it. 18 | public static void Revoke() { 19 | IOleMessageFilter oldFilter = null; 20 | CoRegisterMessageFilter(null, out oldFilter); 21 | } 22 | 23 | // IOleMessageFilter functions. 24 | // Handle incoming thread requests. 25 | int IOleMessageFilter.HandleInComingCall(int dwCallType, 26 | System.IntPtr hTaskCaller, int dwTickCount, System.IntPtr 27 | lpInterfaceInfo) { 28 | //Return the flag SERVERCALL_ISHANDLED. 29 | return 0; 30 | } 31 | 32 | // Thread call was rejected, so try again. 33 | int IOleMessageFilter.RetryRejectedCall(System.IntPtr 34 | hTaskCallee, int dwTickCount, int dwRejectType) { 35 | if (dwRejectType == 2) 36 | // flag = SERVERCALL_RETRYLATER. 37 | { 38 | // Retry the thread call immediately if return >=0 & 39 | // <100. 40 | return 99; 41 | } 42 | // Too busy; cancel call. 43 | return -1; 44 | } 45 | 46 | int IOleMessageFilter.MessagePending(System.IntPtr hTaskCallee, 47 | int dwTickCount, int dwPendingType) { 48 | //Return the flag PENDINGMSG_WAITDEFPROCESS. 49 | return 2; 50 | } 51 | 52 | // Implement the IOleMessageFilter interface. 53 | [DllImport("Ole32.dll")] 54 | private static extern int 55 | CoRegisterMessageFilter(IOleMessageFilter newFilter, out 56 | IOleMessageFilter oldFilter); 57 | } 58 | 59 | [System.Runtime.InteropServices.ComImport(), Guid("00000016-0000-0000-C000-000000000046"), 60 | InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] 61 | interface IOleMessageFilter { 62 | [PreserveSig] 63 | int HandleInComingCall( 64 | int dwCallType, 65 | IntPtr hTaskCaller, 66 | int dwTickCount, 67 | IntPtr lpInterfaceInfo); 68 | 69 | [PreserveSig] 70 | int RetryRejectedCall( 71 | IntPtr hTaskCallee, 72 | int dwTickCount, 73 | int dwRejectType); 74 | 75 | [PreserveSig] 76 | int MessagePending( 77 | IntPtr hTaskCallee, 78 | int dwTickCount, 79 | int dwPendingType); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TcUnit-Verifier")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TcUnit-Verifier")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5d0c625d-7826-4282-948d-d8ccaff7aeb9")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/log4net.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_DotNet/TcUnit-Verifier/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.33529.622 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{B1E792BE-AA5F-4E3C-8C82-674BF9C0715B}") = "TcUnit-Verifier_TwinCAT", "TcUnit-Verifier_TwinCAT\TcUnit-Verifier_TwinCAT.tsproj", "{3B151CEE-1DB6-4543-9B44-7AFACBDFB147}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|TwinCAT CE7 (ARMV7) = Debug|TwinCAT CE7 (ARMV7) 11 | Debug|TwinCAT OS (ARMT2) = Debug|TwinCAT OS (ARMT2) 12 | Debug|TwinCAT RT (x64) = Debug|TwinCAT RT (x64) 13 | Debug|TwinCAT RT (x86) = Debug|TwinCAT RT (x86) 14 | Release|TwinCAT CE7 (ARMV7) = Release|TwinCAT CE7 (ARMV7) 15 | Release|TwinCAT OS (ARMT2) = Release|TwinCAT OS (ARMT2) 16 | Release|TwinCAT RT (x64) = Release|TwinCAT RT (x64) 17 | Release|TwinCAT RT (x86) = Release|TwinCAT RT (x86) 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT CE7 (ARMV7).ActiveCfg = Debug|TwinCAT CE7 (ARMV7) 21 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT CE7 (ARMV7).Build.0 = Debug|TwinCAT CE7 (ARMV7) 22 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT OS (ARMT2).ActiveCfg = Debug|TwinCAT OS (ARMT2) 23 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT OS (ARMT2).Build.0 = Debug|TwinCAT OS (ARMT2) 24 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) 25 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) 26 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) 27 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86) 28 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT CE7 (ARMV7).ActiveCfg = Release|TwinCAT CE7 (ARMV7) 29 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT CE7 (ARMV7).Build.0 = Release|TwinCAT CE7 (ARMV7) 30 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT OS (ARMT2).ActiveCfg = Release|TwinCAT OS (ARMT2) 31 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT OS (ARMT2).Build.0 = Release|TwinCAT OS (ARMT2) 32 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) 33 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) 34 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) 35 | {3B151CEE-1DB6-4543-9B44-7AFACBDFB147}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86) 36 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT CE7 (ARMV7).ActiveCfg = Debug|TwinCAT CE7 (ARMV7) 37 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT CE7 (ARMV7).Build.0 = Debug|TwinCAT CE7 (ARMV7) 38 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT OS (ARMT2).ActiveCfg = Debug|TwinCAT OS (ARMT2) 39 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT OS (ARMT2).Build.0 = Debug|TwinCAT OS (ARMT2) 40 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) 41 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) 42 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) 43 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86) 44 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT CE7 (ARMV7).ActiveCfg = Release|TwinCAT CE7 (ARMV7) 45 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT CE7 (ARMV7).Build.0 = Release|TwinCAT CE7 (ARMV7) 46 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT OS (ARMT2).ActiveCfg = Release|TwinCAT OS (ARMT2) 47 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT OS (ARMT2).Build.0 = Release|TwinCAT OS (ARMT2) 48 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) 49 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) 50 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) 51 | {59ED27DD-D865-40E3-AB9D-3C7E47AFCF7D}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86) 52 | EndGlobalSection 53 | GlobalSection(SolutionProperties) = preSolution 54 | HideSolutionNode = FALSE 55 | EndGlobalSection 56 | EndGlobal 57 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT.tsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | PlcTask 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/POUs/FB_ProtectedVariables.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/PlcTask.TcTTO: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 10000 6 | 20 7 | 8 | PRG_TEST 9 | 10 | {f400f08e-5a68-4fff-a0e9-3ac94652314f} 11 | {752336a3-6d86-46fa-8b17-894c36572213} 12 | {dca1d304-b487-4a01-9d84-a735617e46c0} 13 | {016c9125-cf2c-41be-8f4d-1febd06537f0} 14 | {96455e75-799e-4c2e-8960-cac2a7c45342} 15 | 16 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_AssertCountExceedsMaxNumber.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 15 | 16 | 18 | 19 | 20 | 31 | 32 | 46 | 47 | 48 | 49 | 59 | 60 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_AssertTrueFalse.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 10 | 11 | 15 | 16 | 17 | 23 | 24 | b), 27 | Message := 'INTs are equal'); 28 | 29 | TEST_FINISHED();]]> 30 | 31 | 32 | 33 | 39 | 40 | 46 | 47 | 48 | 49 | 55 | 56 | 62 | 63 | 64 | 65 | 71 | 72 | b), 75 | Message := 'WORDs are equal'); 76 | 77 | TEST_FINISHED();]]> 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_CheckIfSpecificTestIsFinished.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_CreateDisabledTest.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 12 | 13 | 14 | 20 | 21 | 28 | 29 | 30 | 31 | 37 | 38 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_CreateFourTestsWithSameName.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 14 | 15 | 16 | 22 | 23 | 30 | 31 | 32 | 33 | 39 | 40 | 47 | 48 | 49 | 50 | 56 | 57 | 64 | 65 | 66 | 67 | 73 | 74 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_EmptyAssertionMessage.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_EmptyTestSuite.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_ExtendedTestInformation.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 8 | 9 | 14 | 15 | 16 | 21 | 22 | 29 | 30 | 31 | 32 | 37 | 38 | 45 | 46 | 47 | 48 | 55 | 56 | 67 | 68 | 69 | 70 | 75 | 76 | 83 | 84 | 85 | 86 | 91 | 92 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_MultipleAssertWithSameParametersInDifferentCyclesAndInSameTest.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 18 | 19 | 20 | 21 | 22 | 51 | 52 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_MultipleAssertWithSameParametersInDifferentCyclesButWithDifferentTests.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 18 | 19 | 32 | 33 | 34 | 45 | 46 | 63 | 64 | 65 | 66 | 77 | 78 | 95 | 96 | 97 | 98 | 109 | 110 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_MultipleAssertWithSameParametersInSameCycleWithSameTest.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 13 | 14 | 15 | 16 | 17 | 28 | 29 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_SkipAssertionsWhenFinished.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 18 | 19 | 22 | 23 | 24 | 29 | 30 | 34 | 35 | 36 | 37 | 41 | 42 | 48 | 49 | 50 | 51 | 55 | 56 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_TestDurationMeasurement.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 8 | 9 | 12 | 13 | 14 | 19 | 20 | 30 | 31 | 32 | 33 | 40 | 41 | 57 | 58 | 59 | 60 | 64 | 65 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_TestFinishedNamed.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/FB_TestFinishedNamedDoesNotExist.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 11 | 12 | 13 | 14 | 15 | 20 | 21 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Test/PRG_TEST.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 38 | 39 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/TcUnitVerifier/Version/Global_Version.TcGVL: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /TcUnit-Verifier/TcUnit-Verifier_TwinCAT/TcUnit-Verifier_TwinCAT/_Config/PLC/TcUnitVerifier.xti: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TcUnitVerifier Instance 6 | {08500001-0000-0000-F000-000000000064} 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /TcUnit-Verifier/img/TcUnit-Verifier_Concept_1280.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/TcUnit-Verifier/img/TcUnit-Verifier_Concept_1280.png -------------------------------------------------------------------------------- /TcUnit.libcat.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 78515825-a6f1-476c-a7b7-6595f51e6013 5 | 1.0.0.0 6 | TcUnit 7 | 8 | -------------------------------------------------------------------------------- /TcUnit.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # TcXaeShell Solution File, Format Version 11.00 4 | VisualStudioVersion = 15.0.28307.1300 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{B1E792BE-AA5F-4E3C-8C82-674BF9C0715B}") = "TcUnit", "TcUnit\TcUnit.tsproj", "{6FA21008-E02E-4675-BDB9-D161F2357484}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|TwinCAT CE7 (ARMV7) = Debug|TwinCAT CE7 (ARMV7) 11 | Debug|TwinCAT OS (ARMT2) = Debug|TwinCAT OS (ARMT2) 12 | Debug|TwinCAT RT (x64) = Debug|TwinCAT RT (x64) 13 | Debug|TwinCAT RT (x86) = Debug|TwinCAT RT (x86) 14 | Release|TwinCAT CE7 (ARMV7) = Release|TwinCAT CE7 (ARMV7) 15 | Release|TwinCAT OS (ARMT2) = Release|TwinCAT OS (ARMT2) 16 | Release|TwinCAT RT (x64) = Release|TwinCAT RT (x64) 17 | Release|TwinCAT RT (x86) = Release|TwinCAT RT (x86) 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT CE7 (ARMV7).ActiveCfg = Debug|TwinCAT CE7 (ARMV7) 21 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT CE7 (ARMV7).Build.0 = Debug|TwinCAT CE7 (ARMV7) 22 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT OS (ARMT2).ActiveCfg = Debug|TwinCAT OS (ARMT2) 23 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT OS (ARMT2).Build.0 = Debug|TwinCAT OS (ARMT2) 24 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) 25 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) 26 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) 27 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86) 28 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT CE7 (ARMV7).ActiveCfg = Release|TwinCAT CE7 (ARMV7) 29 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT CE7 (ARMV7).Build.0 = Release|TwinCAT CE7 (ARMV7) 30 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT OS (ARMT2).ActiveCfg = Release|TwinCAT OS (ARMT2) 31 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT OS (ARMT2).Build.0 = Release|TwinCAT OS (ARMT2) 32 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) 33 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) 34 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) 35 | {6FA21008-E02E-4675-BDB9-D161F2357484}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86) 36 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT CE7 (ARMV7).ActiveCfg = Debug|TwinCAT CE7 (ARMV7) 37 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT CE7 (ARMV7).Build.0 = Debug|TwinCAT CE7 (ARMV7) 38 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT OS (ARMT2).ActiveCfg = Debug|TwinCAT OS (ARMT2) 39 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT OS (ARMT2).Build.0 = Debug|TwinCAT OS (ARMT2) 40 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT RT (x64).ActiveCfg = Debug|TwinCAT RT (x64) 41 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT RT (x64).Build.0 = Debug|TwinCAT RT (x64) 42 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT RT (x86).ActiveCfg = Debug|TwinCAT RT (x86) 43 | {BC994085-3B01-480D-AB11-95935FC773EE}.Debug|TwinCAT RT (x86).Build.0 = Debug|TwinCAT RT (x86) 44 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT CE7 (ARMV7).ActiveCfg = Release|TwinCAT CE7 (ARMV7) 45 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT CE7 (ARMV7).Build.0 = Release|TwinCAT CE7 (ARMV7) 46 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT OS (ARMT2).ActiveCfg = Release|TwinCAT OS (ARMT2) 47 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT OS (ARMT2).Build.0 = Release|TwinCAT OS (ARMT2) 48 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT RT (x64).ActiveCfg = Release|TwinCAT RT (x64) 49 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT RT (x64).Build.0 = Release|TwinCAT RT (x64) 50 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT RT (x86).ActiveCfg = Release|TwinCAT RT (x86) 51 | {BC994085-3B01-480D-AB11-95935FC773EE}.Release|TwinCAT RT (x86).Build.0 = Release|TwinCAT RT (x86) 52 | EndGlobalSection 53 | GlobalSection(SolutionProperties) = preSolution 54 | HideSolutionNode = FALSE 55 | EndGlobalSection 56 | GlobalSection(ExtensibilityGlobals) = postSolution 57 | SolutionGuid = {7D6FE6E2-6485-4068-A809-46511C3C7709} 58 | EndGlobalSection 59 | EndGlobal 60 | -------------------------------------------------------------------------------- /TcUnit/TcUnit.tsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/E_AssertionType.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 57 | 58 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/E_XmlError.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_AdsLogStringMessage.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_AssertArrayResult.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_AssertArrayResultInstances.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_AssertResult.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_AssertResultInstances.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_TestCaseResult.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 16 | 17 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_TestSuiteResult.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14 | 15 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/ST_TestSuiteResults.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/DUTs/U_ExpectedOrActual.TcDUT: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 31 | 32 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/GVLs/GVL_Param_TcUnit.TcGVL: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 'C:\TwinCAT\3.1\Boot\' (Windows), '/usr/local/etc/TwinCAT/3.1/Boot/' (TC/BSD), '\Hard Disk\TwinCAT\3.1\Boot\' (Windows CE) 35 | - %TC_INSTALLPATH% -> 'C:\TwinCAT\3.1\' (Windows), '/usr/local/etc/TwinCAT/3.1/' (TC/BSD), '\Hard Disk\TwinCAT\3.1\' (Windows CE) *) 36 | xUnitFilePath : T_MaxString := '%TC_BOOTPRJPATH%tcunit_xunit_testresults.xml'; 37 | 38 | (* This is the maximum number of ADS-messages that can be stored for reporting at the same time. 39 | Having a size of 2000 means that it's possible to report up to ~400 test cases in one single 40 | PLC cycle. Each entry consumes around 500 bytes, so with an example of a ring buffer size of 41 | 2000 it means that TcUnit will consume around 1 MB of router memory. *) 42 | AdsLogMessageFifoRingBufferSize : UINT := 2000; 43 | 44 | (* Time delay between a test suite is finished and the execution of the next test suite starts 45 | if using RUN_IN_SEQUENCE() *) 46 | TimeBetweenTestSuitesExecution : TIME := T#0MS; 47 | END_VAR]]> 48 | 49 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/GVLs/GVL_TcUnit.TcGVL: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 53 | 54 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/ITFs/I_AssertMessageFormatter.TcIO: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 7 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/ITFs/I_TestResultLogger.TcIO: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/ITFs/I_TestResults.TcIO: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 6 | 7 | 9 | 10 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/FB_AdjustAssertFailureMessageToMax253CharLength.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 25 | 26 | MESSAGE_FORMATTED_STRING_MAX_NUMBER_OF_CHARACTERS THEN 34 | TestInstancePathTemporary := LEFT(STR := TestInstancePath, 35 | SIZE := (MESSAGE_FORMATTED_STRING_MAX_NUMBER_OF_CHARACTERS - LEN(STR := TEST_NAME_TOO_LONG))); 36 | TestInstancePathProcessed := CONCAT(STR1 := TestInstancePathTemporary, 37 | STR2 := TEST_NAME_TOO_LONG); 38 | TestMessageProcessed := ''; 39 | // If test message is too long (so we cant fit the text "...TestMsg too long" to the end of it) , shorten it (so that we can fit the text) 40 | ELSIF (MESSAGE_FORMATTED_STRING_MAX_NUMBER_OF_CHARACTERS - LEN(STR := TEST_MESSAGE_TOO_LONG)) >= LEN(STR := TestInstancePath) THEN 41 | TestInstancePathProcessed := TestInstancePath; 42 | TestMessageProcessed := LEFT(STR := TestMessage, 43 | SIZE := (MESSAGE_FORMATTED_STRING_MAX_NUMBER_OF_CHARACTERS - LEN(STR := TEST_MESSAGE_TOO_LONG) - LEN(STR := TestInstancePathProcessed))); 44 | TestMessageProcessed := CONCAT(STR1 := TestMessageProcessed, 45 | STR2 := TEST_MESSAGE_TOO_LONG); 46 | // If test instance path is too long (length is between 233 and 253 characters long), shorten it and add the text '...TestName too long'. Leave no characters for the message 47 | ELSE 48 | TestInstancePathTemporary := LEFT(STR := TestInstancePath, 49 | SIZE := (MESSAGE_FORMATTED_STRING_MAX_NUMBER_OF_CHARACTERS - LEN(STR := TEST_NAME_TOO_LONG))); 50 | TestInstancePathProcessed := CONCAT(STR1 := TestInstancePathTemporary, 51 | STR2 := TEST_NAME_TOO_LONG); 52 | TestMessageProcessed := ''; 53 | END_IF]]> 54 | 55 | 56 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/FB_AdsAssertMessageFormatter.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 29 | 30 | 0 THEN 45 | TestInstancePathFinal := CONCAT(STR1 := TestInstancePathFinal, 46 | STR2 := ', MSG: %s'); 47 | END_IF 48 | 49 | AdjustAssertFailureMessageToMax253CharLength(TestInstancePath := TestInstancePathFinal, 50 | TestMessage := Message, 51 | TestInstancePathProcessed => TestInstancePathProcessed, 52 | TestMessageProcessed => MessageProcessed); 53 | 54 | GVL_TcUnit.AdsMessageQueue.WriteLog(MsgCtrlMask := ADSLOG_MSGTYPE_ERROR, 55 | MsgFmtStr := TestInstancePathProcessed, 56 | StrArg := MessageProcessed);]]> 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/FB_AdsLogStringMessageFifoQueue.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 23 | 24 | 0 THEN 26 | // Timer has elapsed, print message 27 | IF TimerBetweenMessages.Q THEN 28 | GetAndRemoveLogFromQueue(AdsLogStringMessage => MessageToBeSent, 29 | Error => ErrorGet); 30 | IF NOT ErrorGet THEN 31 | ReturnValue := ADSLOGSTR(msgCtrlMask := MessageToBeSent.MsgCtrlMask, 32 | msgFmtStr := MessageToBeSent.MsgFmtStr, 33 | strArg := MessageToBeSent.StrArg); 34 | END_IF 35 | TimerBetweenMessages(IN := FALSE); // Reset timer 36 | TimerBetweenMessages.IN := TRUE; 37 | END_IF 38 | END_IF]]> 39 | 40 | 41 | 47 | 48 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 75 | 76 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/FB_FileControl.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | SysFile.SysTypes.RTS_INVALID_HANDLE THEN 18 | Close := SysFile.SysFileClose(hFile := FileHandle); 19 | ELSE 20 | Close := SysDir.CmpErrors.Errors.ERR_INVALID_HANDLE; 21 | END_IF]]> 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 42 | 43 | 46 | 47 | 48 | 49 | 58 | 59 | SysFile.SysTypes.RTS_INVALID_HANDLE THEN 60 | FileSize := SysFile.SysFileRead(hFile := FileHandle, 61 | pbyBuffer := BufferPointer, 62 | ulSize := Size, 63 | pResult := ADR(Read)); 64 | ELSE 65 | Read := SysDir.CmpErrors.Errors.ERR_INVALID_HANDLE; 66 | END_IF]]> 67 | 68 | 69 | 70 | 76 | 77 | SysFile.SysTypes.RTS_INVALID_HANDLE THEN 78 | SysFile.SysFileWrite(hFile := FileHandle, 79 | pbyBuffer := BufferPointer, 80 | ulSize := Size, 81 | pResult := ADR(Write)); 82 | ELSE 83 | Write := SysDir.CmpErrors.Errors.ERR_INVALID_HANDLE; 84 | END_IF]]> 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/F_AnyTypeClassToString.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/F_AssertionTypeToString.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 10 | 11 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/F_GetCpuCounterAs64bit.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 12 | 13 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/F_GetTestSuiteNameFromTestInstancePath.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 12 | 13 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/F_RemoveInstancePathAndProjectNameFromTestInstancePath.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 12 | 13 | 0 THEN 20 | TestInstancePath := DELETE(STR := TestInstancePath, 21 | LEN := CharacterPositionOfProjectName-1 + LEN(ProjectNameWithDot), 22 | POS := 1); 23 | END_IF 24 | 25 | // Check if the project name happens to be the same as namespace, and in that case, remove that as well 26 | CharacterPositionOfProjectName := FIND(STR1 := TestInstancePath, 27 | STR2 := ProjectNameWithDot); 28 | 29 | IF CharacterPositionOfProjectName > 0 THEN 30 | TestInstancePath := DELETE(STR := TestInstancePath, 31 | LEN := CharacterPositionOfProjectName - 1 + LEN(STR := ProjectNameWithDot), 32 | POS := 1); 33 | END_IF 34 | 35 | F_RemoveInstancePathAndProjectNameFromTestInstancePath := TestInstancePath;]]> 36 | 37 | 38 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/IS_TEST_FINISHED.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 13 | 14 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/RUN.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/RUN_IN_SEQUENCE.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/TCUNIT_ADSLOGSTR.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14 | 15 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/TEST.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 13 | 14 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/TEST_FINISHED.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 11 | 12 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/TEST_FINISHED_NAMED.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 22 | 23 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/TEST_ORDERED.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 33 | 34 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_BOOL.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_BYTE.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_DATE.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_DATE_AND_TIME.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_DINT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_DWORD.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_INT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_LINT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_LREAL.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_LWORD.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_REAL.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_SINT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_STRING.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_TIME.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_TIME_OF_DAY.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_UDINT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_UINT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_ULINT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_USINT.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_WORD.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/POUs/Functions/WRITE_PROTECTED_/WRITE_PROTECTED_WSTRING.TcPOU: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /TcUnit/TcUnit/Version/Global_Version.TcGVL: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 13 | 14 | -------------------------------------------------------------------------------- /TcUnit/_Config/PLC/TcUnit.xti: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TcUnit Instance 6 | {08500001-0000-0000-F000-000000000064} 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /docs/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/.nojekyll -------------------------------------------------------------------------------- /docs/CNAME: -------------------------------------------------------------------------------- 1 | tcunit.org -------------------------------------------------------------------------------- /docs/LICENSE_USAGE: -------------------------------------------------------------------------------- 1 | Material from the following open source projects have been used for the documentation of this repository: 2 | 3 | -- 4 | https://github.com/mobject-Dev-Team/mobject.org/ 5 | -- 6 | MIT License 7 | 8 | Copyright (c) 2023 benhar-dev 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

4 | 5 | > TcUnit is an [xUnit](https://en.wikipedia.org/wiki/XUnit) type of framework specifically done for [Beckhoff's TwinCAT 3](https://www.beckhoff.com/en-en/products/automation/twincat/) development environment. 6 | It consists of a single library that is easily integrated into any existing TwinCAT 3 project. 7 | 8 | **Want to get started?** 9 | Start by reading the [unit testing concepts](unit-testing-concepts.md) and then the [introduction user guide](introduction-user-guide.md). 10 | 11 | ![TcUnit introduction](img/tcunit-general.png) 12 | 13 | **Easy to use** 14 | The framework is easy to use. 15 | All that is needed is to download & install the library, and provide a reference to the TcUnit-library in your project, and you can start to write your test code. 16 | For a complete set of instructions, start with [the concepts](unit-testing-concepts.md), continue with [the user guide](introduction-user-guide.md) and finish with [the programming example](programming-example-introduction.md). 17 | 18 | **One library** 19 | All functionality is provided by one single library. 20 | Add the library to your project and you are ready to go! You can either [download a precompiled](https://github.com/tcunit/TcUnit/releases) (ready to install) version of the library or [download the source code](https://www.github.com/tcunit/tcunit). 21 | 22 | **MIT-license** 23 | The library and all the source code is licensed according to the MIT-license, which is one of the most relaxed software license terms. 24 | The software is completely free and you can use the software in any way you want, be it private or for commercial use as long as you include the MIT license terms with your software. 25 | 26 | **Automated test runs** 27 | With the additional TcUnit-Runner software, it's possible to do integrate all your TcUnit tests into a CI/CD software toolchain. 28 | With the aid of automation software such as [Jenkins](https://www.jenkins.io/) or [Azure DevOps](https://azure.microsoft.com/en-us/services/devops/), you can have your tests being run automatically and collect test statistics every time something is changed in your software version control (such as Git or Subversion). 29 | -------------------------------------------------------------------------------- /docs/_sidebar.md: -------------------------------------------------------------------------------- 1 | - Home 2 | - [Welcome](/) 3 | - [Download](download.md) 4 | - [Code & Issues](https://www.github.com/TcUnit/TcUnit) 5 | - [FAQ](faq.md) 6 | 7 | - Manuals 8 | - [Unit testing concepts](unit-testing-concepts.md) 9 | - [Introduction user guide](introduction-user-guide.md) 10 | - [API](api.md) 11 | -- [Programming example](programming-example.md) 12 | - [Introduction](programming-example-introduction.md) 13 | - [The function blocks](programming-example-the-function-blocks.md) 14 | - [Test cases - Part 1](programming-example-test-cases-part-one) 15 | - [Test cases - Part 2](programming-example-test-cases-part-two) 16 | - [Implementation - Part 1](programming-example-implementation-part-one.md) 17 | - [Implementation - Part 2](programming-example-implementation-part-two.md) 18 | - [Final words](programming-example-final-words.md) -------------------------------------------------------------------------------- /docs/docsify/custom.css: -------------------------------------------------------------------------------- 1 | 2 | .markdown-section output:after, .markdown-section pre:after { 3 | content: ''; 4 | } 5 | 6 | pre { 7 | margin : 0px; 8 | } 9 | 10 | .markdown-section pre { 11 | padding: 0; 12 | } 13 | 14 | .markdown-section pre>code { 15 | padding: 2.2em 2.2em; 16 | } 17 | 18 | .markdown-section code { 19 | background-color: #f8f8f8; 20 | padding : 0.5em; 21 | } 22 | 23 | .markdown-section pre { 24 | margin: 0em 0; 25 | position: relative; 26 | background-color:white; 27 | } 28 | 29 | .markdown-section blockquote { 30 | border-left: 4px solid #929292; 31 | background-color: #f4f4f4; 32 | } 33 | 34 | .sidebar ul li.active>a { 35 | color: #29292b;; 36 | } 37 | 38 | .github-corner svg { 39 | fill: #383d41; 40 | } 41 | 42 | a { 43 | text-decoration: none; 44 | } -------------------------------------------------------------------------------- /docs/docsify/language-st.css: -------------------------------------------------------------------------------- 1 | .token.class-name { 2 | color:blue; 3 | } 4 | 5 | .token.keyword { 6 | color:blue; 7 | } 8 | 9 | .token.variable { 10 | color:blue; 11 | } 12 | 13 | .token.comment { 14 | color:green; 15 | } 16 | 17 | 18 | [data-lang="declaration"] { 19 | margin-bottom: 0px !important; 20 | } 21 | 22 | [data-lang="body"] { 23 | border-top: 1px solid lightgrey; 24 | margin-top: 0px !important; 25 | } 26 | 27 | 28 | [data-lang="body"] + [data-lang="declaration"] { 29 | border-top: 1px solid lightgrey; 30 | margin-top: 0px !important; 31 | } 32 | -------------------------------------------------------------------------------- /docs/docsify/language-st.js: -------------------------------------------------------------------------------- 1 | Prism.languages.example = { 2 | 'comment': [ 3 | { 4 | pattern: /(^|[^\\])(?:\/\*[\s\S]*?(?:\*\/|$)|\(\*[\s\S]*?(?:\*\)|$)|\{[\s\S]*?(?:\}|$))/, 5 | lookbehind: true, 6 | }, 7 | { 8 | pattern: /(^|[^\\:])\/\/.*/, 9 | lookbehind: true, 10 | greedy: true, 11 | }, 12 | ], 13 | 'string': { 14 | pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 15 | greedy: true, 16 | }, 17 | 'class-name': /\b(?:END_)?(?:PROGRAM|CONFIGURATION|INTERFACE|FUNCTION_BLOCK|FUNCTION|ACTION|TRANSITION|TYPE|STRUCT|(?:INITIAL_)?STEP|NAMESPACE|LIBRARY|CHANNEL|FOLDER|RESOURCE|VAR_(?:GLOBAL|INPUT|PUTPUT|IN_OUT|ACCESS|TEMP|EXTERNAL|CONFIG)|VAR|METHOD|PROPERTY)\b/i, 18 | 'keyword': /\b(?:(?:END_)?(?:IF|WHILE|REPEAT|CASE|FOR)|ELSE|FROM|THEN|ELSIF|DO|TO|BY|PRIVATE|PUBLIC|PROTECTED|CONSTANT|RETURN|EXIT|CONTINUE|GOTO|JMP|AT|RETAIN|NON_RETAIN|TASK|WITH|UNTIL|USING|EXTENDS|IMPLEMENTS|GET|SET|__TRY|__CATCH|__FINALLY|__ENDTRY)\b/, 19 | 'variable': /\b(?:AT|BOOL|BYTE|(?:D|L)?WORD|U?(?:S|D|L)?INT|L?REAL|TIME(?:_OF_DAY)?|TOD|DT|DATE(?:_AND_TIME)?|STRING|ARRAY|ANY|POINTER)\b/, 20 | 'symbol': /%[IQM][XBWDL][\d.]*|%[IQ][\d.]*/, 21 | 'number': /\b(?:16#[\da-f]+|2#[01_]+|0x[\da-f]+)\b|\b(?:T|D|DT|TOD)#[\d_shmd:]*|\b[A-Z]*\#[\d.,_]*|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, 22 | 'boolean': /\b(?:TRUE|FALSE|NULL)\b/, 23 | 'function': /\w+(?=\()/, 24 | 'operator': /(?:S?R?:?=>?|&&?|\*\*?|<=?|>=?|[-:^/+])|\b(?:OR|AND|MOD|NOT|XOR|LE|GE|EQ|NE|GT|LT)\b/, 25 | 'punctuation': /[();]/, 26 | 'type': { 27 | 'pattern': /#/, 28 | 'alias': 'selector', 29 | }, 30 | }; 31 | 32 | Prism.languages.declaration = { 33 | 'comment': [ 34 | { 35 | pattern: /(^|[^\\])(?:\/\*[\s\S]*?(?:\*\/|$)|\(\*[\s\S]*?(?:\*\)|$)|\{[\s\S]*?(?:\}|$))/, 36 | lookbehind: true, 37 | }, 38 | { 39 | pattern: /(^|[^\\:])\/\/.*/, 40 | lookbehind: true, 41 | greedy: true, 42 | }, 43 | ], 44 | 'string': { 45 | pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 46 | greedy: true, 47 | }, 48 | 'class-name': /\b(?:END_)?(?:PROGRAM|CONFIGURATION|INTERFACE|FUNCTION_BLOCK|FUNCTION|ACTION|TRANSITION|TYPE|STRUCT|(?:INITIAL_)?STEP|NAMESPACE|LIBRARY|CHANNEL|FOLDER|RESOURCE|VAR_(?:GLOBAL|INPUT|PUTPUT|IN_OUT|ACCESS|TEMP|EXTERNAL|CONFIG)|VAR|METHOD|PROPERTY)\b/i, 49 | 'keyword': /\b(?:(?:END_)?(?:IF|WHILE|REPEAT|CASE|FOR)|ELSE|FROM|THEN|ELSIF|DO|TO|BY|PRIVATE|PUBLIC|PROTECTED|CONSTANT|RETURN|EXIT|CONTINUE|GOTO|JMP|AT|RETAIN|NON_RETAIN|TASK|WITH|UNTIL|USING|EXTENDS|IMPLEMENTS|GET|SET|__TRY|__CATCH|__FINALLY|__ENDTRY)\b/, 50 | 'variable': /\b(?:AT|BOOL|BYTE|(?:D|L)?WORD|U?(?:S|D|L)?INT|L?REAL|TIME(?:_OF_DAY)?|TOD|DT|DATE(?:_AND_TIME)?|STRING|ARRAY|ANY|POINTER)\b/, 51 | 'symbol': /%[IQM][XBWDL][\d.]*|%[IQ][\d.]*/, 52 | 'number': /\b(?:16#[\da-f]+|2#[01_]+|0x[\da-f]+)\b|\b(?:T|D|DT|TOD)#[\d_shmd:]*|\b[A-Z]*\#[\d.,_]*|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, 53 | 'boolean': /\b(?:TRUE|FALSE|NULL)\b/, 54 | 'function': /\w+(?=\()/, 55 | 'operator': /(?:S?R?:?=>?|&&?|\*\*?|<=?|>=?|[-:^/+])|\b(?:OR|AND|MOD|NOT|XOR|LE|GE|EQ|NE|GT|LT)\b/, 56 | 'punctuation': /[();]/, 57 | 'type': { 58 | 'pattern': /#/, 59 | 'alias': 'selector', 60 | }, 61 | }; 62 | 63 | Prism.languages.body = { 64 | 'comment': [ 65 | { 66 | pattern: /(^|[^\\])(?:\/\*[\s\S]*?(?:\*\/|$)|\(\*[\s\S]*?(?:\*\)|$)|\{[\s\S]*?(?:\}|$))/, 67 | lookbehind: true, 68 | }, 69 | { 70 | pattern: /(^|[^\\:])\/\/.*/, 71 | lookbehind: true, 72 | greedy: true, 73 | }, 74 | ], 75 | 'string': { 76 | pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, 77 | greedy: true, 78 | }, 79 | 'class-name': /\b(?:END_)?(?:PROGRAM|CONFIGURATION|INTERFACE|FUNCTION_BLOCK|FUNCTION|ACTION|TRANSITION|TYPE|STRUCT|(?:INITIAL_)?STEP|NAMESPACE|LIBRARY|CHANNEL|FOLDER|RESOURCE|VAR_(?:GLOBAL|INPUT|PUTPUT|IN_OUT|ACCESS|TEMP|EXTERNAL|CONFIG)|VAR|METHOD|PROPERTY)\b/i, 80 | 'keyword': /\b(?:(?:END_)?(?:IF|WHILE|REPEAT|CASE|FOR)|ELSE|FROM|THEN|ELSIF|DO|TO|BY|PRIVATE|PUBLIC|PROTECTED|CONSTANT|RETURN|EXIT|CONTINUE|GOTO|JMP|AT|RETAIN|NON_RETAIN|TASK|WITH|UNTIL|USING|EXTENDS|IMPLEMENTS|GET|SET|__TRY|__CATCH|__FINALLY|__ENDTRY)\b/, 81 | 'variable': /\b(?:AT|BOOL|BYTE|(?:D|L)?WORD|U?(?:S|D|L)?INT|L?REAL|TIME(?:_OF_DAY)?|TOD|DT|DATE(?:_AND_TIME)?|STRING|ARRAY|ANY|POINTER)\b/, 82 | 'symbol': /%[IQM][XBWDL][\d.]*|%[IQ][\d.]*/, 83 | 'number': /\b(?:16#[\da-f]+|2#[01_]+|0x[\da-f]+)\b|\b(?:T|D|DT|TOD)#[\d_shmd:]*|\b[A-Z]*\#[\d.,_]*|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, 84 | 'boolean': /\b(?:TRUE|FALSE|NULL)\b/, 85 | 'function': /\w+(?=\()/, 86 | 'operator': /(?:S?R?:?=>?|&&?|\*\*?|<=?|>=?|[-:^/+])|\b(?:OR|AND|MOD|NOT|XOR|LE|GE|EQ|NE|GT|LT)\b/, 87 | 'punctuation': /[();]/, 88 | 'type': { 89 | 'pattern': /#/, 90 | 'alias': 'selector', 91 | }, 92 | }; -------------------------------------------------------------------------------- /docs/download.md: -------------------------------------------------------------------------------- 1 | # Download 2 | 3 |

4 | 5 |

6 | 7 | TcUnit can be downloaded as either a [pre-compiled library](https://github.com/tcunit/TcUnit/releases) or [as source code](https://github.com/tcunit/TcUnit). 8 | For a tutorial on how you install TcUnit from either a downloaded library or from source read the [introduction user guide](introduction-user-guide.md). 9 | The libraries are compatible with TwinCAT **3.1.4020.0** or newer. 10 | 11 | **Release history** 12 | All releases can be downloaded from the official [TcUnit release site](https://github.com/tcunit/TcUnit/releases). 13 | -------------------------------------------------------------------------------- /docs/img/AssertAnyWithParameter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/AssertAnyWithParameter.png -------------------------------------------------------------------------------- /docs/img/DiagnosticMessageDiagnosticCodeParser-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/DiagnosticMessageDiagnosticCodeParser-1.png -------------------------------------------------------------------------------- /docs/img/TcUnit-Logo-Header-v2_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnit-Logo-Header-v2_2.jpg -------------------------------------------------------------------------------- /docs/img/TcUnit13Successful_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnit13Successful_2.png -------------------------------------------------------------------------------- /docs/img/TcUnit16Of17Failed_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnit16Of17Failed_2.png -------------------------------------------------------------------------------- /docs/img/TcUnitAllSuccessful2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnitAllSuccessful2.png -------------------------------------------------------------------------------- /docs/img/TcUnitElevenSuccessful_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnitElevenSuccessful_2.png -------------------------------------------------------------------------------- /docs/img/TcUnitFiveSuccessful_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnitFiveSuccessful_2.png -------------------------------------------------------------------------------- /docs/img/TcUnitManyFails.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnitManyFails.png -------------------------------------------------------------------------------- /docs/img/TcUnitNineSuccessful_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/TcUnitNineSuccessful_2.png -------------------------------------------------------------------------------- /docs/img/add-library-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/add-library-reference.png -------------------------------------------------------------------------------- /docs/img/diagnosis-code-bytes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/diagnosis-code-bytes.png -------------------------------------------------------------------------------- /docs/img/diagnosticmessageflagsparser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/diagnosticmessageflagsparser.png -------------------------------------------------------------------------------- /docs/img/diagnosticmessageparser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/diagnosticmessageparser.png -------------------------------------------------------------------------------- /docs/img/diagnosticmessagetextidentityparser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/diagnosticmessagetextidentityparser.png -------------------------------------------------------------------------------- /docs/img/diagnosticmessagetimestampparser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/diagnosticmessagetimestampparser.png -------------------------------------------------------------------------------- /docs/img/flagslayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/flagslayout.png -------------------------------------------------------------------------------- /docs/img/function-block-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/function-block-layout.png -------------------------------------------------------------------------------- /docs/img/functionblocklayout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/functionblocklayout.png -------------------------------------------------------------------------------- /docs/img/hide-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/hide-reference.png -------------------------------------------------------------------------------- /docs/img/iolink-tests-tcunit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/iolink-tests-tcunit.png -------------------------------------------------------------------------------- /docs/img/library-repository-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/library-repository-window.png -------------------------------------------------------------------------------- /docs/img/tc3_banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner2.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner4.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner5.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner6.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner7.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner97.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner97.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner98.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner98.jpg -------------------------------------------------------------------------------- /docs/img/tc3_banner99.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tc3_banner99.jpg -------------------------------------------------------------------------------- /docs/img/tcunit-adslogstr-correct-order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-adslogstr-correct-order.png -------------------------------------------------------------------------------- /docs/img/tcunit-adslogstr-not-correct-order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-adslogstr-not-correct-order.png -------------------------------------------------------------------------------- /docs/img/tcunit-arch-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-arch-example.png -------------------------------------------------------------------------------- /docs/img/tcunit-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-arch.png -------------------------------------------------------------------------------- /docs/img/tcunit-block-explanations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-block-explanations.png -------------------------------------------------------------------------------- /docs/img/tcunit-example-click-description.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-example-click-description.png -------------------------------------------------------------------------------- /docs/img/tcunit-example-successful.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-example-successful.png -------------------------------------------------------------------------------- /docs/img/tcunit-general.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-general.png -------------------------------------------------------------------------------- /docs/img/tcunit-increaseMaxNumberOfTestsForEachTestSuite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-increaseMaxNumberOfTestsForEachTestSuite.png -------------------------------------------------------------------------------- /docs/img/tcunit-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-logo.png -------------------------------------------------------------------------------- /docs/img/tcunit-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-results.png -------------------------------------------------------------------------------- /docs/img/tcunit-saveaslibraryandinstall-window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-saveaslibraryandinstall-window.png -------------------------------------------------------------------------------- /docs/img/tcunit-timebetweentestsuitesexecution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit-timebetweentestsuitesexecution.png -------------------------------------------------------------------------------- /docs/img/tcunit_logextendedtestresults.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit_logextendedtestresults.png -------------------------------------------------------------------------------- /docs/img/tcunit_run_option1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit_run_option1.png -------------------------------------------------------------------------------- /docs/img/tcunit_run_option2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit_run_option2.png -------------------------------------------------------------------------------- /docs/img/tcunit_run_option3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit_run_option3.png -------------------------------------------------------------------------------- /docs/img/tcunit_run_option4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/tcunit_run_option4.png -------------------------------------------------------------------------------- /docs/img/test-fbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/test-fbs.png -------------------------------------------------------------------------------- /docs/img/test-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/test-results.png -------------------------------------------------------------------------------- /docs/img/unit-test-structure-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/img/unit-test-structure-1.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | TcUnit - An unit testing framework for Beckhoff's TwinCAT 3 6 | 7 | 8 | 12 | 16 | 17 | 18 | 19 | 20 |
21 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /docs/programming-example-final-words.md: -------------------------------------------------------------------------------- 1 | # Final words 2 | 3 |

4 | 5 |

6 | 7 | There are some final words that should be mentioned in relation to this example. 8 | What's important to note here is that we managed to develop a lot of working software just by reading specifications. 9 | We haven't yet had any need for any hardware, but even so we can still with high confidence say things are going to work. 10 | By making sure that we want to test only very small pieces of functionality at a time, we have designed a highly modularized pieces of software where each function block only does a small thing, but where they together implement an important part of the functionality of IO-Link. 11 | The large amount of test code that we have produced now also acts as excellent documentation for any other developer reading your code. 12 | If it's hard to understand what a specific function block is supposed to do, just take a look at the test code for some excellent documentation. 13 | 14 | The final test of that the software is actually working is of course to run in on real hardware. 15 | In [this blog post](https://sagatowski.com/posts/test_driven_development_in_twincat_part_7/) this is described, running the software on various IO-Link masters supporting the diagnosis history object. 16 | 17 | We are at the end of this programming example, and this is a good opportunity to go through some of the gains that we achieve by writing our software using test driven development together with an unit testing framework. 18 | 19 | **Documentation** 20 | Writing all this test code has resulted in some really good documentation for the software. 21 | Simply by looking at the tests it is easy to understand what the actual software is supposed to do. 22 | The test cases that we wrote dictate what outputs every function block should provide given a set of inputs. 23 | With this information, any developer that looks at the test cases gets a better understanding of what the function block is supposed to do, so the test cases become examples of what the code should do. 24 | 25 | **Fewer bugs** 26 | Because we can write as many test cases as we want for our code, we achieve better test coverage. 27 | We're not only limited on what tests we can do with any hardware, but can throw any test scenario at our code. 28 | We can test all those extreme edge cases having higher code coverage. 29 | Because we have better code coverage, we will have fewer bugs. 30 | 31 | **Regression test-suite** 32 | We can at any point run our tests and see that all tests still succeed. 33 | At some point or another we will need to do changes in the software, for instance if we want add new functionality. 34 | Doing changes in software can make anyone nervous, but because we have our tests we can with significantly higher confidence do any changes. 35 | Simply run the tests again and see that nothing has broken. 36 | 37 | **Acceptance criteria** 38 | When developing a certain set of functionalities, it's necessary to define what that functionality is supposed to provide. 39 | With unit test cases, this is exactly what is done and thus these test cases become the acceptance criteria of the software. 40 | 41 | **Clear defined interfaces** 42 | When defining the tests, you'll automatically define what the function blocks under test should provide, and thus you'll end up with clear defined interfaces for the function blocks. 43 | The unit tests won't just be software for validating the application, but will also be an engine for the design of the software. 44 | 45 | **Modularized code** 46 | Once you've written tests for a time, it gets natural to test small sets of functionalities at a time, and thus your function blocks usually end up quite small. 47 | Adhering to test driven development thus leads to more modularized, extensible, and flexible code. 48 | -------------------------------------------------------------------------------- /docs/programming-example-part-two.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/docs/programming-example-part-two.md -------------------------------------------------------------------------------- /docs/programming-example-the-function-blocks.md: -------------------------------------------------------------------------------- 1 | # The function blocks 2 | 3 |

4 | 5 |

6 | 7 | Let's create the headers for all the function blocks that we will write unit tests for. 8 | What we'll do is to create a function block for parsing each and one of the parameters (a total number of four), and an additional function block that uses all these four separate function blocks to deliver the result in the struct `ST_DIAGNOSTICMESSAGE`. 9 | A rudimentary scheme for this looks like follows: 10 | ![Function block layout](img/function-block-layout.png) 11 | 12 | Note that we at this stage are not implementing the function blocks, we're only stating what functionality they must provide, by declaring their interfaces. 13 | As this example is quite simple, we'll solve that for every function block by making them provide a function block output. 14 | The function blocks and their headers will have the following layout: 15 | 16 | ## Main diagnosis message event parser 17 | 18 | ```declaration 19 | FUNCTION_BLOCK FB_DiagnosticMessageParser 20 | VAR_INPUT 21 | anDiagnosticMessageBuffer : ARRAY[1..28] OF BYTE; 22 | END_VAR 23 | VAR_OUTPUT 24 | stDiagnosticMessage : ST_DIAGNOSTICMESSAGE; 25 | END_VAR 26 | ``` 27 | 28 | This takes the 28 bytes that we receive from the IO-Link master, and outputs the complete diagnostic message according to the layout of our struct `ST_DIAGNOSTICMESSAGE` described earlier. 29 | Note that in this example we'll only make use of the first 16 (mandatory) bytes, and ignore the 12 (optional) bytes. 30 | 31 | ## Diagnostic code parser 32 | 33 | ```declaration 34 | FUNCTION_BLOCK FB_DiagnosticMessageDiagnosticCodeParser 35 | VAR_INPUT 36 | anDiagnosticCodeBuffer : ARRAY[1..4] OF BYTE; 37 | END_VAR 38 | VAR_OUTPUT 39 | stDiagnosticCode : ST_DIAGNOSTICCODE; 40 | END_VAR 41 | ``` 42 | 43 | This function block takes four of the 28 bytes as input and outputs the diagnostic code according to the layout of our struct `ST_DIAGNOSTICCODE` described earlier. 44 | 45 | ## Flags parser 46 | 47 | ```declaration 48 | FUNCTION_BLOCK FB_DiagnosticMessageFlagsParser 49 | VAR_INPUT 50 | anFlagsBuffer : ARRAY[1..2] OF BYTE; 51 | END_VAR 52 | VAR_OUTPUT 53 | stFlags : ST_FLAGS; 54 | END_VAR 55 | ``` 56 | 57 | This function block takes two of the 28 bytes as input and outputs the flags according to the layout of our struct `ST_FLAGS` described earlier. 58 | 59 | ## Text identity parser 60 | 61 | ```declaration 62 | FUNCTION_BLOCK FB_DiagnosticMessageTextIdentityParser 63 | VAR_INPUT 64 | anTextIdentityBuffer : ARRAY[1..2] OF BYTE; 65 | END_VAR 66 | VAR_OUTPUT 67 | nTextIdentity : UINT; 68 | END_VAR 69 | ``` 70 | 71 | This function block takes two of the 28 bytes as input and outputs the text identity as an unsigned integer according to the description earlier. 72 | 73 | ## Timestamp parser 74 | 75 | ```declaration 76 | FUNCTION_BLOCK FB_DiagnosticMessageTimeStampParser 77 | VAR_INPUT 78 | anTimeStampBuffer : ARRAY[1..8] OF BYTE; 79 | bIsLocalTime : BOOL; 80 | END_VAR 81 | VAR_OUTPUT 82 | sTimeStamp : STRING(29); 83 | END_VAR 84 | ``` 85 | 86 | This function block takes eight of the 28 bytes as input and outputs the timestamp as a human-readable string. 87 | Note that we also have a bIsLocalTime input, as we want to have different handling on the parsing of the timestamp depending on whether the timestamp is a local or global time stamp. 88 | This could be handled in many ways, but for the sake of this example we'll handle the timestamp as: 89 | 90 | - If it's global, the timestamp is based on the EtherCAT distributed clock of the system and we'll make use of/parse the eight bytes 91 | - If it's local, we ignore the eight bytes and instead return the current task distributed clock time 92 | 93 | Although this text is about unit testing, it's worth pointing out that we could handle this differently in such a way that if the timestamp is local, we could read-out the local time of the EtherCAT slave/IO-Link master (if available, located in CoE object 0x10F8), and then calculate what the global time stamp is by calculating the age of the message, and subtracting this from the current DC-time. 94 | 95 | And that's it! 96 | Now we have prepared all the data types and function blocks that together form the functionality specification of our parser. 97 | What's nice about this is that we now have formed the acceptance criteria for the expected functionality, which are all the outputs of the function blocks. 98 | If we run our function blocks now with real input, they will of course not return the correct values. 99 | Everything returned will just be with the default values of the different structures. 100 | Our next step will be to write the unit tests that will make our tests fail, and once that is done (and not before!), we'll write the actual body (implementation) code for the function blocks. 101 | -------------------------------------------------------------------------------- /docs/programming-example.md: -------------------------------------------------------------------------------- 1 | # Programming Example 2 | 3 |

4 | 5 |

6 | 7 | 8 | ## Overview: 9 | 10 | - [Introduction](programming-example-introduction.md) 11 | - [The function blocks](programming-example-the-function-blocks.md) 12 | - [Test cases - Part 1](programming-example-test-cases-part-one) 13 | - [Test cases - Part 2](programming-example-test-cases-part-two) 14 | - [Implementation - Part 1](programming-example-implementation-part-one.md) 15 | - [Implementation - Part 2](programming-example-implementation-part-two.md) 16 | - [Final words](programming-example-final-words.md) 17 | -------------------------------------------------------------------------------- /img/tcunit-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tcunit/TcUnit/d9934d547aa0adb6719ddd6385191ade8c620c29/img/tcunit-logo.png --------------------------------------------------------------------------------