Skip to content
This repository has been archived by the owner on Feb 24, 2021. It is now read-only.

[WIP] Stream test tool #292

Closed
wants to merge 20 commits into from
Closed

[WIP] Stream test tool #292

wants to merge 20 commits into from

Conversation

pablisco
Copy link
Contributor

@pablisco pablisco commented Sep 29, 2020

This PR adds a new module to help test streams.

The main entry point of this API is the function testStream { ... }. The provided closure has a TestStreamScope receiver.

TestStreamScope defines the following operations available to work with streams in tests:

  • capture
  • captureInOrder
  • expect
  • expectThat
  • expectAll
  • expectInOrder
  • expectException
  • expectNothingMore
  • next
  • nextOrNull
  • nextException
  • next(n)

Copy link
Member

@nomisRev nomisRev left a comment

Choose a reason for hiding this comment

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

Not a 100% sure why "// TODO: Not working ATM" is not working, but afaik GlobalScope is unsafe for this, no?

Comment on lines 54 to 55
val values = queue.dequeue().interruptAfter(now).toList()
check(values.isEmpty()) { "Expected nothing more but got: $values" }
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
val values = queue.dequeue().interruptAfter(now).toList()
check(values.isEmpty()) { "Expected nothing more but got: $values" }
val option = queue.tryDequeue1()
check(option.isEmpty()) { "Expected nothing more but got: $values" }

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Interesting, this change makes the test that is failing work... however, I feel that we may be losing potential data... My intention was to basically flush the queue of all current values. So we can tell the tester that there were one or more items that were emitted...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Never mind, the success was a fluke 🙃 Damn concurrency is hard... need to find a better way to control the coroutines in tests

@pablisco pablisco marked this pull request as ready for review October 4, 2020 00:36
@pablisco
Copy link
Contributor Author

pablisco commented Oct 4, 2020

@nomisRev It should be fully working now with more options available :) I need to add some extra documentation.

Copy link
Member

@nomisRev nomisRev left a comment

Choose a reason for hiding this comment

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

What benefits would this library offer over using the build in Stream operators?

Most of the tests in TestStreamTest can be written in a simpler manner using simple terminal operators like done in the test suite of Stream itself.

pablisco and others added 3 commits October 5, 2020 09:05
…tream/test/TestStreamScope.kt

Co-authored-by: Simon Vergauwen <nomisRev@users.noreply.github.com>
…tream/test/TestStreamScope.kt

Co-authored-by: Simon Vergauwen <nomisRev@users.noreply.github.com>
@pablisco
Copy link
Contributor Author

pablisco commented Oct 7, 2020

@nomisRev

What benefits would this library offer over using the build in Stream operators?

For simple cases, I think it's clear that it's simpler to use terminal operations. I think it adds value when we start looking at more complex workflows as it's easier to lay down expectations in a linear way... I guess could call it test comprehensions :)

I started this idea while testing view bindings with instrumentation tests. Something like:

testStream {
  onActivity { activity -> activity.button.clicks().capture() } // runs on the main android Looper
  onView(withId(R.id.button)).perform(click())
  expect(Unit)
  onView(withId(R.id.button)).perform(click())
  expect(Unit)
  expectNothingMore()
}

In this case, I couldn't extract the stream of clicks from the button from the main thread and I wasn't able to run espresso operations on the main thread.

Doing this, the test will block the test thread until it receives the required Unit from the click trigger :)

@nomisRev
Copy link
Member

@pablisco thanks for looking into this. This became obsolete by deprecating Stream in favor of Flow from KotlinX Coroutines. We'd like to offer a set of extension functions over Flow that offer the same APIs as we have with Stream.

@pablisco
Copy link
Contributor Author

Totally understand. Makes sense. I may try to do something for flow if I find the time as I've been thinking about such extensions for a while. Closing this for now though 👍

@pablisco pablisco closed this Dec 12, 2020
@nomisRev
Copy link
Member

@pablisco I'll try to add some tickets on the repo with ideas for Flow extensions feel free to do the same.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants