添加第一个练习


每个学习路径上的第一个练习都是一个非常简单的“Hello, World!”练习。

这个练习的目的,是快速确认所有部分都正确连通。它会验证用户是否正确安装了编程环境、是否知道如何运行测试,以及能否让测试通过。除此之外,对于 Exercism 命令行客户端(CLI)来说,它还能确保用户已正确安装并配置了 CLI,并确保网站为练习下发正确的文件,而不附带任何多余的产物。最后,它还能让用户熟悉这样一个循环:用 CLI 下载练习,在本地开发环境中解题,再把解答提交回网站。

换句话说,此时还谈不上学习这门语言本身。我们的目标就是做到极简。

这也可能是正确搭建学习路径仓库的过程中最难的部分,因为实现一个练习涉及很多环节。

实现练习

“Hello, World!”练习有一些特殊的规则:

  • 它始终是学习路径中的第一个练习
  • 每个学习路径都必须实现它
  • 测试文件只有一个测试
  • 存根文件里是一个几乎可用的实现,但它用的不是“Hello, World!”,而是“Goodbye, Mars!”
  • 它没有prerequisites
  • 它没有practices

确定文件路径

“Hello, World!”练习(其实 Exercism 上的_所有_练习都是如此)需要一组特定的文件:

  • 文档:向学员说明需要做什么(可以自动生成)。
  • 元数据:向 Exercism 提供练习的一些元数据(大部分可以自动生成)。
  • 测试套件:检验解答是否正确(学习路径专属)。
  • 存根实现:为学员提供一个起点(学习路径专属)。
  • 示例实现:提供一个能通过所有测试的示例实现(学习路径专属)。
  • 附加文件:确保测试能够运行(学习路径专属,可选)。

在创建“Hello, World!”练习之前,你需要先决定学习路径专属的文件名和文件路径(测试套件、存根实现、示例实现以及任何附加文件)。

经验法则是:使用符合该语言习惯的名称。如果没有特别强烈的偏好,就优先选择层级较浅的目录结构。示例实现需要能被 CI 脚本识别出来,所以最好选一个所有练习都能通用的基础文件名,例如example、sample或reference-solution。

配置文件路径

选定学习路径专属的文件路径之后,你应该在根目录config.json文件的files键中配置它们。files键会作为所有练习的模板,这样任何工具(稍后我们会用到其中一些)都能知道去哪里找文件。你可以使用各种占位符,方便地配置练习的 slug(这里是hello-world)。

示例

如果你的学习路径使用 PascalCase 命名文件,files键可能长这样:

"files": {
  "solution": [
    "%{pascal_slug}.cs"
  ],
  "test": [
    "%{pascal_slug}Tests.cs"
  ],
  "example": [
    ".meta/Example.cs"
  ]
}
Note

示例文件应存放在.meta目录中。

更多信息请查看files键文档。

创建文件

指定好文件路径模板之后,你就可以在学习路径的根目录下运行以下命令,快速搭出“Hello, World!”练习的文件:

bin/fetch-configlet
bin/configlet create --practice-exercise hello-world

设置作者

想让网站把你列为练习的作者,请按以下步骤操作:

在练习的.meta/config.json文件中:

  • 把你的 GitHub 用户名添加到authors键中

要让它生效,你需要把 Exercism 账号关联到 GitHub。你可以在网站的设置页面的集成部分完成。

Note

练习作者还会获得声望

使用脚本

较新的学习路径仓库可以使用bin/add-practice-exercise脚本(源码)来添加新练习:

bin/add-exercise -a <github_username> two-fer
Note

如果你正在处理的学习路径仓库没有这个文件,可以随意通过上面的源码链接把它们复制到你的仓库里。

完成练习实现

搭好脚手架文件之后,你还需要:

  • 往测试文件里添加测试
  • 添加示例实现
  • 定义存根文件的内容

添加测试

添加练习的关键一步就是添加测试。大致来说,实现上述练习时有两种选择:

  1. 从零开始实现测试,用练习的canonical-data.json里的测试用例
  2. 从另一个学习路径的实现中移植测试(小提示:打开https://exercism.org/exercises/hello-world,看看哪些学习路径已经实现了这个练习)。

对于“Hello, World!”练习来说,只会有一个测试用例,所以两种方式都可以。

添加示例实现

示例实现文件中应该包含让测试通过所需的代码。

定义存根

存根文件里应该有一份_几乎_能通过测试的解答,只是要把“Hello, World!”这段文本换成“Goodbye, Mars!”。小提示:直接把示例实现复制过来,稍作修改即可。

更新练习的作者

完成练习后,请把你的 GitHub 用户名添加到练习的.meta/config.json文件的"authors"数组中。这样我们就能正确地把你记为练习的创建者。

代码检查

要验证练习配置是否正确,可以使用 configlet 工具内置的代码检查功能。

第一步是获取configlet工具,为此我们准备了两个脚本:

  • bin/fetch-configlet:在使用 *nix 或 macOS 时运行
  • bin/fetch-configlet.ps1:在使用 Windows 时运行

在学习路径仓库的根目录下运行其中一个脚本,就会下载bin/configlet或bin/configlet.exe可执行文件。

然后你就可以运行bin/configlet lint来检查练习是否正确。

Note

configlet很可能会报告下面这个错误:

The `tags` array is empty:
/path/to/track/config.json

这个错误会在准备发布这一步中修复,所以你可以:

  • 暂时忽略这个错误,或者
  • 通过添加标签来修复这个错误
Note

只要有内容被推送到main或发起拉取请求,configlet工作流就会自动运行configlet lint。