单元测试/与 Simulink/Stateflow 持续集成

发布于 2024-12-03 21:43:05 字数 744 浏览 2 评论 0 原文

如何在 Simulink(或者最好是 Stateflow)中执行单元测试?

我是敏捷软件方法的粉丝,包括测试驱动开发。我负责安全关键控制软件的开发,我们使用 Matlab/Simulink/Stateflow 来开发它。选择此工具集是因为与工厂(硬件)模型的链接。 (模型在环、硬件在环)

我在 Stackoverflow 上找到了一些链接: MATLAB 单元测试框架xunitslunitdoctest

  • 有人有使用这些或不同单元测试框架的经验吗?
  • 如何将其链接到持续集成系统(即Hudson)?

How can I perform unit testing in Simulink, or preferably, Stateflow?

I'm a fan of agile software methods, including test driven development. I'm responsible for the development of safety critical control software and we're using Matlab/Simulink/Stateflow for the development of it. This toolset is selected because of the link with plant (hardware) models. (model-in-the-loop, hardware-in-the-loop)

I have found some links on Stackoverflow: Unit-testing framework for MATLAB: xunit, slunit and doctest.

  • Does anyone have experience in using those or different unit test frameworks?
  • How to link this to continuous integration systems (i.e. Hudson)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

抱着落日 2024-12-10 21:43:06

不幸的是,单元测试 Simulink 并不简单。 Mathworks 有 SystemTest。或者,您可以构建自己的 Simulink 测试框架,这是我们遵循的方法,并且不太困难,但您可能需要以编程方式构建测试工具。

为了与 CI 集成,您需要创建一个执行所有测试的函数/脚本,然后您可以使用 MATLAB.exe 的命令行参数在启动时运行脚本。不过,我不确定是否有人有将测试报告与 CI 软件集成的好方法。只需查看 MATLAB 单元测试框架< 中的评论数量即可/a>.

Unit testing Simulink is not straightforward, unfortunately. Mathworks have the SystemTest. Alternatively, you can roll-your-own Simulink testing framework, which is the approach that we've followed and is not too difficult, but you may need to built test-harnesses programmatically.

In order to integrate with CI, you need to create a function/script that executes all the tests, then you can use the command-line parameters for MATLAB.exe to run a script on start-up. I'm not sure anyone has a good way of integrating the test reports with the CI software, though. Just look at the number of comments in Unit-testing framework for MATLAB.

迷雾森÷林ヴ 2024-12-10 21:43:06

2015 年,Matlab 推出了新产品“Simulink Test”。也许这会简化这个混乱。

http://www.mathworks .com/products/simulink-test/features.html#manage-test-plans-and-test-execution

With 2015a Matlab introduces a new product name "Simulink Test". Perhaps that'll simplify this mess.

http://www.mathworks.com/products/simulink-test/features.html#manage-test-plans-and-test-execution

逆流 2024-12-10 21:43:06

R2016b 引入了 Simulink TestMATLAB 单元测试框架。使用测试管理器 (*.mldatx) 通过 Simulink Test 创建的测试可被 MATLAB Unit Test Runner 识别并可在本机运行,因此您可以生成 JUnit 样式的 XML 测试结果或 TAP 测试结果,以促进持续集成工作流程。

有关详细信息,请参阅此参考:https://www.mathworks.com/help/sltest/ug/run-test-files-using-matlab-unit-test.html?s_tid=gn_loc_drop

