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

Fix #2209: Create a Helper class to provide methos for [RecyclerViewActions] scrolling actions #2451

Closed

Conversation

srikanthkb
Copy link
Contributor

@srikanthkb srikanthkb commented Jan 11, 2021

Explanation

Fixes #2209

Created a new class which provides all of the potential [RecyclerViewActions] required by our codebase.
Replaced scrollToPosition() with actionOnItemAtPosition() [RecyclerViewActions].
This change allows both Espresso and Roboelectric tests for TopicLessonsFragmentTest.kt to be successful.

Checklist

  • The PR title starts with "Fix #bugnum: ", followed by a short, clear summary of the changes. (If this PR fixes part of an issue, prefix the title with "Fix part of #bugnum: ...".)
  • The PR explanation includes the words "Fixes #bugnum: ..." (or "Fixes part of #bugnum" if the PR only partially fixes an issue).
  • The PR follows the style guide.
  • The PR does not contain any unnecessary auto-generated code from Android Studio.
  • The PR is made from a branch that's not called "develop".
  • The PR is made from a branch that is up-to-date with "develop".
  • The PR's branch is based on "develop" and not on any other branch.
  • The PR is assigned to an appropriate reviewer in both the Assignees and the Reviewers sections.

Created a new file in testing module to provide for the different
recyclerview actions.

TODO:
* Update the Testing class to use scrolling action from this api
* Include the third method of scrolling actions
* Work on the documentation - for the class, and each method in it
* Check and confirm gradle dependencies
(TODO) Improve clarity on the names, Kdocs, usage of the methods
described in the new file.
into scrolling-actions-testing-module
@srikanthkb
Copy link
Contributor Author

@BenHenning , @anandwana001 , @rt4914
Please provide your inputs on the method names, documentation, test cases etc.

Copy link
Member

@BenHenning BenHenning left a comment

Choose a reason for hiding this comment

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

Thanks @Srikanth-Kb! Left my thoughts.

Comment on lines 11 to 17
/**
* Provides the different scrolling options for RecyclerView
*
* This is needed because few Roboelectric tests require different scrolling actions for the tests
* to be successful.
* See https://github.com/oppia/oppia-android/issues/2209 for more information.
*/
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
/**
* Provides the different scrolling options for RecyclerView
*
* This is needed because few Roboelectric tests require different scrolling actions for the tests
* to be successful.
* See https://github.com/oppia/oppia-android/issues/2209 for more information.
*/
/**
* Provides different scrolling actions for [RecyclerView]s.
*
* This is needed because different testing scenarios in Robolectric tests
* potentially require different scrolling actions for the tests to be successful.
* See #2209 for more information.
*/

(May need line wrapping--you should ensure the KDocs lines take up as much space in the 100 character column limit).

Note that I rephrased this slightly to try and clarify the meaning. Note also that we can just reference issues within our repository directly by '#'--that's conventional on the team so others will understand what that means when they come across it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted. Updated the changes.

Comment on lines 37 to 39
* 1) Scroll RecyclerView to position
* 2) Perform an action on the view at position
* Usage : TODO
Copy link
Member

Choose a reason for hiding this comment

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

Some thoughts:

  • We probably don't care about documenting usage at this level (that can be introspected by seeing where this method is being used, instead)
  • The documentation shouldn't discuss how the method works, just what it's promising to do
  • Between this & the method above, I don't understand when to pick one versus the other. How does one make that decision? These KDocs should clearly explain when it's appropriate to use each one so that it can become clearer to others when trying to decide which to use when scrolling in a recycler view.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted. KDoc for latest changes implemented with these changes.

@BenHenning BenHenning assigned srikanthkb and unassigned BenHenning Jan 12, 2021
@srikanthkb
Copy link
Contributor Author

@rt4914 @anandwana001
As an alternative, I used the actionOnItemAtPosition view action instead of scrollToPosition view action, in the private method scrollToPosition in TopicLessonsFragmentTest.kt

With this one line change, I was able to run both the Espresso tests and Roboelectric tests successfully for TopicLessonsFragmentTest.kt, the screenshots are attached for reference.

Espresso tests
image

Roboelectric tests
image

Do we still need the helper class to provide different scrolling actions for the RecyclerView ?

@rt4914
Copy link
Contributor

