“This is the 15th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

Chapter 20, Chapter 2 of the Definitive Guide to Android Programming completes unit testing for BeatBox apps.

Address:

Juejin. Cn/post / 703334…

Write test functions

The Test function will use the @test annotation.

    @Test
    fun exposesSoundNameAsTitle(){
        assertThat(subject.title,`is`(sound.name))
    }
Copy the code

assertThat(…) Choose Assert. AssertThat (…) from org.junit. Function, is (…). Select the is. Is function in org.hamcrest.

The title function and the file name function of sound return the same value. If not, the unit test fails.

Next test the SoundViewModel interaction with Beatbox.Play (Sound).

    @Test
    fun callsBeatBoxPlayOnButtonClicked(){
        subject.onButtonClicked()
    }
Copy the code

To test the SoundViewModel without tying it too tightly to BeatBox objects, we simulate BeatBox objects in this test case.

class SoundViewModelTest { ... private lateinit var beatBox: BeatBox @Before fun setUp() { beatBox = mock(BeatBox::class.java) ... }... }Copy the code

Mockito’s Verify (Object) verifies that the functions to be tested are called as expected.

    @Test
    fun callsBeatBoxPlayOnButtonClicked(){
        ...
        verify(beatBox).play(sound)
    }
Copy the code

Then follow the instructions in the book. Pass BeatBox to SoundViewModel, fix errors in SoundHolder, provide BeatBox simulators in the test class, and implement onButtonClicked(). The specific code is omitted, see Demo.

Data binding callback

In the layout file, add a data binding lambda expressions, let the button object and SoundViewModel onButtonClicked () function.

    <Button
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:onClick="@{()->viewModel.onButtonClicked()}"
        android:text="@{viewModel.title}"
        tools:text="Sound name" />
Copy the code

Run the app, click the button, and you’ll hear a strange scream. Try it yourself.

10. Release audio

Soundpool.release () should be called to release SoundPool once the audio has played.

Add methods to BeatBox:

    fun release(){
        soundPool.release()
    }
Copy the code

Then call MainActivity when it is destroyed:

    override fun onDestroy() {
        super.onDestroy()
        beatBox.release()
    }
Copy the code

Deep learning: Integrated testing

  • In unit tests, the object under test is a single class. Ensure that each class unit works correctly and interacts with each other as expected.

  • In integration testing, the object under test is part of the application, including many objects that work together. Verify that the tested parts are properly integrated and working as expected. On The Android platform, integration testing is still generally uI-level testing (interacting with UI widgets to verify that they behave as expected). Instrumentation testing is often implemented.

Espresso is a UI testing framework developed by Google for testing Android applications. Usually new projects automatically reference this dependency.

AndroidTestImplementation 'androidx. Test. Espresso: espresso - core: 3.3.0'Copy the code

You can use it to test the behavior of an activity.

Determine that a view on the screen displays the filename of the first sample_sounds tested file:

@RunWith(AndroidJUnit4::class)
class MainActivityTest {
    
    @get:Rule
    val activityRule = ActivityTestRule(MainActivity::class.java)
    
    @Test
    fun showsFirstFileName(){
        onView(withText("65_cjipie"))
            .check(matches(isDisplayed()))
    }
}
Copy the code

RunWith(Androidjunit4.class) indicates that this is an Android tool test that requires activity and other Android runtime support.

The @Get :Rule annotation on activityRule tells JUnit to start an instance of MainActivity before running the test.

OnView (withText(“65_cjipie”)) finds the view showing “65_cjipie” and tests it.

Check (matches(isDisplayed())) is used to check that the view is visible on the screen.

For details about Espresso:

Developer.android.com/training/te…

In-depth study: Mock objects and tests

Mock objects masquerade as unrelated components in order to isolate the objects under test. Mockito’s ability to quickly create mock objects is useful for unit testing.

However, when integrating tests, it is best to avoid using automatic simulation testing frameworks like Mockito because simulation is too heavy, requires many integration test sharing, and is too cumbersome.

** Basic rule: ** The utility of mock objects should not extend beyond the boundaries of the components under test. Focus on testing scope to prevent testing from crossing boundaries.

Challenge exercise: Play progress control

In MainActivity, use SeekBar to control the play(Int, Float, Float, Int, Int, Float) function of SoundPool.

Refer to Demo, may not update when. O ha ha ~ O (studying studying)

Challenge exercise: equipment rotation problem

Add a Jetpack version of the ViewModel to the BeatBox application to save BeatBox objects as the device rotates.

Refer to Demo, may not update when. O ha ha ~ O (studying studying)

other

BeatBox Project Demo address:

Github.com/visiongem/A…


🌈 follow me ac~ ❤️

Public account: Ni K Ni K