扬声器 | 成绩单 |
| 塞尔凯·奥尔梅兹 | 大家好,我是 Seagate 的 Serkay 和 Fred,今天我们将讨论如何构建 JSL 生态系统来管理 JSL 脚本。 |
| 因此,我们使用 Git 来管理源代码控制、JSL 脚本的源代码,以及分发它们。 这就是今天演讲的重点。 |
| 但除此之外,我还将讨论用于 PowerPoint 集成的 VBA、崩溃日志收集以及单元测试。 我会快速跳到大纲。 |
| 所以我想首先谈谈我们JSL的历史。 我使用 JSL 编写脚本已有大约 10 年左右的时间。 |
| 我们对目前所处的位置非常满意,但我们花了相当多的时间才到达这里,我想谈谈我们经历的里程碑,我们迄今为止所做的事情以及我们这样做的原因。 |
| 然后我们将讨论 Git 以及我们如何使 Git 能够对我们的 JSL 脚本进行源代码控制以及它如何使我们能够构建更多功能。 例如,一旦启用 Git, |
| 您可以添加更多功能,例如监视脚本。 所以您知道开发人员可以知道他们的脚本正在使用中,因此他们可以监视使用情况。 |
| 也许更重要的是,他们还可以收集日志。 如果脚本崩溃,开发人员知道并且他或她可以返回并修复这些错误。 而且你可以... |
| 您可以进一步添加一项功能。 您甚至可以创建您已经知道脚本崩溃的自动错误通知单。 因此,您可以自动为此创建错误单。 您可以使用 JIRA 或 Atlassian 等跟踪软件来跟踪这些票证。 |
| 最后我将介绍我们迄今为止的最佳实践和经验教训。 |
| 所以, |
| 在附录中,我还有我将要讨论的脚本的手册。 这是一个可以将图像推送到 PowerPoint 的脚本。 |
| 我有一本非常详细的手册,我应该让您知道我在这里谈论的所有内容、数据和脚本都将可用。 |
| 它们发布在此处参考部分的公共存储库中,如果您选择这样做,您可以直接去那里获取这些文件。 那么让我从 |
| 这里有简短的历史。 所以 10...我已经与 JSL 合作了大约 10 年左右,并且开始,我开始于 |
| 非常基础的知识,我对 JSL 脚本编写了解不多。 |
| 然后,一旦您开始这样做,您就会意识到您必须有一些适当的源代码控制,并且您需要正确的方法来分发脚本。 |
| 因此,JMP 脚本的特点是它的进入门槛为零。 因此,您实际上可以手动绘制情节,然后去获取脚本。 这是为你写的。 |
| 您还可以使用 JMP.com 中的 Community to JMP 提出问题并获得答案。 |
| 而您...脚本编写非常高效,您的工作非常高效,人们会注意到。 他们会问你是如何做事的,你会说我有一个脚本。 他们会 |
| 问:“你能和我分享一下吗?” 突然之间,你成为了一名开发人员,尽管你无意这样做。 |
| 然后你必须处理分发你的脚本。 我想到的第一个想法就是把它们附加起来,这是一个可怕的想法,我已经这样做了很长一段时间了。 |
| 很明显为什么这不是一个好主意,因为你附上一个脚本,然后将其发送出去,然后第二天你就制作了一个 |
| 修订版,然后你必须再次发送它,你甚至不知道用户是否会接受下一个。 所以我只是在这里说明这一点。 |
| 最近,我收到一位同事发来的电子邮件,他提到了我在 2017 年创建的一个脚本,我只是用这些对我的脚本进行编号 |
| 版本号,这不是一个好主意。 所以三四年后它又回来了,你意识到人们仍在使用三年前的脚本,因为他们没有更新。 |
| 解决此问题的一种方法是使用共享驱动器,并基于我与其中的人员进行的交互 |
| Discovery Summits,就是很多人、很多公司都在用这个。 那么开发人员要做的就是 |
| 将他们的脚本转储到共享驱动器中,用户将直接从共享驱动器中拉取,这解决了分发问题的一半问题,但它对源代码控制没有任何作用。 您不...您无法跟踪您在代码中所做的更改。 |
| 这就是我们实际上转向 Git 的原因。 这对我们来说是一个突破,并启用了许多功能。 那么,您使用 Git 所做的就是开发人员将他们的脚本推送到存储库并 |
| 用户将直接从 Git 提取脚本。 所以这对我们来说是一个很大的改进,它使我们能够收集崩溃日志并 |
| 脚本的使用等等。我只想谈谈我从峰会中学到的更多东西。 它们对提高我的脚本技能非常有用,我参加了 2018 年的一次峰会,学到了很多关于表达式等的知识。所以 |
| 人们可能想回去听这些演示,因为它们确实有助于提高脚本编写技能。 |
| 我们的另一个里程碑是关于测试。 因此,我受到了去年峰会上的这次演讲的启发,该演讲是关于单元测试的,它使您能够在发布脚本之前自动测试脚本。 |
| 今天我将主要讨论集成测试,因为单元测试......单元测试是必需的,但还不够。 |
| 因为您可以进行单元测试,所以您可以测试所有模块,并且它们检查得很好。 但当你把它们放在一起时,它们就不起作用了。 它们会崩溃,如此处所示。 每个抽屉可能都经过测试,但是当你把它们放在一起时,它们将无法操作。 |
| 一项对开发人员有很大帮助的好功能是日志收集。 |
| 知道您的脚本崩溃以及它是如何崩溃的非常有帮助。 您可以通过收集用户的日志来做到这一点,然后您可以返回并修复脚本并推送更改,用户将立即拥有固定的脚本。 |
| 我们最近推出的最后一个功能是关于自动错误报告。 既然您已经有了崩溃报告,为什么不根据该信息采取行动呢? 所以我们创建了一个自动化的 |
| 监控 |
| 系统,它将跟踪这些崩溃日志,并自动创建错误报告,以便开发人员可以处理这些问题。 最重要的是,您可以将用户添加为观察者,以便用户知道有人正在解决该问题。 这样,这样就解决了 |
| 解决了用户和开发者之间的信息鸿沟。 |
| 这显示了时间表,我将花一些时间 |
| 我们将在各个项目上进行讨论,但我们将从 Git 开始,我将快速构建它并让 Fred 来讨论它。 |
| 163084 | 好的。 |
| 所以, |
| Git 只是一个版本控制系统,我不使用版本控制这个词。 实际上我想说,即使您只在自己的本地计算机上使用 Git,Git 也可以通过为您提供有效的、无限制的重做来帮助您。 它 |
| 使您能够跟踪文件的修订并返回到旧的文件,以防您认为过去几周所做的某些工作不正确并且您想返回到几周前的某些工作。 |
| 所以 Git 只是一个安装在本地计算机上的软件。 它创建一个存储库,然后可以将该存储库发布到其他存储库。 |
| 例如 GitLab 或 GitHub。 TortoiseGit 是一个 GUI 界面,可让您的本地计算机变得更加轻松。 Serkay,您能否打开下一张幻灯片。 |
| 因此,我试图让开发人员使用的模型是在他们的本地计算机上。 本地开发人员,让他们安装 Git 客户端并启动 |
| 控制本地 PC 上文件的版本。 一旦他们养成了这样做的习惯,我们就可以将他们连接到远程存储库 |
| Git 通常连接到远程存储库或 SSH 或其他方法,并且它们可以推送 |
| 将 Git 数据库的副本复制到远程存储库。 一旦它出现在远程存储库上,HTTP Web 服务器就可以将其共享出去并进行 JMP |
| 然后可以指向 URL 和 HTTP...HTTP Web 服务器并从中加载脚本。 因此,我们没有使用共享驱动器,而是使用通过推送到 Git 存储库来填充的 HTTP Web 服务器。 |
| 下面的项目符号只是指出了它的好处以及它到底是如何工作的。 |
| 我们可以转到下一张幻灯片。 |
| 塞尔凯·奥尔梅兹 | 所以我将接管这里,Fred,我将向您展示...展示一个非常基本的插图实现,并且脚本可以在参考资料中找到。 |
| 所以, |
| 这将是一个非常基本的代码。 我在这里展示的是开发人员正在开发的代码。 这是最低限度的,对吧。 它只是一个对话框,上面写着“你好,世界”。 |
| 并假设开发人员希望将此代码传递给用户。 所以开发者传递的不是这段代码,而是这段代码, |
| 这是存储库的链接。 这是 hello JSL 脚本的存储库,它位于其中...... |
| 在远程存储库中。 用户所做的是,它只是抓取...用户抓取 |
| 来自 URL 的脚本。 所以这是静态代码。 它不需要任何更改,因此开发人员可以随时更改脚本,但用户无需执行任何操作。 我将在这里向您展示一个插图,我只想全屏显示。 |
| 只是,只是说明了这个东西如何与特定的 GUI(即 GitHub Desktop)一起工作。 所以你要做的就是安装这个 |
| 您计算机中的软件并创建本地存储库,他们将跟踪您所做的更改。 例如,在本例中,我刚刚创建了这个 hello JSL 脚本 |
| 该软件会知道有更改,并会自动突出显示。 你要做的是,首先将其提交到本地存储库, |
| 它将这些东西推送到您的本地存储库中,然后您将其推送到原点,这是一个远程存储库。 现在我将把它推送到远程,以便用户可以使用它。 |
| 因此,一旦您这样做了,现在用户将能够提取这个新代码。 我现在切换回用户角色,这是脚本,用户运行,当...一旦执行此操作,对话框就会显示。 因此,您正在运行从存储库中提取的脚本。 |
| 所以我将用更高级的代码来更好地说明这一点,这也与 PowerPoint 相关。 |
| 因此,人们在 JMP 中进行了大量分析,并且许多人最终仍然希望将结果推送到 PowerPoint 中。 我知道 JMP 有一些可以推动的功能 |
| 图像直接导出到 PowerPoint,但我们想要更多……更复杂的东西。 我们想 |
| 管理 PowerPoint 模板。 我们想要在 PowerPoint 中做更多的事情,决定每张幻灯片要放置多少个图像等。并且 |
| 为此,您首先需要将 JMP 与 PowerPoint 连接起来,实际上您可以非常... |
| 这是一种非常好的方式,因此您甚至不必离开 JMP。 因此,您可以找到 PowerPoint 可执行文件的位置,它通常位于 Program Files 下。 |
| 然后你创建一个批处理文件来触发这个 PowerPoint 可执行文件,它会抓取你想要运行的 PowerPoint 文件,然后运行它。 因此,您可以在 JMP 中完成所有这些操作。 基本上,它的作用是搜索 PowerPoint 可执行文件。 |
| 一旦找到它,它就会将其捆绑到这个批处理文件中。 它还包括您要运行的 PowerPoint 的路径 |
| 和宏,所以PowerPoint中会有一个宏来进行PowerPoint内部的管理。 所以这就是你的方式 |
| 将 JMP 与 PowerPoint 联系起来,您甚至必须让 JMP 来做这件事。 但问题是,首先如何向用户提供此 PowerPoint 文件? 你可以 |
| 让他去下载它,这并不理想,因为您想要自动管理它,同时您也想要控制您的 PowerPoint 的源代码。 所以它需要是一个好的候选者;它需要成为整个生态系统的重要组成部分。 你不想把它放在外面。 |
| 另一项要求是您不想在每次脚本运行时都下载 PowerPoint。 因此,仅当该图像存储库中的 PowerPoint 发生更改或 PowerPoint 出现新内容时,您才需要下载 PowerPoint。 |
| 因此,执行此操作的一种方法是使用这个小 JMP 脚本,即创建日期的 JMP 命令。 所以我在这里做的是检查 |
| 本地文件的日期。 因此,如果本地 PowerPoint 比我在存储库中的 PowerPoint 旧,那么我会去下载它。 所以 |
| 它将使用 HTTP 请求下载 PowerPoint,并且 |
| 看起来像这样。 所以你要做的就是去检查本地计算机上的 PowerPoint。 如果它不存在,您可以使用 HTTP 请求从存储库中提取它。 如果它存在,你喜欢看看它的日期,如果它是旧的,你仍然去 |
| 拉新的。 因此,这里的底线是您可以将 PowerPoint 无缝集成到 JMP 环境中,这样您就可以将结果推送到 JMP 中,包括表格、图像。 您可以在不破坏源代码控制的情况下完成所有这些工作,我将在这里展示一个演示。 |
| 例如,这将是您提供给用户的代码。 再次强调,这是静态代码。 它实际上除了一个 URL 之外什么都没有,该 URL 将脚本链接到远程存储库。 所以它会去抓住 |
| 存储库中的 JMP 脚本和这些脚本再次可用,您只需从参考文献中提取它们即可。 |
| 从,从,从开发者方面来看,这就是实际的脚本,对吧。 这是脚本,开发者已经开发并 |
| 他或她将其推送到远程存储库。 这个脚本的好处是,我只想快速指出一些功能。 |
| 例如,如果看看这个。 这是一个独立的文本脚本,您不必分发 PowerPoint 文件或其他脚本 |
| 分别地。您要做的就是在脚本中链接它们,并且它们在此处的存储库中链接, |
| 包括 PowerPoint。 所以这个脚本将管理所有的分发。 因此,它会去抓取 PowerPoint。 |
| 如果需要的话,它会去获取其他附加文件。 因此,所有内容都捆绑在一起到脚本中,因此它会为您完成所有管理。 让我快速展示一下。 我会把这个拉回来 |
| 并将其设置为全屏 |
| 这样你就可以看得清楚。 所以这将是自动触发PowerPoint的演示 |
| 对于它的特定情况。 这个脚本的作用是,它从表中获取路径,这是一个包含大量图像路径的 JMP 表,这些路径指的是这个特定的路径 |
| 服务器,它将采用这些路径,并且只会采用此处突出显示的路径,并将它们推送到 PowerPoint 中。 |
| 我将运行此脚本,如果您想尝试一下,您可以使用此脚本。 这是一个功能齐全、有用的脚本。 所以,我正在运行这个 |
| 脚本在这里。 同样,它指的是存储库。 所以它没有行脚本,它只是从存储库中提取它。 你运行它,它检索代码,运行对话。 |
| 我将简单地运行这个。 我不会详细介绍,一旦你运行它,它就会自动触发 PowerPoint。 |
| PowerPoint 将启动,然后它将...它正在开始...它正在此处构建幻灯片。 它将提取 20 张图像,这将需要 10 或 20 秒,然后您将获得 PowerPoint |
| 完毕。这就是您获得的 PowerPoint,一切都是自动完成的,并且所有内容都是从存储库中提取的。 |
| 那么下一步是什么? 您将如何修改此 PowerPoint? 所以,我假设您想对模板进行一些更改。 和 |
| 您可以在附录中看到更多详细信息,但我想展示的是如何更改 |
| PowerPoint 中的脚本。 我会转到全屏, |
| 我就运行这个。 我们从上一张幻灯片中剩下的开始,右,所以你有这些图像。 |
| 我想做的是以一种简单的方式更改模板,只是为了说明这一点。 所以你去... |
| 你转到宏,向下滚动并找到你想要更改的内容,我将在这里进行简单的更改。 我将更改标题颜色只是为了表明一点,对吧。 所以你改变这个 |
| 和 |
| 保存。 这就是实时进行的。 |
| 您保存它并可以删除幻灯片,以便它更快地到达存储库,因为您将把它推送到存储库。 |
| 然后使用 Git GUI 将其推出。 它将进入存储库 |
| 它将使其可供您的用户使用。 因此您的所有用户都将立即收到修改。 因此,您不必要求他们去更新 PowerPoint 或其他任何内容。 |
| 这只是去存储库。 |
| 我将切换回 JMP 并处于用户模式,然后再次运行脚本,这将检索新的 PowerPoint。 |
| 如果你再次运行它,它将通过 |
| 幻灯片,它将创建幻灯片。 您会注意到,您确实进行了更改,即更改标题行的颜色。 |
| 所以, |
| 我们还有什么? |
| 脚本监控。 我认为这是我们开发的最好的功能之一,因为这使开发人员能够查看是否 |
| 他们的剧本……他的,他的剧本是否受到赞赏。 正确的。 那么运行了吗? 有人定期运行吗? |
| 这是好处之一。 另一个好处是关于 |
| log...崩溃日志收集。 因此,如果脚本失败,您可以使用 JMP 的日志捕获功能来捕获故障。 因此,您将子例程夹在日志捕获中。 |
| 如果失败...失败...失败的日志将返回到此日志返回文本中。 然后你所做的就是你 |
| 将其包含在尝试中,以便脚本仍然可以进行报告。 |
| 然后你检查它是否为空。 如果它是空的,则意味着根本没有发生崩溃,因此您的脚本得以幸存。 |
| 但如果不是,如果它不为空,则意味着发生了崩溃,并且您将其控制住了。 您可以抓取日志,现在可以报告它。 而实现的方法就是使用HTTP |
| 用户 ID、脚本名称和日志注释,是否崩溃... |
| 无论是崩溃还是只是常规运行,也许还有一些性能指标。 因此,底线是您可以将有关脚本的一些数据元数据传输回开发人员。 |
| 服务器要做的就是记录它们,您将在服务器中存储一组文件,并且可以监视它们。 我只是展示一个示例 |
| 表出这些。 这是一个崩溃日志,其中有......其中有日期戳,它有一个脚本名称,因此该脚本在该日期失败 |
| 与这次特殊的崩溃。 因此这对于开发人员来说非常有用,因为他或她可以返回并解决问题。 所以我将折叠这个和这个,我将在这里做一个快速演示,向您展示如何 |
| 你怎么 |
| 包含崩溃以及如何向用户报告它。 所以我在这里要做的就是让子程序崩溃。 我将创建一个未定义的参数 |
| JMP 会抱怨。 它会说这个东西没有定义,所以脚本正在崩溃。 但我要做的就是调用该子程序 |
| 在日志捕获功能中,所有内容都会夹在尝试下。 因此,尽管脚本因子例程而崩溃,但它总体上会幸存下来,并且能够报告 |
| 崩溃报告。 那么,您是否向用户提供格式良好的通知并说出来。 因此,脚本因这个特定错误而崩溃,我们为其创建了一个日志,并且正在处理它。 这就是您向他们...向用户发出的通知。 |
| 因此,我在峰会上学到的一件重要的事情是关于自动化测试。 所以我过去常常手动进行测试,这非常令人沮丧。 |
| 因为这需要时间,而且您无法捕获脚本的每个角落。 当你做一个小改变时,不可能进行几个小时的测试。 |
| 所以我开始进入自动化测试,进行单元测试非常重要。 所以,你知道,测试是指对单个子程序的测试。 所以你有一个函数并且你想测试它 |
| 在将其放入整个系统之前多次,这样您就可以进行这些单元测试 |
| 对于单个模块,但这还不够。 我可以向您展示几个例子。 |
| 例如,美国宇航局因一次非常奇怪的事件而失去了火星气候轨道飞行器……因为一个非常奇怪的错误,因为有两个软件团队,一个在欧洲, |
| 一个在美国。其中之一是使用英镑单位,是的,这是美国的单位,也是欧洲的单位 |
| 正在使用牛顿。 所以他们当然做了单元测试。 但当他们把代码放在一起时,它不起作用,因为一个期望的是牛顿,另一个期望的是磅。 所以他们实际上失去了 |
| 轨道飞行器,只是因为他们忘记了从磅转换为牛顿。 最近,作为 Starliner,波音公司丢失了他们的 Starliner,然后他们承认,如果他们这样做的话,他们可能会发现这个错误 |
| 严格的集成测试。 归根结底,重要的是 |
| 集成测试,因为模块不是单独存在于脚本中,而是一起对话。 |
| 这是这里问题的一个有趣的说明。 所以你可以有两个经过彻底测试的对象。 这是一扇窗户,对吧,窗户能出什么问题吗? |
| 但是,如果你将其中两个放在一起,它们甚至无法打开,因此你必须进行一些集成测试,看看它们是否组合在一起,是否可以正常工作。 |
| 我想在这里快速说明一下我是如何开始进行自动化测试的。 这将涉及一个特定的情况,即 |
| 公平地说,这是一个困难的情况,因为这将是对模式窗口的测试,除非您单击按钮,否则模式窗口不会消失。 所以你必须 |
| 创建一个单击按钮的 JMP 脚本,这有点模仿人类的行为,我在这里所做的是将测试程序注入到 |
| 模式窗口在这里。 我认为这种方法的好处是你仍然可以分发 |
| 这个东西,这个脚本给你的用户,用户甚至不会意识到其中实际上有一些测试例程。 |
| 所以它有测试仪的钩子,但是当你单独运行它时,它所做的就是寻找这个测试模式参数,但它没有设置。 |
| 因此,如果未设置,脚本会将其设置为零,这将禁用表中的所有挂钩。 因此,您可以将其提供给您的用户,他们可以这样运行它。 |
| 但是,如果您想测试脚本,您要做的就是在其之上构建测试器代码。 因此测试器代码会将测试模式设置为一,并且还将创建测试器...... |
| 您想要注入到脚本中的测试器对象。 例如,在这个特殊情况下,它所做的是选择一个特定的列 |
| 然后它通过单击按钮将其分配给一个角色,然后运行脚本,对吧。 所以这实际上是在模仿人类的行为。 |
| 那么它将加载实际的脚本。 所以它基本上是将这些参数注入到您想要测试的脚本中。 现在您正在自动运行脚本,因此它将加载脚本并运行它,并且在单击此按钮和该按钮后它将关闭 UI。 |
| 然后你要做的就是在日志捕获功能中再次运行它,这样你就知道如果出现问题,你将捕获失败。 |
| 并且您还将它放入了输入尝试中,以便总体而言,脚本能够幸存并报告日志。 然后,如果没有任何问题,您将返回空日志,这意味着您的脚本没有失败。 |
| 如果出现问题,您将在日志捕获中知道。 这就是我们的想法。 |
| 所以, |
| 我们有 |
| 监视脚本的能力。 我们有能力 |
| 捕获崩溃日志。 所以我们想为什么我们不根据崩溃日志采取行动呢? 如果您看到崩溃日志,这意味着出现了问题,并且脚本...用户已经知道,因为脚本显然崩溃了,并且开发人员知道脚本崩溃了,因为日志是 |
| 存储在服务器中。 因此,它们就在那里供您采取行动。 但问题是,这还不是一个闭环,因为用户不知道开发人员知道。 您可以通过创建自动票证来关闭该循环。 既然你已经有了信息,你就可以 |
| 使用错误跟踪软件(例如 JIRA Atlassian),然后您可以使用 REST 功能 |
| 从服务器收集信息,创建票证,将其分配给开发人员,也可以将用户分配为观察者。 观察者意味着每当开发者做任何事情时 |
| 有关错误的信息,并将该信息输入到 JIRA 中,该信息将循环回用户,以便他或她收到通知并知道有人正在处理该错误。 |
| 有多种方法可以做到这一点,具体取决于您所拥有的 JIRA 风格,我只是为您提供 |
| 基本代码在这里。 这是一个您可以创建的curl代码,您可以从崩溃日志中收集元数据,并将其嵌入到JSL文件中,然后它将通过REST传输并进入 |
| JIRA,它将为您进行跟踪。 然后 JIRA 会,如果你设置正确,JIRA 会通知它...JIRA 会通知开发人员,并且可能 |
| 脚本崩溃的用户... 因此,这一切都是联系在一起的,开发人员会知道有一个错误需要他或她处理,用户也会知道有人会处理该错误。 |
| 好的。 我想这让我进入我的结束语。 您可以从本次演示中得到的只是要点。 |
| Git 一直是我们系统的基石,它使我们能够实现许多不错的功能,我什至没有提到基本的功能, |
| 这是显而易见的,因为这也给了你协作的能力。 因此,如果多个人正在编写同一个脚本。 您可以使用该软件的所有功能 |