rt4914 commented Jan 12, 2021

@rt4914 @anandwana001
As an alternative, I used the actionOnItemAtPosition view action instead of scrollToPosition view action, in the private method scrollToPosition in TopicLessonsFragmentTest.kt

With this one line change, I was able to run both the Espresso tests and Roboelectric tests successfully for TopicLessonsFragmentTest.kt, the screenshots are attached for reference.

Espresso tests
image

Roboelectric tests
image

Do we still need the helper class to provide different scrolling actions for the RecyclerView ?

@Srikanth-Kb I think we should have only 1 function which works for all because at this point both of these functions looks almost same to me.

@rt4914 rt4914 removed their assignment Jan 12, 2021
* Replace scrollToPosition() RecyclerView action with
  actionOnItemAtPosition()
* Successfully supports both Espresso and Roboelectric test cases in
  TopicLessonsFragment.kt
@srikanthkb srikanthkb changed the title Fix #2209: Introduce scrolling actions testing module Fix #2209: Replace scrollToPosition() with actionOnItemAtPosition() [RecyclerViewActions] Jan 13, 2021
Copy link
Contributor

@anandwana001 anandwana001 left a comment

Choose a reason for hiding this comment

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

left my thoughts on replacing thing.

@@ -381,8 +378,9 @@ class TopicLessonsFragmentTest {

private fun scrollToPosition(position: Int) {
onView(withId(R.id.story_summary_recycler_view)).perform(
scrollToPosition<RecyclerView.ViewHolder>(
position
actionOnItemAtPosition<RecyclerView.ViewHolder>(
Copy link
Contributor

Choose a reason for hiding this comment

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

There are many other files in the whole codebase where we are using scrollToPosition<RecyclerView.ViewHolder>(position).

So, as for this file only, if we bring consistency by using actionOnItemAtPosition<RecyclerView.ViewHolder>() everywhere, it's also good, but we do need a helper class which is something single point where we can look for when to use which scrolling way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@anandwana001
Copy link
Contributor

Should we use actionOnItemAtPosition everywhere in the codebase? WDYT?

@anandwana001 anandwana001 removed their assignment Jan 13, 2021
* Created a new helper class including methods for all of required
  RecyclerView actions for the codebase
* Added required gradle dependencies in the testing module
@srikanthkb srikanthkb changed the title Fix #2209: Replace scrollToPosition() with actionOnItemAtPosition() [RecyclerViewActions] Fix #2209: Create a Helper class to provide for all [RecyclerViewActions] Jan 15, 2021
@srikanthkb
Copy link
Contributor Author

srikanthkb commented Jan 15, 2021

Requesting @BenHenning , @anandwana001 for any thoughts on this implementation

@srikanthkb srikanthkb changed the title Fix #2209: Create a Helper class to provide for all [RecyclerViewActions] Fix #2209: Create a Helper class to provide methos for [RecyclerViewActions] scrolling actions Jan 15, 2021
Copy link
Member

@BenHenning BenHenning left a comment

Choose a reason for hiding this comment

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

Thanks @Srikanth-Kb. Some thoughts:

  1. When following up to a review, make sure to respond to all comments before sending the PR back to the reviewer
  2. The implementation of the helper class looks good (aside from my style nits), so I think that you can go ahead and broadly move the rest of the codebase over to this implementation
  3. Note that the migration over to this implementation ought to happen in a later PR. I suggest splitting this up such that:
    a. We introduce a new utility with its own dedicated tests to verify correctness
    b. We migrate all positional uses over to the new utility
    c. We migrate all view type uses to the new utility

This results in 3 PRs to keep things a bit smaller and self-contained. It also means that if something breaks and we need to revert the PR, we won't need to revert the entire batch of changes.

* Use this method for all testing scenarios when scrolling to a RecyclerView at a particular
* position
*/
fun scrollToPosition(recyclerViewId: Int, position: Int) {
Copy link
Member

Choose a reason for hiding this comment

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

Here & below: recyclerViewId should be annotated with LayoutRes (https://developer.android.com/reference/androidx/annotation/LayoutRes) to explicitly specify that this represents a layout resource ID.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

}

/**
* Performs scrolling action to [RecyclerView] of a particular ViewType
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
* Performs scrolling action to [RecyclerView] of a particular ViewType
* Performs scrolling action to [RecyclerView] of a particular ViewType designed by a view holder via [baseMatcher].

Some additional context (may need wrapping). Try to keep this & other KDocs as proper paragraphs, too (e.g. don't line break unless it's for wrapping or you want to communicate separate ideas (in which case there should be a blank documentation line, e.g. just '*' between the paragraphs).

Ditto for both in above KDocs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted. Updated the change in commit.

'androidx.test.espresso:espresso-core:3.2.0',
'androidx.test.espresso:espresso-contrib:3.2.0',
'androidx.test.espresso:espresso-intents:3.1.0',
Copy link
Member

Choose a reason for hiding this comment

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

Why is the intents library needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

intents library is not required in the testing module.
Updated the change in new commit.

actionOnItemAtPosition<RecyclerView.ViewHolder>(2, scrollTo())
recyclerViewScrollingActions.scrollToPosition(
R.id.story_summary_recycler_view,
2
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
2
position = 2

When using literals, prefer to add named arguments to provide context to readers on the value. Ditto elsewhere in this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Noted. Done.
Also created #2515 as a good-first-issue for such changes elsewhere in the codebase.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change will be handled in an independent PR, as planned, migration for positional use case will be handled independently for the entire codebase.

@@ -253,7 +257,10 @@ class StateFragmentTest {
launchForExploration(TEST_EXPLORATION_ID_2).use {
startPlayingExploration()

scrollToViewType(CONTINUE_INTERACTION)
Copy link
Member

Choose a reason for hiding this comment

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

I think let's invert this refactor--scrollToViewType can use RecyclerViewScrollingActions' scrollToViewType (the current syntax is much cleaner so we actually lose that by refactoring at the test level).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This change will be handled in a separate PR, as migration will be handled independently.

@BenHenning BenHenning removed their assignment Jan 16, 2021
@anandwana001 anandwana001 removed their assignment Jan 19, 2021
The migration of the actual tests will be handled independently.
* Updated KDocs with line wrapping, better context.
* Updated annotation @LayoutRes for recyclerViewId
@srikanthkb
Copy link
Contributor Author

  1. Note that the migration over to this implementation ought to happen in a later PR. I suggest splitting this up such that:
    a. We introduce a new utility with its own dedicated tests to verify correctness
    b. We migrate all positional uses over to the new utility
    c. We migrate all view type uses to the new utility

This results in 3 PRs to keep things a bit smaller and self-contained. It also means that if something breaks and we need to revert the PR, we won't need to revert the entire batch of changes.

Hi @BenHenning ,
Regarding the first PR, when we are writing dedicated tests to verify the correctness of the utility methods in RecyclerViewScrollingActions.kt
a. Do we have to create a RecyclerViewScrollingActionsTestActivity, RecyclerViewTestAdapter, RecyclerViewTestViewHolder, required test layouts (xml) for activity, viewholder etc and fake data (used only for testing) ?
Is this line of thinking right ?
b. Can you provide some inputs on how we should test the scrollToViewType() method, given that its argument is of type BaseMatcher<RecyclerView.ViewHolder> ?

@anandwana001 Please provide your suggestions as well.

@BenHenning BenHenning added the PR don't merge - NEEDS UPDATE Corresponds to PRs that need to be updated with the latest develop changes before they can be merged label Feb 24, 2021
@BenHenning BenHenning removed the PR don't merge - NEEDS UPDATE Corresponds to PRs that need to be updated with the latest develop changes before they can be merged label Feb 24, 2021
@srikanthkb
Copy link
Contributor Author

Here's some information regarding writing tests for the RecyclerView scrolling actions:

  1. We need to create a dedicated TestActivity, TestFragment, TestFragment presenter, layouts, RecyclerViewAdapter, Viewholders (of two types) and fake data. Use BinderAdapter tests for reference.
  2. For the first method: scrollToPosition() , we can use a RecyclerView with fake data (preferably text) and verify if the text is displayed correctly at that position.
  3. For the second method: scrollToViewType, we have to create a CustomMatcher which extends the BaseMatcher class, and use at least two viewholder types to verify the data displayed on different view types.

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

Successfully merging this pull request may close these issues.

Introduce test-only component for RecyclerView scrolling
4 participants