简体   繁体   中英

Does Dart support parameterized unit tests?

I would like to run a Dart test which is repeated with a set of inputs and expected outputs, similar to what is possible with JUnit.

I wrote the following test to achieve similar behavior but the problem is that event if all the test outputs are computed incorrectly, the test will only fail once:

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));
    });
  });
}

The reason I want to use parameterized tests, is so that I can achieve the following behavior in my test:

  • Write only one test
  • Test n different inputs/outputs
  • Fail n times if all n tests are broken

Dart's test package is smart in that it is not trying to be too clever. The test function is just a function that you call, and you can call it anywhere, even inside a loop or another function call. So, for your example, you can do something like:

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);
    });
  });
});

The only important thing to remember is that all the calls to test should happen synchronously when the main function is called, so no calling it inside asynchronous functions. If you need time to set something up before running the test, do so in a setUp instead.

You can also create a helper function, and drop the map entirely (this is what I usually do):

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");
});

Here each call of checkFormat introduces a new test with its own name, and each of them can fail individually.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM