开发区域

MATLAB高级软件开发

You 've Got Mail!

今天我想分享一些乐趣,我一直在定制从我的Jenkins构建发送的电子邮件。这是受到纳伦德拉的启发评论在之前的一篇文章中。所以,说到这里,我在看完评论后快速浏览了一下,找到了Email-ext插件,允许自定义电子邮件发送给管理员和代码提交者(违规者?)失败或不稳定的构建。这个插件会立即发送一封电子邮件,列出所遇到的失败测试。虽然这很好,但在我的书中,它不合格。为什么?
  1. 默认情况下,它非常适合JUnit测试结果。看在上帝的份上,这些不是JUnit的结果!我们在这里谈论的是MATLAB代码!我希望CI系统配置像它正在集成的代码一样是生产级的,这意味着我们不接受将MATLAB测试结果调用为JUnit测试结果!
  2. 显示失败的测试很好,但我还想查看诊断。如果我们有机会立即知道问题是什么,那么我就不需要通过点击来解决这个问题。在电子邮件中有诊断可能意味着当我在手机上收到电子邮件时,我确切地知道构建失败的原因骑T在回家的路上。剩下的旅程将受益于已经找到解决方案的宝贵大脑周期。如果我必须点进去?不行。
用MATLAB编写好了,我的策略是从默认的html电子邮件模板中提取基本格式,因为定制API涉及编写果冻我打赌没有多少人有丰富的果冻写作经验(我当然没有)。你可以看到一个html电子邮件的默认果冻脚本被列出在这里,所以在第一次剪辑中,让我们把它简化成我们自己的版本。如果你分析默认的html模板,你可以看到jelly脚本有这样的基本格式:
     
