Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Dart support parameterized unit tests?

Tags:

dart

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
like image 358
jsa Avatar asked Nov 01 '18 14:11

jsa


People also ask

What is parameterized unit test?

Parameterized test is to execute the same test over and over again using different values. It helps developer to save time in executing same test which differs only in their inputs and expected results. Using Parameterized test, one can set up a test method that retrieves data from some data source.

What is dart in testing?

The dart test command runs tests that rely on the test package and are under the test directory of the current Dart project. For information on writing tests, see the testing documentation. If you're working on Flutter code, then use the flutter test command instead, as described in Testing Flutter apps.

How do you test a dart file?

A single test file can be run just using dart test path/to/test. dart (as of Dart 2.10 - prior sdk versions must use pub run test instead of dart test ). Many tests can be run at a time using dart test path/to/dir . It's also possible to run a test on the Dart VM only by invoking it using dart path/to/test.


1 Answers

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.

like image 87
lrn Avatar answered Sep 18 '22 14:09

lrn