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

24

我应该如何在Simulink或更好的Stateflow中进行单元测试?

作为一个敏捷软件方法的爱好者,包括测试驱动开发。我负责开发安全关键控制软件,并且我们正在使用Matlab / Simulink / Stateflow进行开发。选择这个工具集是因为与仿真系统(硬件)模型之间的链接。 (模型-环路,硬件-环路)

我在Stackoverflow上找到了一些链接: MATLAB的单元测试框架: xunit, slunitdoctest

  • 有人使用过这些或其他单元测试框架吗?
  • 如何将其与持续集成系统(例如Hudson)链接?
8个回答

9

编辑:现在有Jenkins插件可以更轻松地进行MATLAB相关操作了。

原始回答:

正如Craig所提到的,MATLAB确实在R2013a中引入了一个框架。此外,在R2014a中,该框架增加了TAPPlugin,可输出Test Anything Protocol。使用该协议,您可以使用TAPPlugin(例如JenkinsTeamCity)设置CI构建,以便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;

编辑:我将这个主题作为今年推出的一个新开发者定向博客第一篇第二篇文章。


是的,终于。R2013开始成为专业软件开发的真正平台,而R2014变得更好了。此外,基本配置管理是一个很好的补充。回到2011年,这个功能严重缺失,很高兴他们赶上了。 - Adriaan
我也在尝试在Simulink模型上设置单元测试,并使用matlab.unittest框架。使用上述示例,我可以获得一个包含测试结果的tapFile,但我还想导出从测试运行的cvsim中获取的覆盖率信息。有什么想法吗? - Otzen

4

很不幸,对于Simulink单元测试并不是一件容易的事情。MathWorks推出了SystemTest。另外,您可以选择自己编写Simulink测试框架,这是我们采用的方法,并且并不太困难,但您可能需要通过编程构建测试工具。

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


非常正确。通常Simulink模型被视为整体块;Mathworks也是如此,但我的首选方法是小的、可独立测试的块,可以由团队中的多个人并行工作。此外,Mathworks往往会推出另一个新工具(有独立的许可证方案,常常需要所有团队成员)。生命中最好的事情之一是免费的;我认为xUnit就是其中之一......也许Matlab/Simulink/Stateflow社区还没有准备好敏捷/测试驱动开发。感谢您为此引入悬赏。 - Adriaan

3
R2016b推出了Simulink测试MATLAB单元测试框架之间的集成。使用Test Manager(*.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
文档显示了使用matlab.unittest.plugins.TAPPlugin生成TAP结果的示例,但您也可以同样轻松地使用XMLPlugin(https://www.mathworks.com/help/matlab/ref/matlab.unittest.plugins.xmlplugin-class.html)。
这将在MATLAB环境中实现更好的集成,即使没有CI,也能够在同一测试套件中同时运行MATLAB和Simulink测试。例如,如果您有一个名为MYDIR的目录,其中包含本地MATLAB单元测试和Simulink测试,则可以执行以下简单操作以一次性执行两种测试:

results = runtests(MYDIR)


3

Simulink Test看起来非常有用,可以解决测试方面的问题,您有关于与CI系统集成的任何想法吗? - Craig
你可以从命令行运行Matlab脚本。我使用TeamCity进行编排,使用Matlab脚本来运行测试。查看matlab.unittest.plugins.TAPPlugin,以在CI前端查看测试报告。 - Aykut Kllic

2
自2013b版本以来,Matlab内置了对xUnit的支持,形式为Unit Testing Framework
虽然我没有使用过它,但由于可以通过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单元测试框架是在R2013a中引入的。然而,它的附加功能已经在R2013b和R2014a中添加了。 - Andy Campbell

2
如果您的系统比较复杂,建议使用模型引用进行分解,并独立测试每个部分。
另一个解决方案(更加“老派”)是将主要模块放入库中,并创建小型模型。
为了测试这些子模型,特别是那些具有状态机(Stateflow)的模型,最好使用Signal builder块创建时间测试用例。您可以使用强大的函数signalbuilder与该块进行交互并加载测试用例。我的方法是为每个子模型的每个情况获取一个输入文件和一个输出文件。模型使用sim(无外部输入)运行,然后使用脚本比较两个输出,指示哪个信号不同(以及何时)。
您可以使用现有系统,但我更喜欢使用自己的系统来运行每个用例(或其中的一些)。
我没有任何公共代码,但这是我使用的方式。我不使用CIS,所以无法回答你问题的第二部分。

这个回答并没有真正帮到你,但看起来它将会得到悬赏,除非有人提供更好的解决方案。 - Nzbuu
1
我已经使用SVN进行版本管理,为了这个目的完成了这项工作。然而在测试方面,我预见到会有大问题。特别是因为即使是一些小修改也要求编译新的“正确”输出。 - Adriaan

0

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

编辑:我是这个软件的开发人员,所以我的观点可能有偏见。但我没有参与产品的营销或销售。我只是发布这篇文章,因为我知道几乎没有符合提问者需求的单元测试框架(正如答案所推测的那样)。

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


0

我看到了不同的解决方案来解决单元测试Simulink模型的问题。 Simulink Verification & Validation 在检查时不支持测试运行器和测试套件的xUnit概念,TPT 负载过多,不易使用,并且在可变性和可维护性方面非常困难。

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

最终,我们最终使用了一个C单元测试框架(CUnit)测试生成的代码。虽然这确实有一个缺点,就是您必须在测试之前生成代码,但它也有很多优点,比如轻松集成到CI系统中,编写单元测试的高度灵活性,快速执行单元测试,以及在从Simulink切换到另一个基于模型的环境或手写代码方面具有重构能力。特别是最后一点不应该被低估,因为我已经看到很多本来应该是手写模块的Simulink模型。现在,我建议使用GoogleTest而不是CUnit

当然,您可以对生成的代码进行单元测试。但我正在寻找有关模型和算法的证明。在代码生成后,可以重复使用单元测试来证明生成的代码产生相同的结果。我已经使用大型数据集进行了集成测试。 - Adriaan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接