如何编写Android导航控制器的测试

时间:2018-07-08 05:59:35

标签: android android-testing android-jetpack android-architecture-navigation

我正在使用新的导航控制器,该控制器当前处于Alpha状态。它工作正常,但是我找不到任何文档或示例应用程序来查看测试是如何完成的。谷歌还发布了android.arch.navigation:navigation-testing库,用于测试导航,但是同样没有文档。

任何帮助或建议,将不胜感激。

3 个答案:

答案 0 :(得分:5)

Google的文档可能是最典型的答案。我也搜索了Medium @ Android Developers,但找不到与此主题相关的文章。但是我可以用Java提供一些示例代码,包括上下文。这与Test Navigation中的一个示例完全相同,但是声明了androidx的依赖项和导入,提供了整个借口。

让我们像这样假设依赖项:

dependencies {

    implementation "androidx.appcompat:appcompat:1.1.0"    
    implementation "androidx.navigation:navigation-fragment:2.1.0"
    implementation "androidx.navigation:navigation-ui:2.1.0"

    testImplementation "junit:junit:4.12"
    androidTestImplementation "androidx.test.ext:junit:1.1.1"
    androidTestImplementation "androidx.test:core:1.2.0"
    androidTestImplementation "androidx.test:runner:1.2.0"
    androidTestImplementation "androidx.test:rules:1.2.0"

    // Espresso
    androidTestImplementation "androidx.test.espresso:espresso-core:3.2.0"

    // Mockito
    androidTestImplementation "org.mockito:mockito-core:2.7.22"
    androidTestImplementation "org.mockito:mockito-android:2.7.22"

    // FragmentScenario
    debugImplementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.50"
    debugImplementation ("androidx.fragment:fragment-testing:1.1.0") {
        // required, while there is no version 1.2.0 yet.
        exclude group: "androidx.test", module: "core"
    }
}

这些就是进口:

import org.junit.Test;
import org.junit.runner.RunWith;

import androidx.fragment.app.testing.FragmentScenario;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.test.espresso.action.ViewActions;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import com.acme.fragment.LoginFragment;

import static androidx.test.espresso.Espresso.onView;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;

以下是带有模拟FragmentScenario的{​​{1}}的正式示例:

NavController

此类@RunWith(AndroidJUnit4.class) public class NavControllerTest { @Test public void testLoginToMainFragment() { // Create a mock NavController NavController mockNavController = mock(NavController.class); // Create a graphical FragmentScenario for the LoginFragment // (this is why the dependency has to be debugImplementation). FragmentScenario<LoginFragment> loginScenario = FragmentScenario.launchInContainer(LoginFragment.class); // Set the NavController property on the fragment loginScenario.onFragment(fragment -> Navigation.setViewNavController(fragment.requireView(), mockNavController) ); // Entering login credentials ... // Verify that performing a click prompts the correct Navigation action onView(ViewMatchers.withId(R.id.button_login)).perform(ViewActions.click()); verify(mockNavController).navigate(R.id.action_loginFragment_to_mainFragment); } } 的Lambda表达式需要在模块的->中设置的compileOptions sourceCompatibility JavaVersion.VERSION_1_8

答案 1 :(得分:0)

目前,官方的android文档提供了一些详细信息,但示例不多。

在测试中,您可以使用Mockito提供一个模拟NavController,并可以使用它来验证应用程序的交互。

例如,要测试应用程序在用户单击按钮时将用户正确导航到特定屏幕,您的测试需要验证该片段是否以所需的操作调用了NavController.navigate()

结合使用FragmentScenario,Espresso和Mockito,您可以重新创建测试此方案所需的条件,如下所示:

@RunWith(AndroidJUnit4::class)
class FirstScreenTest {

    @Test
    fun testNavigationToSecondScreen() {
        // Create a mock NavController
        val mockNavController = mock(NavController::class.java)

        // Create a graphical FragmentScenario for the FirstScreen
        val firstScenario = launchFragmentInContainer<FirstScreen>()

        // Set the NavController property on the fragment
        firstScenario.onFragment { fragment ->
            Navigation.setViewNavController(fragment.requireView(), mockNavController)
        }

        // Verify that performing a click prompts the correct Navigation action
        onView(ViewMatchers.withId(R.id.button)).perform(ViewActions.click())
        verify(mockNavController).navigate(R.id.action_first_screen_to_second_screen)
    }
}

答案 2 :(得分:-1)

他们确实有this minimal文档,但是看起来有些示例代码会很好。