{"id":45766,"date":"2021-11-23T20:47:04","date_gmt":"2021-11-23T11:47:04","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=45766"},"modified":"2021-11-23T20:47:06","modified_gmt":"2021-11-23T11:47:06","slug":"testing-in-jetpack-compose-%ec%97%b0%ec%8a%b5%eb%ac%b8%ec%a0%9c","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=45766","title":{"rendered":"Testing in Jetpack Compose &#8211; \uc5f0\uc2b5\ubb38\uc81c"},"content":{"rendered":"\n<p>\uc774 \ub2e8\uacc4\uc5d0\uc11c\ub294 \uc561\uc158(Action)\uc744 \uc0ac\uc6a9\ud558\uc5ec RallyTopAppBar\uc758 \ub2e4\ub978 \ud0ed\uc744 \ud074\ub9ad\ud558\uba74 \uc120\ud0dd \ud56d\ubaa9\uc774 \ubcc0\uacbd\ub418\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. Action\uc5d0 \ub300\ud55c \ubd80\ubd84\uc740 <a href=\"https:\/\/developer.android.com\/jetpack\/compose\/testing-cheatsheet?hl=ko\">Testing Cheat Sheet<\/a>\ub97c \ucc38\uc870\ud558\uc790.<\/p>\n\n\n\n<p>\ud78c\ud2b8:<\/p>\n\n\n\n<ul><li>\ud14c\uc2a4\ud2b8 \ubc94\uc704\uc5d0\ub294 RallyApp\uc774 \uc18c\uc720\ud55c \uc0c1\ud0dc(State)\uac00 \ud3ec\ud568\ub418\uc5b4\uc57c \ud55c\ub2e4.<\/li><li>\ud589\ub3d9(behavior)\uc774 \uc544\ub2c8\ub77c \uc0c1\ud0dc(state)\ub97c \ud655\uc778(verify)\ud558\uc790. \ud638\ucd9c\ub41c \uac1d\uccb4\uc640 \ubc29\ubc95\uc5d0 \uc758\uc874\ud558\ub294 \ub300\uc2e0 UI \uc0c1\ud0dc\uc5d0 \ub300\ud55c \uc8fc\uc7a5(assertion)\uc744 \uc0ac\uc6a9\ud55c\ub2e4.<\/li><\/ul>\n\n\n\n<p>\uc774 \uc5f0\uc2b5\ubb38\uc81c\uc5d0\ub294 \uc81c\uacf5\ub41c \ud574\ub2f5\uc774 \uc5c6\ub2e4.<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<blockquote class=\"wp-block-quote\"><p>\uc815\ub2f5\uc774 \uc5c6\uc9c0\ub9cc \uc5f4\uc2ec\ud788 \uc5f0\uc2b5\ubb38\uc81c\ub97c \ud480\uc5b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \ud0dc\ud074 \ud658\uc601\ud569\ub2c8\ub2e4.<\/p><\/blockquote>\n\n\n\n<p>\uc8fc\uc5b4\uc9c4 \ud78c\ud2b8\uac00 \uc0ac\uc2e4\uc740 \uc81c\uc57d\uc0ac\ud56d\uc778 \uac83 \uac19\ub2e4.<\/p>\n\n\n\n<p>RallyApp\uc774 \uac00\uc9c0\uace0 \uc788\ub294 \uc0c1\ud0dc\ub97c \ubc18\ub4dc\uc2dc \ud3ec\ud568\ud574\uc11c \ud14c\uc2a4\ud2b8 \ubc94\uc704\ub97c \uc7a1\uc544\uc57c \ud558\uace0, \uc0c1\ub2e8 \ubc14\uc758 \ud0ed\uc744 \ud074\ub9ad\ud574\uc11c \ud574\ub2f9 \uc0c1\ud0dc\uac00 \ubcc0\uacbd\ub418\uc5c8\ub294\uc9c0\ub3c4 \ud655\uc778\ud574\uc57c \ud558\ub2c8 \uc6b0\uc120 RallyApp\ucf54\ub4dc\ub97c \uc0b4\ud3b4\ubcf8\ub2e4.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Composable\nfun RallyApp() {\n    <em>RallyTheme <\/em><strong>{\n        <\/strong>val allScreens = RallyScreen.values().<em>toList<\/em>()\n        var <strong>currentScreen<\/strong> by <em>rememberSaveable <\/em><strong>{ <\/strong><em>mutableStateOf<\/em>(RallyScreen.<em>Overview<\/em>) <strong>}\n        <\/strong><em>Scaffold<\/em>(\n            topBar = <strong>{\n                <\/strong><em>RallyTopAppBar<\/em>(\n                    allScreens = allScreens,\n                    onTabSelected = <strong>{ <\/strong>screen <strong>-> <\/strong>currentScreen = screen <strong>}<\/strong>,\n                    currentScreen = currentScreen\n                )\n            <strong>}\n        <\/strong>) <strong>{ <\/strong>innerPadding <strong>->\n            <\/strong><em>Box<\/em>(Modifier.<em>padding<\/em>(innerPadding)) <strong>{\n                <\/strong>currentScreen.content(onScreenChange = <strong>{ <\/strong>screen <strong>-> <\/strong>currentScreen = screen <strong>}<\/strong>)\n            <strong>}\n        }\n    }\n<\/strong>}<\/pre>\n\n\n\n<p>\ucf54\ub4dc\ub97c \uc0b4\ud3b4\ubcf4\uba74 \uccab\ubc88\uc9f8 \ud78c\ud2b8\uc5d0 \ub098\uc628 \uc0c1\ud0dc\uac00 currentScreen\uc784\uc744 \uc54c \uc218 \uc788\ub2e4. currentScreen\uc5d0 \ub530\ub77c RallyTopAppBar\uac00 \uc601\ud5a5\uc744 \ubc1b\uace0 \uc788\uace0, \ub610 RallyTopAppBar\uc758 \ud0ed\uc744 \ud074\ub9ad\ud568\uc5d0 \ub530\ub77c \uc0c1\ud0dc\uac00 \ubcc0\uacbd\ub418\ub294 \uac83\uc744 \uc54c \uc218 \uc788\ub2e4.<\/p>\n\n\n\n<p>RallyApp\uc740 \uc0c1\ud0dc\ub97c \uac16\uace0 \uc788\uae30 \ub54c\ubb38\uc5d0 stateful\ud558\ub2e4. stateful\ud55c \ucef4\ud3ec\uc800\ube14 \ud568\uc218\ub294 \ud14c\uc2a4\ud2b8 \ud558\uae30 \uc5b4\ub835\ub2e4. \ud14c\uc2a4\ud2b8\uc5d0\uc11c \ud574\ub2f9 \uc0c1\ud0dc\uc5d0 \uc561\uc138\uc2a4 \ud558\uae30 \uc5b4\ub835\uae30 \ub54c\ubb38\uc774\ub2e4. \uc0c1\ud0dc\ub97c \ub04c\uc5b4\uc62c\ub824(state hoisting) \ud14c\uc2a4\ud2b8 \uac00\ub2a5\ud558\ub3c4\ub85d \ubcc0\uacbd\ud574\ubcf4\uc790.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">@Composable\nfun RallyApp(<strong>currentScreen:RallyScreen, onTabSelected: (RallyScreen) -> Unit<\/strong>) {\n    <em>RallyTheme <\/em><strong>{\n        <\/strong>val allScreens = RallyScreen.values().<em>toList<\/em>()\n\n        <em>Scaffold<\/em>(\n            topBar = <strong>{\n                <\/strong><em>RallyTopAppBar<\/em>(\n                    allScreens = allScreens,\n                    onTabSelected = <strong>onTabSelected<\/strong>,\n                    currentScreen = currentScreen\n                )\n            <strong>}\n        <\/strong>) <strong>{ <\/strong>innerPadding <strong>->\n            <\/strong><em>Box<\/em>(Modifier.<em>padding<\/em>(innerPadding)) <strong>{\n                <\/strong>currentScreen.content(onScreenChange = <strong>onTabSelected<\/strong>)\n            <strong>}\n        }\n    }\n<\/strong>}<\/pre>\n\n\n\n<blockquote class=\"wp-block-quote\"><p><strong>Note<\/strong>: state hoisting\uc740 \uc0c1\ud0dc\ub97c \ub04c\uc5b4\uc62c\ub9ac\uae30 \uc704\ud55c \uc77c\ubc18\uc801 \ud328\ud134\uc740 \ucef4\ud3ec\uc800\ube14 \ud568\uc218 \ub0b4\uc5d0 \uc120\uc5b8\ub41c \uc0c1\ud0dc \ubcc0\uc218\ub97c \ud574\ub2f9 \ucef4\ud3ec\uc800\ube14 \ud568\uc218\uc758 \ub450 \uac1c\uc758 \ub9e4\uac1c\ubcc0\uc218\ub85c \ubc14\uafb8\ub294 \uac83\uc774\ub2e4.<\/p><p>1. value: T : \ud45c\uc2dc\ud560 \ud604\uc7ac \uac12. \uc704\uc758 \ucf54\ub4dc\uc5d0\uc11c currentScreen\uc5d0 \ud574\ub2f9 <br>2. onValuChange: (T) -> Unit : T\uac00 \uc81c\uc548\ub41c \uc0c8\uac12\uc778 \uacbd\uc6b0 \uac12\uc744 \ubcc0\uacbd\ud558\ub3c4\ub85d \uc694\uccad\ud558\ub294 \uc774\ubca4\ud2b8. \uc704\uc758 \ucf54\ub4dc\uc5d0\uc11c onTabSelected\uc5d0 \ud574\ub2f9<\/p><\/blockquote>\n\n\n\n<p>RallyApp\uc744 \ubcc0\uacbd\ud558\uc600\uc73c\ubbc0\ub85c RallyActivity\uc758 \ucf54\ub4dc\ub3c4 \ub2e4\uc74c\uacfc \uac19\uc774 \ubcc0\uacbd\ud558\uc790.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">class RallyActivity : ComponentActivity() {\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        <em>setContent <\/em><strong>{\n            var currentScreen:RallyScreen by <em>rememberSaveable <\/em>{ <em>mutableStateOf<\/em>(RallyScreen.<em>Overview<\/em>) }\n            <em>RallyApp<\/em>(currentScreen){\n                screen-> currentScreen = screen\n            }\n        }\n    <\/strong>}\n}<\/pre>\n\n\n\n<p>\uc774\uc81c \ud14c\uc2a4\ud2b8 \ucf54\ub4dc\ub97c \uc791\uc131\ud558\uc790.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">...\n@get:Rule\nval composeTestRule = createComposeRule()\n\n@Test\nfun rallyTopAppBarTest_clickTabs(){\n    var currentScreen:RallyScreen = RallyScreen.<em>Overview \/\/ \ud604\uc7ac \uc0c1\ud0dc\n    <\/em>composeTestRule.setContent <strong>{ \ucef4\ud3ec\uc988 \ud14c\uc2a4\ud2b8 \ub8f0\uc5d0 RallyApp \uc124\uc815\ud558\uae30\n        <\/strong><em>RallyApp<\/em>(currentScreen)<strong>{ <\/strong>screen<strong>-> <\/strong>currentScreen = screen <strong>}\n    }\n<\/strong>\n    \/\/<strong> \ubaa8\ub4e0 \ud0ed\uc744 \uc21c\ud68c\ud558\uba74\uc11c \ud074\ub9ad \ud558\uace0 \ud604\uc7ac \uc0c1\ud0dc\ub97c \ud655\uc778\ud55c\ub2e4.\n    <\/strong>RallyScreen.values().<em>forEach <\/em><strong>{ <\/strong>screen<strong>->\n        <\/strong>composeTestRule\n            .<em>onNodeWithContentDescription<\/em>(screen.name)\n            .<em>performClick<\/em>()\n        <em>assert<\/em>(currentScreen == screen)\n    <strong>}\n<\/strong>}<\/pre>\n\n\n\n<p>onNoWithContentDescription \ud30c\uc778\ub354(finder)\ub97c \ud1b5\ud574 \ud2b9\uc815 \ud0ed\uc744 \ucc3e\uace0, performClick()\uc744 \ud638\ucd9c\ud558\uc5ec \ud574\ub2f9 \ud0ed\uc744 \ud074\ub9ad\ud55c\ub2e4. \ud074\ub9ad\ud55c \ud6c4 currentScreen\uc774 \uc62c\ubc14\ub974\uac8c \ubcc0\uacbd\ub418\uc5c8\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uc774 \ub2e8\uacc4\uc5d0\uc11c\ub294 \uc561\uc158(Action)\uc744 \uc0ac\uc6a9\ud558\uc5ec RallyTopAppBar\uc758 \ub2e4\ub978 \ud0ed\uc744 \ud074\ub9ad\ud558\uba74 \uc120\ud0dd \ud56d\ubaa9\uc774 \ubcc0\uacbd\ub418\ub294\uc9c0 \ud655\uc778\ud55c\ub2e4. Action\uc5d0 \ub300\ud55c \ubd80\ubd84\uc740 Testing Cheat Sheet\ub97c \ucc38\uc870\ud558\uc790. \ud78c\ud2b8: \ud14c\uc2a4\ud2b8 \ubc94\uc704\uc5d0\ub294 RallyApp\uc774 \uc18c\uc720\ud55c \uc0c1\ud0dc(State)\uac00 \ud3ec\ud568\ub418\uc5b4\uc57c \ud55c\ub2e4. \ud589\ub3d9(behavior)\uc774 \uc544\ub2c8\ub77c \uc0c1\ud0dc(state)\ub97c \ud655\uc778(verify)\ud558\uc790. \ud638\ucd9c\ub41c \uac1d\uccb4\uc640 \ubc29\ubc95\uc5d0 \uc758\uc874\ud558\ub294 \ub300\uc2e0 UI \uc0c1\ud0dc\uc5d0 \ub300\ud55c \uc8fc\uc7a5(assertion)\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \uc774 \uc5f0\uc2b5\ubb38\uc81c\uc5d0\ub294 \uc81c\uacf5\ub41c \ud574\ub2f5\uc774 \uc5c6\ub2e4. \uc815\ub2f5\uc774 \uc5c6\uc9c0\ub9cc \uc5f4\uc2ec\ud788 \uc5f0\uc2b5\ubb38\uc81c\ub97c [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[38],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45766"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=45766"}],"version-history":[{"count":1,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45766\/revisions"}],"predecessor-version":[{"id":45767,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45766\/revisions\/45767"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=45766"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=45766"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=45766"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}