文档显示了生成 TAP 的示例使用 matlab.unittest.plugins.TAPPlugin 结果,但您可以使用 XMLPlugin (https://www.mathworks.com/help/ matlab/ref/matlab.unittest.plugins.xmlplugin-class.html)也同样容易。

这应该能够在 MATLAB 环境中实现更好的集成,即使图中没有 CI,也能够将 MATLAB 和 Simulink 测试放在同一个测试套件中,并让它们无缝地一起运行。例如,如果您有一个目录 MYDIR,其中包含本机 MATLAB 单元测试和 Simulink 测试,则可以执行如下简单操作来一次性执行两种测试:

<块引用>

结果=运行测试(MYDIR)

R2016b introduces integration between Simulink Test and MATLAB Unit Testing framework. Tests created with Simulink Test using Test Manager (*.mldatx) are recognized by and can be run natively using the MATLAB Unit Test Runner and thus you can generate JUnit style XML test results or TAP test results facilitating Continuous integration workflows.

See this reference for more information: https://www.mathworks.com/help/sltest/ug/run-test-files-using-matlab-unit-test.html?s_tid=gn_loc_drop

The documentation shows an example of producing TAP results using matlab.unittest.plugins.TAPPlugin but you can use XMLPlugin (https://www.mathworks.com/help/matlab/ref/matlab.unittest.plugins.xmlplugin-class.html) instead just as easily.

This should open up a better integration within just MATLAB environment even without CI in the picture with the ability to have MATLAB and Simulink Tests together in the same test suite and have them run together seamlessly. For example if you have a directory MYDIR with both native MATLAB unit tests and Simulink Tests, you can do something as simple as the follows to execute both kinds of tests in one shot:

results = runtests(MYDIR)

情栀口红 2024-12-10 21:43:06

如果您的系统很复杂,您应该使用 模型参考并独立测试其中每一个。

另一种解决方案(更“老派”)是将主要模块放入库中并创建小型模型。

要测试这些子模型,尤其是使用状态机 (Stateflow) 的子模型,最好是创建临时测试用例
使用 Signal builder 块。你有一个强大的功能signalbuilder与此块交互并加载测试用例。我的方法是为每个子模型的每种情况获取一个输入文件和一个输出文件。模型的输出是“正确”的输出,并且是来自模块的输出。该模型使用 sim 运行(无外部输入),并将 2 个输出与脚本进行比较,指示哪个信号不同(以及何时)。

您可以使用现有的系统,但我更喜欢使用我自己的系统来运行每个案例(或其中一些案例)。

我没有任何公共代码,但这就是我使用的方式。我不使用 CIS,因此无法回答您问题的第二部分。

If your system is complex, you should decompose it using Model Reference and test each of these independently.

An other solution (more "old school") is to put your main blocks in a library and to create small models.

To test these submodels and especially those with a State Machine (Stateflow), the best is to create temporal test cases
with the Signal builder block. You have a powerful function signalbuilder to interact with this block and load test cases. My method is to get for each case of each submodel an input file and an output file. Your outputs of the model are the "correct" output and the one from the blocks. The model is run with sim (no external inputs) and the 2 outputs are compared with a script the indicated which signal is different (and when).

You could use an existent system but I prefer to use my own to run each case (or some of them).

I don't have any public code for that but that's the way I use. I don't use a CIS so I can't answer the second part of your question.

尝蛊 2024-12-10 21:43:06

Matlab(自 2013b 起)内置了对 xUnit 的支持,其形式为 单元测试框架
我还没有使用过它,但由于可以使用 sim() 从 Matlab 运行 simulink,因此该框架可用于测试您的 simulink 模型。正如其他回答者所指出的那样,您的库和可能的模型将需要一个包装器来执行它。

Mathworks 网站上有很多示例,遗憾的是它们都没有运行 simulink 模型。我会为你编写一个示例,但我没有 ML2013b :-(

为了从 CI 启动测试(我使用 Jenkins),那么你可以调用 matlab 来运行一个 .m 文件来运行你的测试套件,此示例 cmd 脚本将从 Matlab 调用 Run_Tests.m

IF EXIST "C:\Program Files (x86)\MATLAB\R2013b\bin\win32\matlab.exe" (
    REM WinXP
    "C:\Program Files (x86)\MATLAB\R2013b\bin\win32\matlab.exe" -r "Run_Tests;exit" -logfile matlab.log
) ELSE (
    REM Win7
    "C:\Program Files\MATLAB\R2013b\bin\win32\matlab.exe" -r "Run_Tests;exit" -logfile matlab.log
)

请注意,如果您调用 Matlab 的目录中存在 startup.m,那么它将自动执行在Run_Tests.m`之前。

Matlab (since 2013b) has built-in support for xUnit, in the form of the Unit Testing Framework.
I haven't used it but since it's possible to run simulink from Matlab with sim() then this framework can be used to test your simulink models. You libraries and possibly models will need a wrapper to execute it as the other answerers have noted.

There are plenty of examples on the Mathworks site, unfortunately non of them run simulink models. I'd code an example for you, but I don't have ML2013b :-(

In order to initiate your tests from a CI (I use Jenkins) then you can call matlab to run a .m file that runs your test suite, this example cmd script will call Run_Tests.m from Matlab:

IF EXIST "C:\Program Files (x86)\MATLAB\R2013b\bin\win32\matlab.exe" (
    REM WinXP
    "C:\Program Files (x86)\MATLAB\R2013b\bin\win32\matlab.exe" -r "Run_Tests;exit" -logfile matlab.log
) ELSE (
    REM Win7
    "C:\Program Files\MATLAB\R2013b\bin\win32\matlab.exe" -r "Run_Tests;exit" -logfile matlab.log
)

Note that if a startup.m exists in the directory that you call Matlab from, then it'll be executed automatically beforeRun_Tests.m`.

救星 2024-12-10 21:43:06

我认为您正在寻找类似 EZTEST 的内容。它专为您的特殊目的而设计:单元级别的 Simulink 和 Stateflow 测试驱动开发。对于安全关键软件,还包含一份安全手册,其中描述了 ISO 26262 的涵盖内容。

编辑:我是该软件的开发人员,因此我的观点可能有偏见。但我不参与该产品的营销或销售。我只是发布此内容,因为我知道几乎没有单元测试框架可以满足提问者的需求(正如答案可能假设的那样)。

还支持使用 SIL 和 PIL 的测试单元。不幸的是我对哈德逊不熟悉,所以我无法回答这部分问题。

I think you are searching for something like EZTEST. It is intended for your special purpose: Test driven development for Simulink and Stateflow on unit level. For safety critical software, there is also a Safety Manual included, which describes what is covered regarding ISO 26262.

Edit: I am a developer of this software, so my opinion may be biased. But I am not involved in the marketing or sale of the product. I am just posting this, because I know that there are little to none unit test frameworks out there, meeting the questioner's needs (as the answers might suppose).

Testing units using SIL and PIL is also supported. Unfortunately I am not familiar with Hudson, so I cannot address this part of the question.

巷雨优美回忆 2024-12-10 21:43:06

我见过针对 Simulink 模型单元测试问题的不同解决方案。 Simulink 验证与验证验证在检查时不支持测试运行程序和测试套件的xUnit概念,TPT功能过多,不易于使用,并且在可更改性和可维护性方面非常困难。

此外,我还看到过使用 Matlab 脚本和 Excel 表格的自定义解决方案,它们很轻量,但在可理解性和可维护性方面也很困难。我仍然不建议使用任何这些方法,至少不建议用于单元测试。

最后,我们最终使用 C 单元测试框架 (CUnit) 测试生成的代码。虽然这肯定有一个缺点,即您必须在测试之前生成代码,但它也有很多优点,例如轻松集成到 CI 系统中,编写单元测试的灵活性高快速执行单元测试,以及最后但并非最不重要的重构功能,即从 Simulink 切换到另一个基于模型的环境或手写代码。尤其是最后一点不容小觑,因为我见过很多本来应该是手写模块的 Simulink 模型。如今,我建议使用 GoogleTest 而不是 CUnit.

I've seen different solutions to the problem of unit testing Simulink models. Simulink Verification & Validation which did not support xUnit concepts of test runners and test suites at the time of examination, TPT being overloaded with functionality, not easy to use and very hard in terms of changeability and maintainability.

Furthermore I've seen custom solutions with Matlab scripts and Excel tables which were lightweight but also difficult in terms of understandability and maintainability. I'd still not recommend using any of these approaches, at least not for unit testing.

In the end, we ended up using a C unit testing framework (CUnit) testing the generated code. While this definitely has the disadvantage that you have to generate code before testing, it also has a lot of advantages, like easy integration into CI systems, high flexibility of writing unit tests, fast execution of unit tests and last but not least refactoring capabilities in terms of switching from Simulink to another model-based environment or to hand-written code. Especially the last point should not be underestimated since I have seen many Simulink models that should have been hand-written modules in the first place. Nowadays, I'd recommend using GoogleTest instead of CUnit.

寂寞陪衬 2024-12-10 21:43:05

变得更加容易并且变得越来越容易

编辑:现在使用 MATLAB 的 Jenkins 插件原始答案 :

正如 Craig 提到的,R2013a 中确实引入了 MATLAB 框架。此外,该框架添加了 TAPPlugin 在 R2014a 中,输出 Test Anything Protocal。使用该协议,您可以使用 TAPPlugin 设置 CI 构建(例如 Jenkins< /a>, TeamCity) 以便 CI 系统如果测试失败,构建可能会失败。

您的 CI 构建可能看起来像启动 MATLAB 并运行所有测试的 shell 命令:

/your/path/to/matlab/bin/matlab -nosplash -nodisplay -nodesktop -r "runAllMyTests"

然后 runAllMyTests 创建要运行的套件并运行它,同时将 Tap 输出重定向到文件。您需要在此处调整具体细节,但这也许可以帮助您开始:

function runAllMyTests

import matlab.unittest.TestSuite;
import matlab.unittest.TestRunner;
import matlab.unittest.plugins.TAPPlugin;
import matlab.unittest.plugins.ToFile;

try
    % Create the suite and runner
    suite = TestSuite.fromPackage('packageThatContainsTests', 'IncludingSubpackages', true);
    runner = TestRunner.withTextOutput;
    
    % Add the TAPPlugin directed to a file in the Jenkins workspace
    tapFile = fullfile(getenv('WORKSPACE'), 'testResults.tap');
    runner.addPlugin(TAPPlugin.producingOriginalFormat(ToFile(tapFile)));

    runner.run(suite); 
catch e;
    disp(e.getReport);
    exit(1);
end;
exit force;

编辑:我将此主题用作第一个 两篇 帖子 今年推出的新的面向开发人员的博客

EDIT: This is now much easier and getting easier all the time with the Jenkins plugin for MATLAB

ORIGINAL ANSWER:

As Craig mentioned there is indeed a framework in MATLAB introduced in R2013a. Furthermore, this framework added a TAPPlugin in R2014a which outputs the Test Anything Protocal. Using that protocol you can set up your CI build with a TAPPlugin (eg. Jenkins, TeamCity) so that the CI system can fail the build if the tests fail.

Your CI build may look like a shell command to start MATLAB and run all your tests:

/your/path/to/matlab/bin/matlab -nosplash -nodisplay -nodesktop -r "runAllMyTests"

Then the runAllMyTests creates the suite to run and runs it with the tap output being redirected to a file. You'll need to tweak specifics here, but perhaps this can help you get started:

function runAllMyTests

import matlab.unittest.TestSuite;
import matlab.unittest.TestRunner;
import matlab.unittest.plugins.TAPPlugin;
import matlab.unittest.plugins.ToFile;

try
    % Create the suite and runner
    suite = TestSuite.fromPackage('packageThatContainsTests', 'IncludingSubpackages', true);
    runner = TestRunner.withTextOutput;
    
    % Add the TAPPlugin directed to a file in the Jenkins workspace
    tapFile = fullfile(getenv('WORKSPACE'), 'testResults.tap');
    runner.addPlugin(TAPPlugin.producingOriginalFormat(ToFile(tapFile)));

    runner.run(suite); 
catch e;
    disp(e.getReport);
    exit(1);
end;
exit force;

EDIT: I used this topic as the first two posts of a new developer oriented blog launched this year

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文