在主脚本主体中,有一个用于样式化的节点和一个用于主体的节点。现在,让我们只保留与默认模板匹配的样式,有一个显著的不同之处在于,我们定义了另一个类来处理筛选后的测试。
对于主体内容,为什么我们不删除我们不使用的内容,只保留我们目前感兴趣的内容呢?所以我将保留一般的工作信息,来自您的SCM系统的变更集信息,以及工件:
<身体> < j: var =“spc”价值= ",,,,”/ > < !——GENERAL INFO——>< TABLE>  < j:when test="${build. "result=='SUCCESS'}">     < j:否则>< IMG SRC="${rooturl}static/e59dfe28/images/32x32/yellow.gif" /> < /j:choose>  $ {rooturl} ${构建。url} < / > < / TD > < / TR > < TR > < TD >项目:< / TD > < TD > $ {project.name} < / TD > < / TR > < TR > < TD >构建日期:< / TD > < TD > ${。timestampString} 构建时间:${构建。durationString}  
CHANGES
${spc}Revision ${cs.commitId?:cs.revision?:cs.changeNumber} by ${aUser!=null?aUser. displayname:cs.author。displayName}: < / B > < B > ($ {cs.msgAnnotated}) < / B > < / TD > < / TR > < j: forEach var = = " $ {cs“p”项。affectedFiles} " > < TR > < TD宽度=“10%”> ${程控}$ {p.editType.name} < / TD > < TD > $ {p。路径}< / TD > < / TR > < / j: forEach > < / j: forEach > < j:如果测试= " $ {!hadChanges} " > < TR > < TD colspan = " 2 " >没有变化< / TD > < / TR > < / j: if > < /表> < BR / > < / j: if > < !——ARTIFACTS——>
BUILD ARTIFACTS
  • ${f}

  • 还在听吗?好的,接下来的部分变得很有趣,因为我想以类似于MATLAB如何将它们作为TestResults数组呈现给我的方式查看测试结果。因此,我们将打印通过/失败/过滤测试的总数,而不是遍历所有的包,然后为失败的测试创建一个部分,为过滤的测试创建一个部分。
    <!——测试报告模板(对JUnit的引用是指由MATLAB TestRunner生成的JUnit风格的XML输出)——>          
  • Failed:${failed_test.getFullName()}
  • Filtered:李$ {filtered_test.getFullName ()} < / > < / B > < / TD > < / TR > < / j: forEach > < / j: forEach > < / j: forEach > < /表> < BR / > < / j: if >注意,我们在这里所做的是jenkins中的分析信息TestResult包含由MATLAB生成的JUnit样式xml中包含的信息的实例XMLPLugin还记得?)有了这些信息,我们将循环遍历这些结果三次,一次计算总数,一次打印失败的测试,一次打印过滤后的测试。现在我们可以为子孙后代展示长尾并结束身体而且果冻标签。
    <!日志输出——> <表格宽度=“100%”单元格边距= " 0 "单元格间距= " 0 " > < TR > < TD类=“bg1”> < B >日志尾部(附完整的日志)< / B > < / TD > < / TR > <珍:forEach var =“线”项目= " $ {build.getLog (100)} " > < TR > < TD类=“控制台”> ${线}< / TD > < / TR > < / j: forEach > < /表> < BR / > < /身体> < / j:果冻>
    这有用吗?现在还没有。首先,我们需要将这个果冻脚本保存在一个允许我们配置Jenkins在创建电子邮件时使用该脚本的位置。为此,需要将脚本保存到JENKINS_HOME /邮件模板/美元文件夹,以便被插件拾取。如果你不是jenkins管理员,这可能需要一些哄骗说管理员。然而,一旦哄骗成功,你可以配置插件在一个项目一个项目的基础上使用这个脚本。对我来说是这样的:应用这个脚本后,我现在收到了Jenkins的这封电子邮件: 哇哇!那封邮件会说MATLAB!下一步-包括一些诊断。诊断结果是什么,医生?这实际上很容易,只需对jelly脚本的失败部分进行简单的修改。我们只需要添加另一个表行作为预格式化文本,并调用getErrorStackTrace,这是MATLAB的诊断程序所在的位置。
  • MATLAB测试套件摘要: ${passCount+failCount+skipCount} Ran, ${failCount} Failed, ${passCount} Passed,${skipCount} Filtered
    Failed Tests
    Filtered Tests
    Failed Tests
  • Failed: ${failed_test. getfullname ()}
  • < /TR> 通过这个简单的更改,Jenkins现在也在电子邮件中包含了诊断信息。 两全其美好吧,我需要再做最后一个调整(我保证)。虽然我很喜欢在邮件中包含诊断信息,但它似乎一次包含了太多的信息。我真正想要的是我们产生的第一个输出,它可以一次显示我所看到的每个测试失败的诊断结果。这能做到吗?嗯,有点。请记住,我们是在电子邮件客户端中处理电子邮件内容,而不是呈现动态html和JavaScript的成熟浏览器。使用JavaScript通常很容易做到这一点,但不幸的是,电子邮件内容不支持这一点。金宝app我们需要某种形式的动态内容来响应静态html内容中的鼠标点击。鼠标点击,或鼠标徘徊在.好吧,秘密已经泄露了。这可以为支持CSS悬停选择器的电子邮件客户端的子集!金宝app对于其他人,你仍然可以发送完整的电子邮件内容,只是无法看到动态行为。我的客户端恰好支持悬停CSS选择器,所以它金宝app很适合我。这是我们需要做的。首先,用更多的样式类和悬停行为更新文档的样式部分,当我们没有悬停在测试名称上时,将诊断的字体大小设置为0%,当我们悬停在测试名称上时,将大小设置为100%。它看起来像下面这样
    在这里,我们为表行添加了一些类,当我们将鼠标悬停在测试结果行上时,将它标记为浅灰色。与此同时,我们还将紧随悬停行之后的输出行样式更改为100%。欺骗!这也需要对jelly脚本的测试结果部分进行一些更改,主要是为了选择这些不同的样式类。
    Failed Tests
  • Failed:李$ {failed_test.getFullName ()} < / > < / B > < / TD > < / TR > < TR类=“output_row”> < TD类=“输出”> < PRE > $ {failed_test.getErrorStackTrace ()} < / PRE > < / TD > < / TR > < / j: forEach > < / j: forEach > < / j: forEach >我们做得怎么样?至少在我的电子邮件客户端中,我们有一封简洁的电子邮件,当我在感兴趣的测试上停留时,它会为我提供每个测试的完整诊断信息。这是最后的果冻脚本。请拿着这个,让它变得更好,让我知道你在评论
         
    BUILD ${build.result}
    Build URL${rooturl}${build.url}
    Project:${project.name}
    Date of build:${it.timestampString}
    Build duration:${build.durationString}

    Changes
    ${spc}Revision ${cs.commitId?:cs.revision?:cs.changeNumber} by ${aUser!=null?aUser.displayName:cs.author.displayName}: (${cs.msgAnnotated})
    ${spc}${p.editType.name} ${p.path}
    No Changes

    Build Artifacts
  • ${f}

  • MATLAB Test Suite Summary: ${passCount+failCount+skipCount} Ran, ${failCount} Failed, ${passCount} Passed, ${skipCount} Filtered
    Failed Tests
  • Failed: ${failed_test.getFullName()}
  • ${failed_test.getErrorStackTrace()}
    Filtered Tests
  • Filtered: ${filtered_test.getFullName()}

  • Build Log Tail (Full Log Attached)
    ${line}

    发布与MATLAB®R2015b

    |
    • 打印
    • 发送电子邮件

    评论

    如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。