开发人员区

高级软件开发与MATLAB

我们会帮你

报道。一切都很好。医疗保险很好。手机信号很好。即使是云层覆盖,有时也能在强烈的阳光照射下提供一个很好的休息。毫无疑问,好的代码覆盖也会给我们一种温暖而模糊的感觉,就像在寒冷的日子里喝一杯温暖的饮料。

...和often for good reason. Code coverage can help us see areas of our code that are not exercised in some form or another, and can be very helpful, in agood-friend-that-can-be-brutally-honest-with-you排序的方式。它可以指出我们真正需要添加更多测试的地方。一旦我们对好朋友的建议做出反应,加入更好的测试,我们就会变得更好。

顺便提一下,需要注意的是。我们(所有人)应该记住,代码覆盖率并不能显示什么代码涵盖哪些代码不是覆盖。这是因为看到一段代码被覆盖并不能说明它是如何被覆盖的,它是否被一个专门针对该代码的测试所覆盖,或者一些偶然的覆盖,并且也没有关于该覆盖是否以任何方式验证了正确结果的信息。外卖,使用覆盖率来查看代码的区域是测试。不要掉进陷阱,不要得出结论说覆盖的代码没有bug,或者甚至远程测试充分。

也就是说,如果您对它有正确的心态,它将是一个伟大的工具,当与测试和持续集成相结合时,它可以帮助我们确保我们的测试符合标准。

好消息!这就简单多了。我们有CodeCoveragePlugin对于单元测试框架,它已经产生了一份报告,该报告更多地被设计用于交互式MATLAB环境,而不是CI系统工作流。现在我们可以选择在Cobertura格式,并从中受益Cobertura插件Jenkins

让我们继续我们的(矩阵)构建最后一次,但增加一些报道。

导入(“matlab.unittest.plugins.CodeCoveragePlugin”);导入('matlab.unittest.plugins.codecoverage.coberturaformat');coverageFile = fullfile (resultsDir,“coverage.xml”);runner.addPlugin (CodeCoveragePlugin.forFolder (src,...'制作'CoberturaFormat (coverageFile)));

简单派。现在让我们看看它在CI构建中是什么样子的:

哦!我忘记了我们正在构建的其他版本没有这个插件的事实:

没什么大不了的,我们只需要通过版本检查将插件的安装打包到TestRunner中。让我们把它放到一个函数中:

函数addCoberturaCoverageIfPossible(跑步者,src coverageFile)如果~ verLessThan (matlab的“9.3”)进口(“matlab.unittest.plugins.CodeCoveragePlugin”);导入('matlab.unittest.plugins.codecoverage.coberturaformat');runner.addPlugin (CodeCoveragePlugin.forFolder (src,...'制作'CoberturaFormat (coverageFile)));结束结束

我们只能从我们的测试运行脚本调用该函数:

试一试导入(“matlab.unittest.TestRunner”);导入(“matlab.unittest.plugins.XMLPlugin”);导入(“matlab.unittest.plugins.ToFile”);ws = getenv (“工作区”);src = fullfile (ws,'来源');目录(src);测试= fullfile (ws,'测试');套件= testsuite(测试);%创建并配置运行器跑步者= TestRunner.withTextOutput (“冗长”3);%添加TAP插件resultsDir = fullfile (ws,'检测结果');mkdir (resultsDir);resultsFile = fullfile (resultsDir,“testResults.xml”);runner.addPlugin (XMLPlugin.producingJUnitFormat (resultsFile));coverageFile = fullfile (resultsDir,“coverage.xml”);addCoberturaCoverageIfPossible(跑步者,src coverageFile);结果= runner.run(套房)E DISP(GetReport(e,'延伸'));出口(1);结束辞职(“力”);

此外,MATLAB代码只是等式的一半。我们还需要确保Jenkins Cobertura插件已经安装,并且构建配置为跟踪覆盖范围。在这里,我们只是将其作为一个构建后操作添加,并将其配置为在结果文件夹中查找名为coverage.xml.xml.

注意,由于我们在多个版本中运行测试,并且早期的版本没有插件,我们还需要告诉插件如果没有覆盖文件出现,不要让构建失败。如果我们不这样做,那么所有早期版本的构建都将失败,因为不会找到Cobertura xml文件。

好的,现在我们在商业。该构建现在通过所有版本:

然而,当我们导航到R2017b构建时,我们可以看到覆盖报告:

深入挖掘,我们可以看到我们需要添加测试的地方:

现在构建非常清楚地显示了我们忘记添加一个否定测试。让我们解决!下面是我想要写的测试:

函数testinvalidinput(testcase)%测试以确保我们在错误输入时优雅地失败testCase.verifyError (@ () simulateSystem (“双层”),...'Simulateystem:InvalidDesign:肩部);结束

但是,再次看我们的来源,我注意到一些可怕的东西,我们不可验证!作为提醒,这里是模拟器的代码:

函数[x, t] = simulateSystem springMassDamperDesign;%创建设计变量。如果~ isstruct(设计)| | ~所有(isfield(设计,{“c”'k'})) 错误('Simulateystem:InvalidDesign:肩部...“设计应该是一个具有字段“c”和“k”的结构”);结束%设计变量c = design.c;k = design.k;%常数变量z0 = (-0.1;0);%初始位置和速度m = 1500;%的质量Odefun = @(t,z) [0 1;- k / m - c / m] * z;[t, z] = ode45(odefun, [0,3], z0);%第一列为位置(平衡位移)X = z(:, 1);

...和for the design:

m = 1500;需要知道质量来确定临界阻尼design.k = 5e6;%弹簧常数Design.c = 2 * M * SQRT(Design.k / m);%阻尼系数是严重阻尼的清除

呵!没有办法在代码中输入坏值来测试它。因此,目前的代码是死的。如果需要,我们可以删除错误条件,因为我们知道脚本生成正确的设计格式。然而,这可能没有抓住重点。我们将设计从模拟脚本中分离出来的原因是为了调整设计和探索。我们真的想要simulateSystem功能可在许多不同的设计中可重复使用,因此我们应该将其参数化正确。然后该软件更可测试,这是灵活的同义词。为此,我们需要做的就是使设计脚本成为函数并将其作为仿真功能的输入接受:

函数[x, t] = simulateSystem(design)如果~ isstruct(设计)| | ~所有(isfield(设计,{“c”'k'})) 错误('Simulateystem:InvalidDesign:肩部...“设计应该是一个具有字段“c”和“k”的结构”);结束%设计变量c = design.c;k = design.k;%常数变量z0 = (-0.1;0);%初始位置和速度m = 1500;%的质量Odefun = @(t,z) [0 1;- k / m - c / m] * z;[t, z] = ode45(odefun, [0,3], z0);%第一列为位置(平衡位移)X = z(:, 1);函数设计= springMassDamperDesign m = 1500;需要知道质量来确定临界阻尼design.k = 5e6;%弹簧常数Design.c = 2 * M * SQRT(Design.k / m);%阻尼系数是严重阻尼的

做一些测试更新:

函数测试= designTest测试= functiontests(localfunctions);结束函数testSettlingTime (testCase)%%测试系统在2秒内稳定到0.001的零。[位置,时间] = Simulateystem(Springmassdamperdesign);positionafteretling =位置(时间> .002);%在这个例子中,验证在沉淀时间之后的第一个值。verifyLessThan (testCase、abs (positionAfterSettling), 2);结束函数testOvershoot (testCase)检验确保超调量小于0.01[位置,〜] = Simulateystem(Springmassdamperdesign);过度= max(位置);确认(测试柜,过冲,0.01);结束函数testinvalidinput(testcase)%测试以确保我们在错误输入时优雅地失败testCase.verifyError (@ () simulateSystem (“双层”),...'Simulateystem:InvalidDesign:肩部);结束

......现在我们应该在商业。让我们检查构建和结果覆盖:

啊,那很好啊。今天就到此为止吧。

...但在你退房之前史蒂夫的深入学习的新博客!这个人太棒了。多年来,他一直是图像处理方面的世界级博主,现在他正在将深度学习添加到自己的技能中。他甚至承诺将继续开这个图像处理博客。什么一个人!我很期待,一定要赶上他已经有几个帖子了这里这里




发布与MATLAB®R2017b

|

评论

要留下评论,请点击这里登录到您的MathWorks帐户或创建一个新帐户。