Skip to content
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

RFC: Testing convenience API #171

Open
charypar opened this issue Jan 4, 2024 · 1 comment
Open

RFC: Testing convenience API #171

charypar opened this issue Jan 4, 2024 · 1 comment
Labels
enhancement New feature or request

Comments

@charypar
Copy link
Member

charypar commented Jan 4, 2024

This is a list of nice to have APIs on the AppTester to make tests a little bit verbose in common cases. I'll be updating this issue as I think of them. We can also discuss them as we go, and when there's a few of them, I'll open a PR implementing them.

  • tester.resolve_and_update - resolves an effect and immediately sends any resulting events

  • update.filter_effects(Effect::into_x) - shorthand for update.into_effects().filter_map(Effect::into_x)

  • update.first_effect(Effect::into_x) - shorthand for update.into_effects().filter_map(Effect::into_x).next().ok_or(some_error)

  • macro combining the effect finding shorthand with assert_let like behaviour on the operation the effect carries, if possible. It's quite common to pull data out of the requests, while also holding onto the request in order to resolve it.

    E.g. something like

    let mut request = assert_first_effect_let!(Effect::into_x, XOperation { field: thing });
    tester.resolve(&mut request, format!("Received: {}", thing))
@charypar charypar added the enhancement New feature or request label Jan 4, 2024
@redbadger redbadger deleted a comment from habibur4340 Feb 2, 2024
@charypar
Copy link
Member Author

charypar commented Feb 9, 2024

Further thoughts:

  • resolve_and_update should have flat_map-like semantics - all the events sent may produce effect requests, and the total set of them should come back. Having the batches might also be useful, the caller can always .flatten().
  • The typical scenario when working with effects in tests, which we should provide nice API for, is something along the lines of:
    1. Filter effects to a particular type(s) - we should have an ergonomic API for this
    2. Pick each effect apart to get the request and the operation - we should have an ergonomic API for this
    3. Make assertion about the operation
    4. Resolve the request (or multiple, but this is rare)
    5. Send the resulting events and collect effect requests - we should have an ergonomic API for this
    6. Repeat
  • pattern matching semantics similar to let else seem quite a natural way to do the filtering, since it's often useful to do a let binding of the operation for further assertions
  • It would be fantastic if we could find a way to write the interaction tests in a declarative fasion - descibing the expected sequence of effects, state and the responses. The test is almost always a sequence of "rounds", where each round is something like [expected effect, operation assertions, model assertions, response, model assertions].
  • It may be helpful to install single-test scoped "effect handlers" on the AppTester instance when testing chained effects. These would handle specific effects (e.g. an authorization effect before an action) in a stubbing fashion to help the test get to the effects it's interested in without explicitly handling them. They would always handle matching effects and advance the app (effectively "skipping" a round).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Development

No branches or pull requests

1 participant