在 Fortran 赛道上测试

学习如何在 Exercism 上测试你的 Fortran 练习


每个练习都会提供单元测试和一份 CMake 构建配方。你需要提供实现。 每个测试文件都会链接到你的实现,生成一个运行测试的控制台可执行文件。运行测试可执行文件时,会为每个失败的测试打印消息,并在测试失败时报出非零的退出状态。

测试文件的名称是<exercise>_test.f90,所以对于练习“Bob”,包含测试的文件是bob_test.f90。每个测试都会有一段注释来描述该测试,然后是实际的测试,以call assert_equal开头,例如:

  ! Test 16: non-letters with question
  call assert_equal("Sure.", hey(":) ?"), "non-letters with question")

要禁用某个测试,只需用'!'把它注释掉,例如:

  ! Test 16: non-letters with question
  ! call assert_equal("Sure.", hey(":) ?"), "non-letters with question")

逐个完成每个练习的过程是:

  • 用 CMake 创建初始构建
  • 对每个单元测试:
    • 解决编译错误,让测试能够失败。
    • 只实现刚好足以让测试通过的部分。
    • 重构你的实现,以提高可读性、减少重复等。
    • 取消注释下一个测试

用 CMake 创建初始构建

每个练习都会随单元测试一起带有一个CMakeLists.txt文件。其中包含现成的 CMake 配方,替你处理构建。你应该不需要编辑这个文件。提供的配方假定你的实现位于一个以练习命名的源文件中。

例如,练习“Bob”期望实现位于bob.f90文件中。

在运行 CMake 之前,先创建初始的实现文件。 如果在为练习“Bob”运行 CMake 时没有bob.f90文件,CMake 会报出找不到文件的错误。 这些文件可以是空的,但必须存在。

使用这份配方,CMake 可以通过cmake -G加上合适的生成器和练习目录的位置,为你的环境生成一个合适的项目。CMake 会生成适合你的操作系统的构建脚本。为了让这些生成的文件与练习的源代码分开,通常的做法是创建一个名为build的目录,用来存放这些生成的构建文件以及编译后的代码。

这样能让你的练习文件夹保持整洁清爽。

**注意:第一次调用cmake时,会自动下载 testlib。单元测试需要testlib才能正常工作。

由于每个练习你都要运行 CMake 来生成构建指令,你可能想为这条命令创建一个 bash 脚本(Linux/MacOS)或批处理文件(Windows)。

一旦 CMake 创建好构建环境,你就可以用适合你的环境的命令来构建代码:

  • Linux 搭配 make:make
  • Windows 搭配 Visual Studio:从菜单中选择 Build / Build Solution。
  • Windows 搭配 MingW:mingw32-make.exe
  • Windows 搭配 nMake:nmake.exe
  • MacOS 搭配 Xcode:从工具栏中选择 Build

下面展示了在不同环境中运行 CMake 的示例。

Linux\MacOS 搭配 Make

CMake 的生成器名称是Unix Makefiles。 假设当前练习是bob,而我们正处于练习文件夹中:

$ touch bob.f90
$ mkdir build
$ cd build
$ cmake -G "Unix Makefiles" ..
$ make

这个示例展示了在运行 CMake 之前先创建空的实现文件。

只需在 build 目录中输入 make 来编译测试。这应该会产生编译期错误。修复这些错误后,再次运行make。当所有构建错误都修复后,运行测试:

$ ctest -V

Windows 搭配 Visual Studio 2017

CMake 的生成器名称是Visual Studio 15。同一个生成器支持 Visual Studio 2017 的所有 IDE 版本:Community、Professional 和 Enterprise。假设当前练习是bob,而我们正处于练习文件夹中:

> copy nul: bob.f90
> mkdir build
> cd build
> cmake -G "Visual Studio 15" ..

这个示例展示了在运行 CMake 之前先创建空的实现文件。

Windows 搭配 MingW

CMake 的生成器名称是MinGW Makefiles。假设当前练习是bob,而我们正处于练习文件夹中:

> copy nul: bob.f90
> mkdir build
> cd build
> cmake -G "MinGW Makefiles" ..

这个示例展示了在运行 CMake 之前先创建空的实现文件。

只需在 build 目录中输入 make 来编译测试。这应该会产生编译期错误。修复这些错误后,再次运行make。当所有构建错误都修复后,运行测试:

MacOS 搭配 Xcode

CMake 的生成器名称是Xcode。 假设当前练习是bob,而我们正处于练习文件夹中:

$ touch bob.f90
$ mkdir build
$ cd build
$ cmake -G Xcode ..

这个示例展示了在运行 CMake 之前先创建空的实现文件。

只需在 build 目录中输入 make 来编译测试。这应该会产生编译期错误。修复这些错误后,再次运行make。当所有构建错误都修复后,运行测试:

$ ctest -V

Testlib

测试依赖一个名为testlib的小型库,它会在第一次用 cmake 配置构建时从 github 下载。

如果下载失败,也可以手动下载,例如:

mkdir testlib
cd testlib
wget https://raw.githubusercontent.com/exercism/fortran/master/testlib/CMakeLists.txt
wget https://raw.githubusercontent.com/exercism/fortran/master/testlib/TesterMain.f90