-
-
Notifications
You must be signed in to change notification settings - Fork 407
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
Test Co-Location #599
Test Co-Location #599
Conversation
…rectory to the app directory
|
||
#### Acceptance Tests | ||
|
||
Acceptance tests do not have a core affiliation with any other file, so co-locating them _may_ not make sense, depending on what a particular test file is doing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in the interest of not leaving a class of tests alone in the tests folder which would really act to minimize their importance, I would propose a default location for acceptance tests under the app/routes/
folder
reasoning behind that is that in those tests you start off by visiting a route then testing the behavior of it as a whole
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this how most acceptance tests are? I thought to leave them in tests/acceptance/
because I haven't seen a clear pattern (not that I've seen a ton of different people's / companies' acceptance tests)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is partly why I left this comment
also judging by the guide https://guides.emberjs.com/release/tutorial/part-1/automated-testing/
that's what an acceptance test looks like:
await visit('/')
click around assert stuff
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that acceptance tests won't be co-located makes this proposal significantly weaker. Now there are two places to look for tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started a poll on twitter: https://twitter.com/tommyjr/status/1234563047873708032
my thoughts are -- what would they be co-located with?
you can co-locate them yourself, as all .test.js files in the app folder would be detected, but I have a hard time justifying changing the default for acceptance tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
co-locating acceptance tests with routes would not work for us. We have several application level tests where the entry URL doesn't matter, we're just using it as a shell to test some complex interaction / behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm personally on the side of co-locating acceptance test with wherever the route lives. Most of the acceptance tests I've written do have some entry URL. I think it's the "sane default" here. And IMO this does not break other people's workflows. If it does not work for your case, you can still use the old locations.
Will the generator be able to use old locations? With some flag?
Also note that since the crawling code will use **/*.test.js
we can use any location we like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current acceptance test blueprint is pretty tied to a single route. I suppose you could then navigate to other routes, but then the auto-generated module and filename would not be very clear, etc. Whenever I create an acceptance test that isn't just/primarily testing a single route, I don't use the blueprint.
So I could definitely see adding another blueprint, e.g. ember g route-acceptance-test my-route
vs. ember g acceptance-test test-my-whole-app
, but there is clearly a need for a single-route-focused blueprint, and I do think it makes sense to co-locate that one.
So I think my opinion is:
- Co-locate acceptance tests as the blueprint currently understands them
- Maybe add another blueprint for non-route-focused blueprints that probably get generated in
tests/<somewhere>
.
Currently, all tests must end with This way, we would only have to move the file, not rename it as well. |
the RFC says this: https://github.com/emberjs/rfcs/pull/599/files#diff-9e4ea543242ddd0a6ef8209ac8a058e8R27
|
|
||
#### Acceptance Tests | ||
|
||
Acceptance tests do not have a core affiliation with any other file, so co-locating them _may_ not make sense, depending on what a particular test file is doing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that acceptance tests won't be co-located makes this proposal significantly weaker. Now there are two places to look for tests.
Seems good for component and unit tests, but the complication with acceptance tests does make it harder to justify. That said, it may be possible to put acceptance tests at Couple other concerns:
|
that's an interesting idea! would we just want them in
ha, ya, I totally forgot about addons. for addon, non-acceptance tests, I could see those being co-located following all the same rules outlined for the app. (just with
integration vs unit doesn't matter today, aside from the arbitrary folders that those tests get thrown in to. module('Component | my-component', ...);
module('Service | my-service', ...);
module('Helper | my-helper', ...);
// etc |
The blueprints are different |
I meant location-wise |
How would this work for in-repo engines and add-ons? Currently their tests are co-located in the I work on a large app with multiple in-repo engines, and being able to have test files co-located with their relevant files would be a huge improvement to the development experience. Regardless, I really like this RFC. Again, working in a big app makes finding test files quite cumbersome as is. |
I like the idea of test co-location in general, but the acceptance test is the biggest roadblock in front of this. Most people write acceptance tests in the feature/scenario oriented way(according to the latest survey results), it is not necessary to be bounded with routings. Thus, the acceptance tests deserve a dedicated place and it should be easy to navigate. I suggest we don't have to be picky too much, just add another folder called As for the end of tests filename, I agree to keep In-repo add-ons/engines could be another big issue here, but I don't know too much about it, I prefer to using monorepo structure these days. Though I think we don't have to put acceptance tests in the in-repo add-ons because "in-repo" implicates serving and only serving the host application, so the application should take care of the acceptance tests. What about unit tests and rendering tests in the in-repo add-ons, does co-locate support it? I'm not sure, but it should be addressed in this RFC. Another thing is once test co-location is settled, the Just my personal opinion, but I would like to see test co-location becomes a success. |
Agree that we may not want to make such a big deal anymore of the difference but the RFC must include how to deal with it:
The same question apply to template helpers and their tests. Possible strategies would be:
|
Just updated the RFC to answer the questions. In short, tests could be anywhere within the entire repo. Maybe not just scoped to
The intent here (for me) is to provide the least dramatic changes while still enabling a lot of flexibility.
I think this is a technical limitation, and nothing we can do anything about. supporting
Component unit tests, imo, should be deprecated, as they rely heavily on implementation and slow maintenance, buuuut, the generator will already warn and prompt you when there is a file conflict and the migrator will need to de the same. that said, my advice, is if you want both component integration and unit tests to be co-located, you could certainly rename things to be be
the generator will warn in case of a conflict, and the user can decide what to do from there. the automated migrator should probably do the same. hope this helps! I've added some unresolved questions to the bottom of the RFC, and would like people's feedback for in-repo-addons and engines |
I like the proposal - would suit integration and unit tests quite well. Thanks for preparing this |
I think this proposal should address:
I think the answer to (1) is pretty clear ( The answers to (2) and (3) could definitely be "it stays where it is," but should be addressed in the RFC. The answer to (4) could be "it stays where it is" although then we need to talk about importing test helpers since I believe most people do a relative import that never traverses outside the I would propose another option for (4), which is also what I proposed in #575, which is to move test helpers to |
@bendemboski re: #1, did you see this section: https://github.com/NullVoxPopuli/rfcs/blob/colocated-tests/text/0000-colocated-tests.md#addons-in-repo-addons-and-engines ? re: the things that aren't tests -- I don't know if this RFC needs to address them, because this RFC is explicitly about |
@NullVoxPopuli oh yeah, I read it but I guess then forgot about it. That seems to imply that the addon tests would live in I guess not addressing (2) and (3) is valid, although I think it would be helpful to call them out as explicitly not addressed by this RFC because I think the RFC strongly suggests the question of what happens to them. For (4), I suppose you could do the same thing, but unlike |
I linked to a paragraph explicitly talking about addon :P anywho, I've updated everything to use |
I'm a fan of this. Now that I've had some time to think about your suggestions, I think they'd all be useful under the "how we teach this" section. |
Right, that's what I was referring to when I said
Now that the rules reference |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally in favor of this. FWIW, this folder structure:
app/components/my-component/
- component.ts
- template.hbs
- styles.css
- story.ts (demo)
- story.gmd (docs)
- unit.test.ts (testing imperative API)
- rendering.test.ts (testing declarative API)
- integration.test.ts (testing integration with eg. data-integration, REST-API/GraphQL...)
- `tests/integration/helpers/{helper-name}-test.js` | ||
now: | ||
- `{app,addon}/helpers/{helper-name}.js` | ||
- `{app,addon}/helpers/{helper-name}.test.js` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what if I want unit and rendering test?
{app,addon}/helpers/{helper-name}.unit.test.js
{app,addon}/helpers/{helper-name}.rendering.test.js
like this? If so, please add as examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do unit tests for helpers exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use different files? Why not
module('...', function() {
module('...', function(hooks) {
setupTest(hooks);
// ...
});
module('...', function(hooks) {
setupRenderingTest(hooks);
// ...
});
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NullVoxPopuli I believe before RFC232, helpers were tested by importing the helper function and testing it as a Javascript function. I don't think that makes sense now that we have rendering tests, but there are probably still legacy helper unit tests out there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I mean, those legacy tests will still work. because (imo), it may not be the happy path, people could either leave their files in tests/
or manually rename?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NullVoxPopuli I agree with you, was just trying to answer your direct question. In fact, if mixing unit and rendering tests, I'd either put them in different modules in the same file (see above), or just put them all in a rendering test module -- you can do "unit tests" in a rendering test environment -- just don't call render()
!
I think the one case where tests don't mix in the same module is application and rendering tests. As rwjblue likes to point out, setupTest()
and setupApplicationTest()
do almost the same thing -- both fully boot an application. setupRenderingTest()
is the odd one since it sets up a sandboxed rendering environment. And I have on occasion written both application and rendering tests for the same subject, but I'd argue those are pretty rare, and nested modules (or just custom test file naming) gives a clean answer there.
So IMO maaaaaaaybe there's a "how we teach this" point in here, but doesn't seem necessary since anything like this is pretty off the beaten path and also has a fine answer.
|
||
Acceptance tests do not have a core affiliation with any other file, so co-locating them _may_ not make sense, depending on what a particular test file is doing. | ||
|
||
While tests may live anywhere in the `{app,addon}` directory, the default location for acceptance tests will still be `tests/acceptance/`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Engines do have a weird setup with the dummy app, so that might be the co-location in that case.
Also I'm not a big fan of the dummy app being used for docs (e.g. ec-addon-docs) and is loaded in (part of) tests... can sb free it up from the identity crisis? :D
Personally, if there would be multiple test files, I'd make a tests folder per component maybe,
|
The need for this capability has come up a few times in discord (and at work) over the past week or two ;) |
@NullVoxPopuli what's the status of this? |
I think at this point, it needs to be reviewed by a core team member? |
- `{app,addon}/routes/{route-name}.test.js` | ||
pods: | ||
- `{pod-namespace}/{route-name}/route.js` | ||
- `{pod-namespace}/{route-name}/.test.js` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This raises a red flag. Won't this collide with controller tests?
❯ ember g route foo --pods
create app/foo/route.js
// therefore: app/foo/.test.js
❯ ember g controller foo --pods
create app/foo/controller.js
// therefore: app/foo/.test.js
This does not seem right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been under the impression that controller tests are rarely used and there wouldn't be a conflict.
but, the controller blueprint could totally check if there is a name collision and then output `app/foo/.controller.test.js
- `{app,addon}/routes/{route-name}.test.js` | ||
pods: | ||
- `{pod-namespace}/{route-name}/route.js` | ||
- `{pod-namespace}/{route-name}/.test.js` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A file starting with a dot is very likely to cause confusion as it's hidden on some operation systems. I think this should be avoided.
I get the argument that collision with legitim names for non-test code must be avoided. But I think we need to find a better solution for pod file system layout. Maybe route.test.js
and controller.test.js
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A file starting with a dot is very likely to cause confusion as it's hidden on some operation systems.
are all the top-level project files hidden? .eslintrc, .ember-cli, etc?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- But this would not be a top-level project files?
- I think mostly those that are hidden are ... configuration files ... for libraries?
I agree that having test file as "hidden" (dot in front of the name) seems wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aight, how about a hyphen (which is more inline with our current naming)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A file starting with a dot is very likely to cause confusion as it's hidden on some operation systems.
are all the top-level project files hidden? .eslintrc, .ember-cli, etc?
Yes. At least for linux systems. They aren't shown in most file explorers nor in output of ls
terminal command.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with the dot files not looking that great… I associate them with configuration and settings, not with test or any actual code written for an application. The hyphen sounds like a good compromise.
So, here are the remaining todos of this RFC (before I bother the core teams)
Needs more discussion:
Please comment if I missed something ;) |
@NullVoxPopuli what's the status of this? I'd love to get it moving again. |
It's been a while, and I need to test this, but I think with some clever packager loader rules (webpack for now) using embroider strictest mode, we might be able to achieve this today. I don't think there is anything for ember core teams to do, as this is now a packager responsibility. If/when I do try this again, I'll probably uncover something special about the tests tree, and I'll open a more specific issue |
rendered