Skip to content

Conversation

natebosch
Copy link
Member

@natebosch natebosch commented Sep 2, 2020

Towards #1310, #1328

Add directRunTest to configure a reporter and run tests directly in
the same isolate.

Add enumerateTestCases to collect test names without running them, and
directRunSingleTest to run a specific test by its full name. These
APIs ensure the uniqueness of test names to avoid ambiguity. This
restriction may be spread to tests run through the normal test runner as
well.

  • Add fullTestName option on Declarer. When used, only the test (or
    tests if uniqueness is not checked separately) will be considered as a
    test case.
  • Add directRunTest, enumerateTestCases, and directRunSingleTest
    APIs. These are kept under a lib/src/ import for now, and any other
    package that uses these APIs should pin to a specific version of
    package:test_core. The details of these APIs might change without a
    major version bump.

Towards #1310

Open questions:
- Can we make coverage work? How?
- This currently prints full stack traces on failure. Is that OK? Do we
  need to install a top-level zone with an uncaught error handler to
  truncate them?
@jiahaog
Copy link
Contributor

jiahaog commented Sep 8, 2020

Maybe for coverage we could let the user wire that up themselves outside of this function? Another possible approach along the lines of #1310 (comment) could be to expose a args parameter that let users pass the --coverage parameter as needed.

@natebosch
Copy link
Member Author

Maybe for coverage we could let the user wire that up themselves outside of this function?

I think we'll probably need to. @grouma do you have an idea of what type of API we'd want to write to make it easy to trigger coverage collection for the main isolate? This differs a little from our normal approach where we are interested in the coverage from an isolate we spawn and control.

Another possible approach along the lines of #1310 (comment) could be to expose a args parameter that let users pass the --coverage parameter as needed.

I spent some more time thinking about this approach and I don't think it's really feasible. I'll update on the linked issue.

@grouma
Copy link
Member

grouma commented Sep 11, 2020

I think we'll probably need to. @grouma do you have an idea of what type of API we'd want to write to make it easy to trigger coverage collection for the main isolate? This differs a little from our normal approach where we are interested in the coverage from an isolate we spawn and control.

I'm not sure if that is even feasible. To collect coverage you need to provide a service URI. I don't know how the test file would get access to the VM's service URI. I'm also not sure what happens when a VM starts inspecting itself. If a VM can't inspect itself, you may be able to do something super hacky like spawning a detached process to do the inspection. That seems incredibly weird to me though. Finally, I would expect the user would likely have to pass dart --observer <some-test> which also seems quite odd.

@jiahaog
Copy link
Contributor

jiahaog commented Sep 11, 2020

Wouldn't the test file be able to import dart:developer to obtain the service URI? I was able to do this in a Flutter app and call collect from package:coverage, to write the coverage to a file. Could the behavior of the VM inspecting itself be different across other Dart embedders?

@grouma
Copy link
Member

grouma commented Sep 11, 2020

Wouldn't the test file be able to import dart:developer to obtain the service URI? I was able to do this in a Flutter app and call collect from package:coverage, to write the coverage to a file. Could the behavior of the VM inspecting itself be different across other Dart embedders?

I was not aware of this workflow. If this works with Flutter then it will almost certainly work with the vanilla VM. In regards to Nates original question then, the API should probably just mirror that of the --coverage flag. We can provide an optional parameter so the user can specify the output path for the coverage hitmap file. See here.

Add `filterToSingleTestName` to `Declarer`. Any groups or test cases
which do not match the filter will be excluded. This means that any
`solo` use on tests that are excluded will not be honored.

Add `enumeratTestCases` and `directRunSingleTest` APIs.
@natebosch natebosch marked this pull request as ready for review September 23, 2020 23:29
@natebosch
Copy link
Member Author

@jakemac53 @grouma - how do you feel about merging this without tests? I'll keep it in src/ until it's got tests, but I'd like to get this in rolled so we can start prototyping test runners against it.

@natebosch natebosch requested a review from grouma September 23, 2020 23:35
Copy link
Member

@grouma grouma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with landing this as long as we get tests before actually consuming it.

@@ -195,6 +215,11 @@ class Declarer {
bool solo = false}) {
_checkNotBuilt('group');

final fullName = _prefix(name);
if (!(_filterToSingleTestName?.startsWith(fullName) ?? true)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly worth a comment?

I also find the ?? true wrapped in parens and then negated very difficult to parse. I would write a more verbose form.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll need to use ! for the verbose form since it's a field. That's why I wrote it this way originally. I can expand it with the ! though.

/// test a [DuplicateTestNameException] will be thrown.
///
/// Skipped tests are ignored.
Future<Iterable<String>> enumerateTestCases(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we type this as Set instead of Iterable - the contract is guaranteeing uniqueness so I think it makes sense and would avoid some potential copies for users who want a set.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm uncertain when I want to used an ordered collection. As implemented the test names are returned in the same order that they'd be run (without randomization turned on). I don't know if that matters or not, or if it's better to return it as a Set. I'll try Set for now.

@natebosch natebosch changed the title Add directRunTests Add capabilities for building direct test runners Sep 24, 2020
@natebosch natebosch merged commit 5f9fe11 into master Sep 24, 2020
@natebosch natebosch deleted the direct-run branch September 24, 2020 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants