다중 화면 사용자 여정 테스트
inputText와 tapOn을 사용하여 각 단계를 진행하면서 여러 화면에 걸친 가입, 온보딩 및 핵심 기능 사용을 다루는 Maestro 흐름을 작성합니다.
다중 화면 사용자 여정 테스트은(는) CoddyKit의 무료 React Native Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 React Native Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
What Is a Multi-Screen User Journey?
A user journey is a sequence of interactions that spans multiple screens to accomplish a meaningful goal. Examples include the registration journey (onboarding → email signup → profile setup → home), the purchase journey (browse → add to cart → checkout → confirmation), and the content creation journey (home → compose → preview → post).
E2E tests that cover complete journeys provide the most value because they verify that all the pieces of your app work together correctly. A unit test can confirm that a form validates correctly, but only a journey test confirms that a validated form actually navigates to the next screen.
Planning a Journey Flow
Before writing the YAML, sketch the journey on paper: which screens appear, what the user taps or types on each screen, and what the expected final state is. Identify the happy path first — the normal flow without errors — then add edge case flows for error states.
Break the journey into logical phases and comment your YAML accordingly. Comments in YAML start with #. Clear comments make the flow readable to teammates who did not write it and help you debug which phase failed when the test reports an error.
# Journey: User Registration and First Login
# Phase 1: Onboarding
# Phase 2: Sign Up Form
# Phase 3: Email Verification (mocked in dev build)
# Phase 4: Profile Setup
# Phase 5: Home Screen Verification
appId: com.example.myapp
---
# Phase 1: Onboarding
- launchApp:
clearState: true
- assertVisible:
text: 'Welcome'
- tapOn:
text: 'Create Account'The Registration Journey Flow
The registration journey walks through the sign-up form, validates the confirmation screen, and verifies that the user lands on the home screen. Use the env section to parameterize test data so you can run the same flow with different users by changing just the environment variables.
Each phase ends with an assertVisible to confirm the transition was successful before starting the next phase. This gives you precise failure location in the test report — you know exactly which screen transition failed.
appId: com.example.myapp
env:
TEST_EMAIL: testuser@example.com
TEST_PASSWORD: TestPass123!
TEST_NAME: Test User
---
# Phase 1: Open sign-up form
- launchApp:
clearState: true
- tapOn:
text: 'Create Account'
- assertVisible:
text: 'Create your account'
# Phase 2: Fill in the form
- tapOn:
id: 'name-input'
- inputText: '${TEST_NAME}'
- tapOn:
id: 'email-input'
- inputText: '${TEST_EMAIL}'
- tapOn:
id: 'password-input'
- inputText: '${TEST_PASSWORD}'
- tapOn:
text: 'Sign Up'
# Phase 3: Verify success screen
- assertVisible:
text: 'Account Created'
timeout: 8000The Login and Content Browse Journey
A common journey is: log in, browse a list, open an item, interact with it, and go back. This tests navigation forward and backward, data loading on each screen, and the interaction on the detail screen.
Use the back command to simulate pressing the device back button on Android. On iOS, swipe back or tap the back button with tapOn: text: 'Back'. Test both directions of navigation to catch bugs where going back leaves the app in a broken state.
appId: com.example.myapp
---
- launchApp
- runFlow: subflows/login.yaml
# Browse the feed
- assertVisible:
text: 'Latest Posts'
timeout: 8000
- scroll:
direction: DOWN
# Open a post
- tapOn:
text: 'Top 10 React Native Tips'
- waitForAnimationToEnd
- assertVisible:
text: 'Top 10 React Native Tips'
# Like the post
- tapOn:
id: 'like-button'
- assertVisible:
id: 'liked-indicator'
# Go back
- back
- assertVisible:
text: 'Latest Posts'Testing Tab Navigation
Apps with bottom tab navigators require testing that each tab opens the correct screen. Test the initial tab, switch to each other tab, verify the content loads, and switch back. This catches wiring bugs where tabs navigate to the wrong screen.
Use tapOn with the tab label text or the id of the tab bar button. After switching tabs, always assert on unique content that confirms the correct tab is active.
# Test all three tabs of the main navigator
- launchApp
- runFlow: subflows/login.yaml
# Tab 1: Home (default)
- assertVisible:
text: 'Your Feed'
# Tab 2: Search
- tapOn:
id: 'tab-search'
- waitForAnimationToEnd
- assertVisible:
id: 'search-input'
# Tab 3: Profile
- tapOn:
id: 'tab-profile'
- waitForAnimationToEnd
- assertVisible:
text: 'My Profile'
# Return to Tab 1
- tapOn:
id: 'tab-home'
- assertVisible:
text: 'Your Feed'Testing Form Error Paths
Journey tests should cover both the happy path and the error path. A separate flow for the error path verifies that validation errors appear correctly, the user can fix them, and the form successfully submits after correction.
This catches bugs like: error messages not appearing, form not re-enabling after a failed submission, or validation not re-running after the user fixes an input. These bugs are hard to find without an E2E test because they require multiple interactive steps to reproduce.
# Error path: submit empty form, fix errors, succeed
appId: com.example.myapp
---
- launchApp
- tapOn:
text: 'Sign In'
# Submit without filling in fields
- tapOn:
text: 'Submit'
- assertVisible:
text: 'Email is required'
- assertVisible:
text: 'Password is required'
# Fill in email only
- tapOn:
id: 'email-input'
- inputText: 'user@example.com'
- tapOn:
text: 'Submit'
- assertNotVisible:
text: 'Email is required'
- assertVisible:
text: 'Password is required'
# Complete the form
- tapOn:
id: 'password-input'
- inputText: 'correctpassword'
- tapOn:
text: 'Submit'
- assertVisible:
text: 'Home'
timeout: 8000Handling Modals in Journeys
Modals and bottom sheets block interaction with the underlying screen. Test that modals appear correctly, contain the expected content, and dismiss properly. After dismissing a modal, assert that the underlying screen is still in the correct state.
For confirmation dialogs (like delete confirmation), test both paths: tapping Confirm to complete the action and tapping Cancel to abort it. The Cancel path is often untested and frequently has bugs.
# Test delete with confirmation dialog
- tapOn:
id: 'delete-button'
# Confirm dialog appears
- assertVisible:
text: 'Delete Post?'
- assertVisible:
text: 'This action cannot be undone'
# Cancel path: dismiss dialog
- tapOn:
text: 'Cancel'
- assertNotVisible:
text: 'Delete Post?'
- assertVisible:
text: 'My Post Title' # Post still exists
# Now actually delete
- tapOn:
id: 'delete-button'
- tapOn:
text: 'Delete'
- assertNotVisible:
text: 'My Post Title' # Post is gone
timeout: 5000Using Environment Variables for Test Data
Hard-coding test data in flows makes them fragile when the test account changes or the app requires unique data per run. Use Maestro's env section at the top of the flow file to define variables, and pass them on the command line to override them at runtime.
You can also pass env variables from CI systems using command-line arguments. This lets you use different test accounts or API endpoints for different environments without changing the YAML files.
# Define defaults in the flow file
env:
BASE_URL: https://api.dev.example.com
TEST_EMAIL: ci_test@example.com
TEST_PASSWORD: CI_Password_2024
# Override at runtime from the command line:
maestro test \
-e TEST_EMAIL=prod_test@example.com \
-e TEST_PASSWORD=ProdPass123 \
maestro/flows/login.yaml
# In CI (GitHub Actions):
# - name: Run Maestro tests
# env:
# TEST_EMAIL: ${{ secrets.TEST_EMAIL }}
# run: maestro test -e TEST_EMAIL=$TEST_EMAIL maestro/flows/Testing Deep Links in Journeys
Deep links open your app directly at a specific screen. Test them in Maestro by using the openLink command to trigger the deep link URL and then asserting that the app opened to the correct screen.
Deep link tests verify that your app handles incoming URLs correctly and navigates to the right place. They also confirm that the screen renders correctly when navigated to directly (without passing through the normal navigation flow).
# Test deep link opens the correct post
- launchApp
- runFlow: subflows/login.yaml
# Open a deep link to a specific post
- openLink: 'myapp://posts/post-id-123'
- waitForAnimationToEnd
# Assert we are on the correct post detail screen
- assertVisible:
text: 'Deep Link Post Title'
timeout: 8000
# Verify back navigation works after deep link
- back
- assertVisible:
text: 'Home'Organizing Flows by Feature
As your test suite grows, organize flows in directories by feature rather than by screen. This makes it easy to run all tests for a specific feature and to find the relevant test when a feature breaks.
A recommended directory structure: maestro/flows/auth/ for authentication flows, maestro/flows/feed/ for feed features, maestro/flows/profile/ for profile features, and maestro/flows/subflows/ for shared steps. Run a specific feature with maestro test maestro/flows/auth/.
maestro/
flows/
auth/
registration.yaml
login.yaml
password-reset.yaml
logout.yaml
feed/
browse.yaml
like-post.yaml
create-post.yaml
profile/
view-profile.yaml
edit-profile.yaml
subflows/
login.yaml
logout.yaml
dismiss-permission-dialog.yamlMaintaining Journey Tests Long-Term
E2E tests are the most expensive tests to maintain because UI changes break them even when the logic is correct. Minimize maintenance by: querying by semantic content (user-visible text) instead of implementation details (component IDs), keeping flows focused on critical paths, and extracting reusable steps into subflows.
When a flow breaks after a UI redesign, update the query in the tapOn or assertVisible to match the new text or ID. The test logic itself often does not change — only the selector. This is a feature, not a bug: the test caught that the UI changed in a user-facing way.
Quick Check
Test your understanding of React Native Mobile Development concepts from this lesson.
Lesson Recap
In this lesson you learned: how to plan and write multi-screen journey flows that test complete features end to end, how to test both happy paths and error paths including form validation and confirmation dialogs, and how to organize flows by feature for a maintainable E2E test suite. Next up we integrate Maestro tests into a GitHub Actions CI pipeline to catch regressions automatically on every pull request.
자주 묻는 질문
“다중 화면 사용자 여정 테스트” 강의는 무료인가요?
네 — “다중 화면 사용자 여정 테스트” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 React Native Academy 강의 전체를 잠금 해제할 수 있습니다. React Native Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“다중 화면 사용자 여정 테스트”에서 뭘 배우나요?
inputText와 tapOn을 사용하여 각 단계를 진행하면서 여러 화면에 걸친 가입, 온보딩 및 핵심 기능 사용을 다루는 Maestro 흐름을 작성합니다. 브라우저에서 직접 실행하는 실습 코드로 React Native Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
React Native Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 React Native Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“다중 화면 사용자 여정 테스트” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 React Native Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 React Native Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.