Skip to content
Open
64 changes: 64 additions & 0 deletions PiPSampleActivityTest_No_PiP
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.example.android.pip

import android.view.View
import android.widget.TextView
import androidx.test.core.app.ActivityScenario.launch
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.LargeTest
import com.google.common.truth.Truth.assertThat
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
@LargeTest
class PiPSampleActivityTest {

/**
* Verifies that the timer starts and updates the time.
*/
@Test
fun startTimer_updatesTime() {
val scenario = launch(PiPSampleActivity::class.java)

scenario.onActivity { activity ->
val startBtn = activity.findViewById<View>(R.id.start_or_pause)
val timeText = activity.findViewById<TextView>(R.id.time)

// Initial state
assertThat(timeText.text.toString()).isEqualTo("00:00:00")

// Start timer
startBtn.performClick()
}

// Wait for async update
Thread.sleep(1500)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Using Thread.sleep() in UI tests is an anti-pattern that leads to flaky and slow tests. The test can fail if the async operation takes longer than the sleep duration, and it unnecessarily slows down your test suite. Please replace this with a proper synchronization mechanism, such as Espresso Idling Resources, or at least a polling loop that checks for the condition with a timeout.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please fix


scenario.onActivity { activity ->
val timeText = activity.findViewById<TextView>(R.id.time)

// Time should now be updated
assertThat(timeText.text.toString()).isNotEqualTo("00:00:00")
}
}

/**
* Verifies that the Clear button resets the timer.
*/
@Test
fun clearTimer_resetsTime() {
val scenario = launch(PiPSampleActivity::class.java)

scenario.onActivity { activity ->
val startBtn = activity.findViewById<View>(R.id.start_or_pause)
val clearBtn = activity.findViewById<View>(R.id.clear)
val timeText = activity.findViewById<TextView>(R.id.time)

startBtn.performClick()
clearBtn.performClick()

// Time should reset
assertThat(timeText.text.toString()).isEqualTo("00:00:00")
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This test has a potential race condition. It clicks 'start' and then 'clear' immediately within the same UI thread task. This doesn't guarantee that the timer has actually started counting before it's cleared. To make this test more robust, you should first verify that the timer is running and then test the clear functionality. The suggested change refactors the test to wait for the timer to start before clearing it. Note that Thread.sleep is used here for demonstration, but it should be replaced with a proper synchronization mechanism as mentioned in the other comment.

        scenario.onActivity { activity ->
            activity.findViewById<View>(R.id.start_or_pause).performClick()
        }

        // Wait for the timer to have started.
        // NOTE: Using Thread.sleep() here makes the test flaky and slow.
        // This should be replaced by a proper synchronization mechanism like IdlingResource.
        Thread.sleep(1500)

        scenario.onActivity { activity ->
            val timeText = activity.findViewById<TextView>(R.id.time)
            assertThat(timeText.text.toString()).isNotEqualTo("00:00:00")

            activity.findViewById<View>(R.id.clear).performClick()
            assertThat(timeText.text.toString()).isEqualTo("00:00:00")
        }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

please fix

}
}
Loading