-
Notifications
You must be signed in to change notification settings - Fork 218
Add a more precise way to start multiple specific tests at the same time #1598
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is somewhat a limitation of the This doesn't have to be a particularly ergonomic thing to use since I think its mostly only useful for automated tooling, so that also makes things a bit easier. One idea would be to use the uri fragment to indicate the name, something like |
I agree, your syntax proposal sounds good to me. So can I work on adding such feature? |
I do think we should validate this will really give you the UX you desire first, and we don't need a more general feature. For instance, how would you want to handle the case where a new test case is added, or a test case is renamed or deleted? |
If a "exact_test=..." clause doesn't match a test (such that when a test is deleted), I'd expect nothing to happen I wouldn't expect this flag to deal with "execute new/renamed tests". If folks want to execute the renamed/new tests, we could rely on the analyer to detect |
Ultimately what I am implying here is that what we really need is something I have wanted for a long time - an interactive mode for the test runner, intended for use by tools. That would want to be able to do a lot more than just run a specific test and get test results. I have a strong hunch that if we add this feature, we will end up wanting to add a whole bunch of other related features for all these other scenarios. And ultimately its probably better to design a whole new test command which is specifically designed with interactive tooling at top of mind, and all the various scenarios that would entail.
This does indicate something going awry though and it generally goes against our existing behavior which is to fail if no tests are ran. We probably would want to at least explicitly communicate that no test was found somehow.
But I think your general tool probably does want to deal with that? People probably do want new tests to be ran, since they might be failing. Or at least that would be one of the user experiences you probably want to support?
I do agree there would be user value extracted from just this simple feature, and not handling the edge cases. But we also have to design features with the long term in mind since we very rarely make breaking changes. That isn't to say I don't think we should do this, just that we should make sure it still makes sense in the bigger picture and for the long term. |
I understand where you're coming from. But if we're making a wish-list, I think it'd be ideal to offer a Dart API to manipulate It could be useful to be able to do something like: void main() async {
List<Suite> suites = await getSuites();
List<Test> tests = suites.expand((suite) => suite.tests).where((test) => <custom test filter>);
await runTests(tests);
} Although that's a different project.
Yes but as I mentioned, I'd expect the But in general I wouldn't worry to much about it. The "don't execute new/renamed tests" behaviour is how Jest works, and it's a good experience. Supporting new/renamed tests would be for a different kind of filter, like file/name filters or Jest's git filter – which only executes tests impacted by the uncommited git diffs. But the filter is at the suite level, so the existing file filter is enough. |
@natebosch wdyt? Note we have similar but I think not overlapping discussions in #1579, where I proposed a similar solution. We will want to at least make sure these can be compatible (but I think that won't be an issue, they would use different option names). |
I don't think we'll ever be in a place where I think putting a test name in the URI fragment is probably an OK approach, but it does seem like it has drawbacks.
We could consider using line numbers, or even an opaque ID that we control completely, if we want to support the use case even more directly by owning the translation from failure to test identity. Naming would need some thought, but as a strawman we could add flags like |
What sorts of drawbacks? |
Mainly that it's hard to get right. Characters need to be URI escaped and the vast majority of test cases will have spaces. We could instead say we aren't using a URI fragment, but just a In any case, my intuition is that round tripping a test ID which we own 100% may be less brittle than defining a scheme that needs to be maintained backwards-compatible for a long time. |
We would just be talking about a small number of tools (not package:test users) using this option. So I don't think its much of an issue to require the fragment be properly encoded.
We can't make a stable test ID afaik though in the face of new tests being added and such, unless we also base it off the name. So I don't really see what it buys us? But we could give the user a URL safe ID in the json protocol for each test, and then require them to pass that for the fragment instead? |
Owning the definition of the file format would leave some room for adding more understanding of how tests change over time.
Yeah I think no matter what we need some way for users to have us tell them exactly what IDs would work (assuming the test cases also remain stable) including whatever URI escaping needs to happen. Whether that's in the JSON protocol or somewhere else should be fine. |
I'm not fond of using IDs, because that eliminates the possibility for users to use this filter option I could see myself using the "exact_test" proposal without passing by a tool. I more than once had to comment the other tests in a file besides one specific test because |
Note that we do accept regex for |
I'd be interested in something like this too. VS Code's new test runner lets a user multi-select a bunch of tests and run them, and today I had to make this split them by file and run multiple debug sessions to pass the names - which is a lot slower than running them all in a single process (not to mention clumsy for some other reasons, like if the user hits Stop on the debug toolbar it only stops one of them). VS Code currently only uses regexes, though there's been talk of supporting line/col in another issue - if something was added, it could be nice to support both of those (since in the short-term, VS Code will likely continue to use names, but would probably migrate to line/col). On the subject of an interactive/server process, it may be worth keeping an eye on microsoft/vscode#134455. VS Code has a new test runner and it seems to me like it would make a nice "Test Adapter Protocol" similar to LSP/DAP that could be run out-of-process and communicated with via JSON. LSP and DAP both have gotten good traction, so a common interface that other languages/editors might use could be a better option than something completely custom. |
On that note, is there anything I can do in the short term? I originally wanted to fork |
From my perspective here I would be happy with the |
@jakemac53 is it possible to support regex too? VS Code always uses regex right now (because it might be trying to run tests named |
(and by that I just mean a single regex for the file, since I'm already building a regex that covers all names like |
Alternatively would it make sense to try and fix the limitation of |
I don't think so, it is following pretty well established conventions for how command line options work. Options only accept a single value (not potentially multiple). Generally ordering of options is also not supposed to matter. |
There is a precedent though: dart pub global activate --source path <path-to-source> where edit actually I'm not sure. Thinking about it, I never tried to use the command with different combinations |
Fwiw I am always super confused by the way that |
Coming back to this, why would the test name be URI encoded? I suppose you meant Is there a special reason? |
There could be symbols in there that need to be encoded or else they would have other meaning in bash etc such as |
Oh interesting, I didn't know we could do But if we encode the test name, wouldn't this hinder the ability to use regex as name as @DanTup wanted? |
I don't think the encoding affects using regex or not. There may need a way to distinguish what is/isn't a regex, but I think the encoding is just to ensure the arguments parse correctly (and aren't tripped up by the wonderful characters people like to put in their test names - which FWIW can include newlines :-) ) Perhaps one option would be to use the query string:
This might also work nice for line/col as discussed previously:
(with all the correct URI encoding, ofc) |
Using the query string does afford us a lot more flexibility and allow us to solve these identical issues with a common solution so I think that is great. Should we just allow query strings on general file names, so they are passed as rest arguments and not via an extra option then?
|
I presume you mean so we can do:
? It might be a bit strange for cases where there's some relationship between them:
Although if the rules are clear and we could also pass them as separate URIs if it didn't fit the needs, sgtm :-) |
I don't quite understand why passing multiple name/lines in the same --exact-test flag is desirable, since we can pass the flag multiple times |
If they perform an |
SGTM. I also agree that having multiple |
STGM to amend the proposal to allow multiple values for |
@natebosch thoughts on the above #1598 (comment)? |
It occurs to me that we also need to define how these options interact with the global options. I think I would say the global options also must match. So they are respected as well, and these file level filters apply to the results left over after the global filters. |
I would expect this option to be incompatible with others So that if you specify --exact-test, the command fails if you specify files or other options |
Note that my updated proposal removes this argument - it just adds query parameter support to the existing file path arguments which are just I think we do want to support the other global arguments still, it shouldn't add much complexity (actually may even be simpler in some ways). |
If you mean It may be nice to print a good message when no tests match that describes how the conditions were applied, to make it obvious. |
Oh, I didn't realise that the syntax changed. I see, then |
Would this be considered as a breaking change though? As file paths could technically contain Someone could name a file "foo.dart?name=42" 🤷 |
That should be uncommon enough for us to not consider it breaking? Granted people do weird things...but that would be very weird, especially in a dart file path. |
This proposal LGTM overall. We could also consider allowing the abbreviated argument flags
We aren't proposing to implement this today are we? I think we'd implement support for the name regex and full string matching now and leave space for new query types in the future.
We could also have a fallback if the argument can't be parsed as a URI to check if it exists as a file path. I think the only way we'd change existing (passing) behavior is if you happen to have a file path with a |
We could wait, but we have another open issue to support that so we could roll it into the same release imo. |
I do think if you use this approach the full argument should be URI safe, not just the query string. It would mean on windows you'd need to use |
That's fine if we can get them both done, but I wouldn't gate one on the other. |
@rrousselGit were you still interested in taking a shot at implementing this? |
|
Definitely. Although I don't really care about line/col options for now. I'm only after the name/full_name variants |
That is fine, if you wanted to just implement the name/full_name variants we can follow up with line/col later |
As for the implementation, I suppose it involves modifying |
Essentially yes, the paths should now be It might be a little bit funky to pass the extra information along, you might want to merge it into the SuiteConfiguration object that is created for each suite ( |
Ya it looks like you could just use the existing |
Coming back to this, I may be missing something but it seems like We have to do: dart test "test/my_test.dart?name=foo" |
Other than that, I think I got it to work. I'll raise a PR, but I'm not familiar with how to write tests for it. |
FWIW, I'm not desperate for line/col either so also won't hold this up for it. It would allow me to handle some edge cases better when users have duplicate names, but since we're not supporting them in the tree, I'd generally encourage users not to have them (I used it as an example above just to highlight some benefit of using a querystring).
I'm not very familiar with it, but I guess there's some sort of shell expansion going on? For tools this probably isn't an issue (eg. when you spawn a process from Dart or nodejs, you pass an array, and each item should come through normally to the program). I think it's probably reasonable to expect users to quote/escape things correctly if doing this themselves in a shell? |
Ya it doesn't surprise me you would have to explicitly quote it, a bit annoying but 🤷♂️ |
Hello! Some context:
I am working on a custom test renderer and I was trying to implement "execute only failed tests from the previous run" among other things.
I was able to get the list of failing tests, with their suites and names/ids. But I haven't found a way to start them all at the same time while skipping the rest
I was innocently thinking that we could do:
to run the test "a" from
foo_test
and "b" frombar_test
, but this isn't the case because of various issues:--name
filters aren't specific to a test file.--name
queries are defined, they perform an AND filter instead of an OR filterSo
--name "hello"
will run bothtest('hello', ...)
andtest('hello world', ...)
As such I think thinking: Would it be possible to add a more specific filter?
If updating
--name
to behave as described isn't possible due to being a breaking change, what about something like:dart test --test file=test/foo_test.dart name="a" --test file="test/bar_test.dart name="b"
I'd be more than happy to raise a pull request about this.
The text was updated successfully, but these errors were encountered: