Dart是否支持参数化的单元测试?

时间:2018-11-01 14:27:08

标签: dart

我想运行一个Dart测试,该测试使用一组输入和预期输出重复进行,类似于JUnit。

我编写了以下测试以实现类似的行为,但问题是,如果所有测试输出的计算均不正确,则测试将仅失败一次:

import 'package:test/test.dart';

void main() {
  test('formatDay should format dates correctly', () async {
    var inputsToExpected = {
      DateTime(2018, 11, 01): "Thu 1",
      ...
      DateTime(2018, 11, 07): "Wed 7",
      DateTime(2018, 11, 30): "Fri 30",
    };

    // When
    var inputsToResults = inputsToExpected.map((input, expected) =>
        MapEntry(input, formatDay(input))
    );

    // Then
    inputsToExpected.forEach((input, expected) {
      expect(inputsToResults[input], equals(expected));
    });
  });
}

我要使用参数化测试的原因是,以便可以在测试中实现以下行为:

  • 只写一个测试
  • 测试n不同的输入/输出
  • 如果所有n测试均失败,则n次失败

1 个答案:

答案 0 :(得分:6)

Dart的test软件包很聪明,因为它并不试图变得太聪明。 test函数只是您要调用的函数,您可以在任何地方调用它,即使在循环或其他函数调用中也可以。 因此,对于您的示例,您可以执行以下操作:

group("formatDay should format dates correctly:", () {
  var inputsToExpected = {
    DateTime(2018, 11, 01): "Thu 1",
    ...
    DateTime(2018, 11, 07): "Wed 7",
    DateTime(2018, 11, 30): "Fri 30",
  };
  inputsToExpected.forEach((input, expected) {
    test("$input -> $expected", () {
      expect(formatDay(input), expected);
    });
  });
});

要记住的唯一重要事情是,在调用test函数时,对main的所有调用应同步发生,因此不要在异步函数中对其进行调用。如果您需要时间在进行测试之前进行设置,请改为使用setUp

您还可以创建一个辅助函数,然后完全删除地图(这是我通常要做的):

group("formatDay should format dates correctly:", () {
  void checkFormat(DateTime input, String expected) {
    test("$input -> $expected", () {
      expect(formatDay(input), expected);
    });
  }
  checkFormat(DateTime(2018, 11, 01), "Thu 1");
  ...
  checkFormat(DateTime(2018, 11, 07), "Wed 7");
  checkFormat(DateTime(2018, 11, 30), "Fri 30");
});

在这里,每次checkFormat调用都会引入一个具有自己名称的新测试,并且每个测试都可能会单独失败。