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

add Espresso tests for TableDisplayActivityTest #217

Open
wants to merge 2 commits into
base: upgrade-jdk11
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package org.opendatakit.espresso;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.intent.Intents.intended;
import static androidx.test.espresso.intent.matcher.IntentMatchers.hasComponent;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;
import androidx.test.core.app.ActivityScenario;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner;
import androidx.test.rule.GrantPermissionRule;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static org.junit.Assert.assertTrue;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.opendatakit.tables.R;
import org.opendatakit.tables.activities.TableDisplayActivity;
import org.opendatakit.tables.fragments.TableManagerFragment;

@RunWith(AndroidJUnit4ClassRunner.class)
public class TableDisplayActivityTest {

@Rule
public GrantPermissionRule permissionRule = GrantPermissionRule.grant(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE);

@Rule
public ActivityScenarioRule<TableDisplayActivity> activityRule =
new ActivityScenarioRule<>(TableDisplayActivity.class);

private ActivityScenario<TableDisplayActivity> scenario;

@Before
public void setUp() {
scenario = activityRule.getScenario();
}

@After
public void tearDown() {
// Clean up after tests
scenario.close();
}

@Test
public void testOnCreate() {

Choose a reason for hiding this comment

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

@Chinex-Boroja Typically, your tests should have more descriptive names. This will help define the scope of your test and make its purpose more apparent. You can follow a structure like given_when_then or subjectUnderTest_actionOrInput_expectedResult.

// Verify the UI elements and initial state
onView(withId(R.id.recycler_view)).check(matches(isDisplayed()));
}


@Test
public void testFragmentTransaction() {

Choose a reason for hiding this comment

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

@Chinex-Boroja Manually adding the framgment here, does not fully capture the intent of testing. When you manually add the fragment, it’s almost guaranteed that it will be added, which may not provide much value in terms of testing.

The test would be more meaningful if it verified that the fragment was added as part of the actual UI flow, triggered by user interaction or lifecycle events, rather than by directly invoking the fragment transaction in the test. This way, the test would better reflect real-world scenarios and provide more meaningful insights.

If you need more clarifications, I am happy to huddle.
CC: @wbrunette what are your thoughts?

scenario.onActivity(activity -> {
FragmentManager fragmentManager = activity.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

// Start the transaction and add the fragment
TableManagerFragment fragment = new TableManagerFragment();
fragmentTransaction.add(R.id.activity_table_manager_list_fragment, fragment);
fragmentTransaction.commit();

// Verify the fragment is added
fragmentManager.executePendingTransactions();
assertTrue(fragment.isAdded());
});
}

@Test
public void testRecyclerViewItemClick() {
// Simulate a click on an item in the RecyclerView
onView(withId(R.id.recycler_view))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));

// Verify that the appropriate activity is launched
intended(hasComponent(TableDisplayActivity.class.getName()));

Choose a reason for hiding this comment

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

@Chinex-Boroja From what I can see, this test is checking that when a user clicks on an item, the app attempts to start the TableDisplayActivity. However, since this test is already within the context of TableDisplayActivity, it feels a bit redundant. Could you share your thoughts on this approach and the reasoning behind it?

Typically, when you're testing within the context of an activity, you wouldn't use the same activity instance to verify actions triggered within it. It might be more effective to verify the intended behavior by confirming what the code is expected to do and validating against that.

CC: @wbrunette

}

@Test
public void testTableDetailsDisplay() {

Choose a reason for hiding this comment

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

@Chinex-Boroja a more descriptive name here too

Copy link
Author

Choose a reason for hiding this comment

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

Noted @Lamouresparus, will make a fix

// Simulate selecting a table and verify the details are displayed
onView(withId(R.id.recycler_view))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, click()));

// Verify that the details are displayed correctly
onView(withId(R.id.activity_table_display_activity_split_content)).check(matches(isDisplayed()));
onView(withId(R.id.activity_table_display_activity_split_content)).check(matches(withText("Expected Table Details")));
}
}