发布于 2026-01-06 0 阅读
0

走向开源——深入了解 Facebook 的 Jest 项目。什么是 MLH Fellowship?它与其他开源项目有何不同?Jest 是什么?特别收录:报告单个测试用例 #10227。最后,总结一下……DEV 全球展示挑战赛,由 Mux 呈现:展示你的项目!

走向开源——深入了解 Facebook 的玩笑

MLH奖学金是什么?

它与其他开源程序有何不同?

什么是玩笑?

功能:报告单个测试用例 #10227

那么,总结一下……

由 Mux 主办的 DEV 全球展示挑战赛:展示你的项目!

作者

MLH奖学金是什么?

MLH奖学金
MLH Fellowship 为软件工程师提供了一种实习替代方案,专注于开源项目。学生们无需为单一公司工作,而是为全球企业使用的开源项目做出贡献。这是一种在家就能获得真实软件开发经验的绝佳方式。开源社区非常乐于助人,鼓励新开发者积极参与其中。参与者可以拓展视野、检验技能、积累知识,并与社区建立联系,共同编写高质量的代码,造福世界各地的人们。

它与其他开源程序有何不同?

项目伊始,学员们会被分成若干个小组,称为“小组”(pods),在专业软件工程师的指导下,以团队形式共同完成分配的项目。除了工作之外,该项目还提供拓展人脉和享受乐趣的机会!学员们有机会接触最新的开源技术,并根据自身技能和兴趣匹配合适的项目,从而在参与真实项目的同时获得学习机会。但这并非仅仅是编程。除了技术实践工作坊之外,MLH还会定期组织软技能和团队建设活动!这是一个远程项目,但它为学员们提供了一个展示技能的全球平台。在项目期间,我们参与了Facebook/Jest项目。

什么是玩笑?

笑话
这就是我们在项目开始时获得的机会。我们欣喜若狂,终于得到了这个项目!

Jest 是一个 JavaScript 测试框架,旨在确保任何 JavaScript 代码库的正确性。它提供了一个易于使用、熟悉且功能丰富的 API,让您能够快速编写测试并获取结果。Jest 文档齐全,配置简单,并且可以扩展以满足您的需求。Jest 让测试变得轻松愉快。

我们从哪里开始?

  • 在为任何开源项目做贡献之前,你必须先使用它。如果你不了解项目的功能,就很难做出贡献。我们就是这样起步的。我们用 Jest 为我们之前开发的应用程序编写测试。
  • 在MLH项目第一周结束后,我们与Jest的贡献者们举行了一次会议,以便更好地了解分配给我们的任务和项目的路线图。这是一次富有成效的会议,帮助我们深入了解了项目。如果您在参与任何开源项目时遇到困难,强烈建议您与贡献者们联系。您可以通过邮件列表与社区成员沟通。
  • 下一阶段是了解项目的运作方式。这周我们深入研究了 Jest 的代码库。文档和会议演讲在这个过程中非常有用。由于你是项目新手,所以最好为未来的贡献者提供一些指导,帮助他们更好地参与,就像我们写这篇博客一样!熟悉项目的另一种方法是调试工作流程,并在讨论中做笔记,以便进一步研究。至于如何开始贡献,建议新手先从一些适合初学者的问题入手。这不仅能帮助你快速上手,还能让你熟悉贡献指南。

我们需要精通 Jest 才能做贡献吗?🤞

  • 你不需要成为专家才能参与开源项目。即使你是新手,也一定能找到一些项目来帮助你提升技能,获得真实的软件开发经验。如果项目本身存在学习曲线,就像我们当初开发 Jest 时一样,那也是一件好事,因为这样你就能在贡献代码的同时学习知识。
  • 如何理解如此庞大的代码库?其实你不需要理解。项目被拆分成多个独立的包,方便你浏览和探索代码库。你可以大致了解工作流程,并在需要时深入研究各个包,为它们做出贡献。为此,你可以查看 GitHub 仓库的 issues 部分,并筛选出易于上手的问题。当然,如果你遇到任何问题,社区随时为你提供帮助!

好的,我知道bug/功能提案的内容了。我该从哪里开始修改呢?🤔

  • 首先,你需要创建一个 issue。你的 issue 应该描述清楚,并解释其背后的动机。如果你请求添加新功能,你应该说明这个功能是什么,如何实现它,以及它为什么重要。如果你的 issue 与修复 bug 相关,你应该说明如何重现这个 bug,它导致了哪些变更,以及预期行为应该是什么。你应该详细解释你想要实现的目标以及如何实现它。向社区成员征求反馈意见,以获得更多见解。
  • 编写文档至关重要,因为它能帮助其他人更好地帮助你。如果你已经知道如何解决问题,可以为此提交一个 pull request。文档在这里同样重要。你应该说明你做了哪些更改以及原因,你遇到了哪些问题以及你是如何解决的,以及你所做的更改是否会影响现有代码库。记住,别忘了在日志中添加一行记录!

测试运行的工作流程🚀

我认为 Kunal 的这篇文章很好地诠释了Jest-architecture 的理念。

社区的重要性👥

开源

  • 在你的开源之旅中,社区将扮演至关重要的角色。社区存在的唯一目的就是让所有人的协作和学习更加便捷。这使我们能够创造出被世界各地的人们使用和贡献的软件。对于初学者来说,与社区的互动在大多数情况下都能为你提供帮助。当你遇到难题、需要就某个特定主题获得更多意见和建议,或者希望你的 PR 得到审核时,社区成员会为你指明正确的方向,因为他们对项目了如指掌。你的同伴也是你前进的重要动力。以我们之前的结对编程/调试为例,它帮助我们更快更高效地解决了 bug(稍后会详细介绍)。

如何提问和请求反馈

问题

  • 聊天时别只打个招呼!这一点非常重要。每个人都很忙,包括你。所以请在讨论频道里提出你的问题,尽量简短明了。记得@合适的人(先看看频道规则)。
  • 尝试向对方提供链接或简明易懂的问题描述。这样可以提高你的问题获得更多关注并更快得到解决的几率。
  • 与其问一个冗长的问题,不如问十个简短的问题(但不要太短)。问简洁的问题有助于对方更快地得到答案,因为与一个冗长的问题相比,理解文本上下文所需的时间更少。
  • 这引出了另一个重要的观点:尽可能将大型 PR 拆分成较小的 PR!强烈建议这样做,因为它有助于审核人员以更简化的方式理解变更,而这种流程分解有助于进行有效的讨论和反馈。
  • 请在邮件中详细描述重现错误的步骤,以便其他人了解您遇到的问题。同时,请说明您尝试过的解决方法以及最终结果,以避免重复回复和类似“我已经试过了”之类的回复。
  • 在做出贡献时,寻求反馈至关重要。请以清晰明确的方式展示您的工作,以便清楚地说明您的目标。这包括提供您所做的更改以及这些更改如何影响代码功能的信息。
  • 代码可读性也非常重要。必须遵循组织规范,在必要时添加注释。
  • 如果没立即得到回复,请不要频繁刷屏。请耐心等待一段时间后再再次提问。

至此,开源贡献指南就结束了。接下来,我们将深入探讨我们是如何解决问题的,以及一些关于 Facebook Jest 项目的建议。


新增功能:报告单个测试

功能:报告单个测试用例 #10227

概括

  • [第 2 部分(共 2 部分)] - 依赖于 #10293
  • 最初,Jest 运行会testSuites以增量方式更新,并分批更新各个测试用例。此 PR 尝试报告各个(原子)测试用例的进度。
  • 支持 Jest-Circus Runner。
  • 引入此功能eventListeners,使工作进程能够将测试结果发送回其父进程。
  • 能够处理并行运行测试(生成工作线程)和按顺序运行测试时的进度报告。

先前的参考资料和建议

测试计划

当前实施情况

实施演示

作者

合著者 - Saurav M. H @sauravhiremath 合著者 - Kunal Kushwaha @kunal-kushwaha 合著者 - Rogelio Guzman @rogeliog

致谢

感谢 @kunal-kushwaha 的精彩贡献 🚀 🚀 感谢 @rogeliog 为这个 PR 奠定了基础。 🚀 感谢@SimenB 和@jevakallio抽出时间并撰写评论 👏

  • 有时,为了引入新功能,你需要遍历大部分子仓库,这可能会让你感到不知所措。这种情况在单体仓库项目中很常见。在这种情况下,绘制一个简略的图表或流程图,以便你清楚自己在做什么,避免迷失在庞大的项目中。
  • 好吧好吧,我们这里有个小小的优势。问题已经被发现了。我必须强调,一个定义明确的问题与它的解决方案同样重要。

问题:

  • 目前看来,Jest 似乎只在整套测试用例全部通过时才报告进度。我们建议改为每秒报告一次各个测试用例的进度。(其实我们已经改进到比每秒报告更精确的程度,稍后会详细介绍)
  • 否则,进度输出会令人困惑。“测试:N”作为单独一行显示在输出中,会给人一种错觉,认为它与“测试套件:N”一样细粒度,并且会在测试用例通过时立即递增。
  • 所以,单看题目本身就可能令人困惑。而且,你肯定也知道,仅仅阅读上面的描述是不够的。因此,这里附上一张解释性图片。

问题-gif

解决方案

将问题分解为不同的功能

  • 支持从工作线程向父线程发送自定义消息
  • 汇报各个测试用例的进展情况

支持从工作线程向父线程发送自定义消息

  • 它增加了jest-worker工作进程在运行时向其父进程发送“自定义消息”的功能。最终,这将使我们能够向报告者报告每个测试用例的更新。
  • 这部分尤其棘手,因为有一些遗留代码,处理起来非常令人困惑(这在大型代码库中很常见)。
  • 利用 Nodev10 中引入的 eventEmitters(emittery它是 node eventEmitters 的类型化形式)来发送消息,而不是使用传统的回调。
  • 该发射器仅用于并行运行(支持工作线程)。对于带内运行,则无需进行太多修改。
  • 本次 PR对模块的大部分内容jest-worker进行了修改,并且没有造成任何破坏性变更。

汇报各个测试用例的进展情况

  • 拟实现的功能:
    • 最初,Jest 运行会增量更新测试套件,并批量更新各个测试用例。此 PR 尝试报告各个(原子)测试用例的更新进度。
    • 仅支持jest-circus跑步者。
    • 引入事件监听器,使工作进程能够使用事件监听器将测试结果发送回其父进程。emittery
    • 能够处理并行运行测试(生成工作线程)和按顺序运行测试时的进度报告。
  • 如果没有相应的演示,该提案是不完整的。拟议功能演示

发现漏洞是一次学习机会——内存泄漏

  • 我们是怎么找到它的?

    • 幸好 Jest 内置了内存泄漏测试。它本质上是创建对象的浅拷贝,然后删除所有指向该节点的引用(或边)。(这里我指的是全局对象堆上下文中的节点。)如果该对象仍然没有被垃圾回收,则意味着存在内存泄漏,因为还有其他对象在引用它。这就是内存泄漏的检测原理。幸运的是,我们不必手动编写这段代码,已经有人为此开发了一个 npm 模块。
  • 我们尝试了哪些方法,持续了多久?

    • 哎呀!这部分最让人头疼。光知道内存泄漏的原理还不够,我们没办法调试。一开始,我们尝试手动查找代码库中任何低级错误,但一无所获。
    • 接下来,我们在运行测试的同时,每隔一段时间进行内存快照。这里我们以带内方式运行测试,这样更容易了解问题出在哪里。
    • 然后我们分析了这些照片,试图从中找到有用的信息。但一无所获。
    • 我查看了测试的堆内存日志,但也没有发现任何异常情况。
    • 现在,我们采用了这本食谱中最古老的配方,这是大厨们推荐的。破解秘方!(感谢@taneliang发现了这个隐藏的配方)
    • 我们开始逐段删除代码,看看是哪一部分导致了问题。这是我们最后的办法,我们从我们认为最容易出现内存泄漏的地方开始着手。瞧!我们找到了!
  • 我们是如何解决这个问题的?

    • 我们发现问题出在将对象的直接引用发送到了工作线程。即使工作进程被孤立,它仍然持有该对象引用。因此,我们通过创建一个深度循环复制(这是一种比较专业的说法,指的是对可能存在循环引用的对象进行深度复制)并将其再次发送到工作线程来解决这个问题。结果,成功了!
    • 只需一行代码就能解决。仅仅一行!
sendMessageToJest = (eventName, args) =>
    this.eventEmitter.emit(
      eventName,
      deepCyclicCopy(args, {keepPrototype: false}),
    );
Enter fullscreen mode Exit fullscreen mode

哦不

  • 我们学到了什么?
    • 但是,找到这条线索却是我们最棒的旅程之一。我们从中学到了很多关于……
      • Chrome v8 堆积。
      • 内部如何处理垃圾回收。
      • Node 如何维护不同的堆以及它所创建的工作线程之间的相互引用?
    • 以下是我们修复这个漏洞时学到的一些东西。

那么,总结一下……

耶!你居然熬过了书呆子博客!来,吃块饼干🍪

另外,我们并非专家,我们的工作也并非完美无缺。我们只是几个朋友分享经验而已。您可能同意或不同意我们的一些观点。这完全没问题,我们尊重您提出的问题。这只是我们走过的一条路,您可以沿着这条路走,也可以找到自己的路。两条路都有各自的乐趣和挑战 :)

事情大概就是这样。我们就这样从一个从未参与过的项目起步,并在项目期间成功推出了一项新功能。衷心感谢所有社区成员、MLH项目团队以及所有参与这段旅程并激励大家取得更大成就的人。

感谢阅读。
愿源头与你同在

作者简介

关于库纳尔:

大家好!我叫Kunal,来自印度,是一名大三学生。我的兴趣包括DevOps、机器学习和Web开发。我曾参与过多个开源项目,例如MLH Fellowship、Google Summer of Code和Google Code-I等等。工作之余,我是多个大学社团和编程训练营的核心成员,负责教授学生数据科学和DevOps。我还在自己创建的社区(codecau.se/yt)担任志愿者讲师,目前有数千名学生在我们这里学习。
从大一开始,我就积极参与开源项目,这对我未来的职业发展产生了深远的影响。我的目标是参与开发能够对世界产生影响的产品和服务。因此,我非常希望能加入一家引领行业未来的公司。

关于 Saurav:

一位来自印度的友好邻居开发者:DA,计算机科学工程专业学生,主修生物信息学。我热爱DevOps和全栈Web开发。我拥有为初创公司设计产品和平台架构的经验。我曾参与技术研讨会,并就深度学习和产品部署发表过演讲。我是开源社区的坚定拥护者。目前我是MLH Fellowship的成员,并已为开源软件贡献了两年。
我的工作始终致力于让人们的生活更轻松,并打造能够带来改变的产品。总而言之,我热爱我的Arch Linux和开源软件 :)

文章来源:https://dev.to/sauravmh/going-opensource-a-dive-into-facebook-s-jest-cgb