KS
Killer-Skills

mobile-app-testing — Categories.community

v1.0.0
GitHub

About this Skill

Perfect for Automated Testing Agents needing comprehensive mobile app testing capabilities with Flutter and OpenAPI 📱 1Panel 第三方全平台客户端 (Flutter) | 🖥️ Unofficial 1Panel multi-platform client with free multi-server support (OpenAPI)

# Core Topics

IsKenKenYa IsKenKenYa
[12]
[2]
Updated: 2/24/2026

Quality Score

Top 5%
54
Excellent
Based on code quality & docs
Installation
SYS Universal Install (Auto-Detect)
Cursor IDE Windsurf IDE VS Code IDE
> npx killer-skills add IsKenKenYa/1Panel-Client

Agent Capability Analysis

The mobile-app-testing MCP Server by IsKenKenYa is an open-source Categories.community integration for Claude and other AI agents, enabling seamless task automation and capability expansion. Optimized for 1panel, android, dart.

Ideal Agent Persona

Perfect for Automated Testing Agents needing comprehensive mobile app testing capabilities with Flutter and OpenAPI

Core Value

Empowers agents to implement unit tests, UI tests, integration tests, and performance testing for mobile applications using Jest and Detox, while automating UI testing across iOS and Android with OpenAPI support

Capabilities Granted for mobile-app-testing MCP Server

Automating UI testing for cross-platform mobile apps
Performing integration testing with backend services using OpenAPI
Optimizing mobile app performance with regression testing

! Prerequisites & Limits

  • Requires Flutter and OpenAPI setup
  • Limited to mobile app testing only
SKILL.md
Readonly

Mobile App Testing

Overview

Implement comprehensive testing strategies for mobile applications including unit tests, UI tests, integration tests, and performance testing.

When to Use

  • Creating reliable mobile applications with test coverage
  • Automating UI testing across iOS and Android
  • Performance testing and optimization
  • Integration testing with backend services
  • Regression testing before releases

Instructions

1. React Native Testing with Jest & Detox

javascript
1// Unit test with Jest 2import { calculate } from '../utils/math'; 3 4describe('Math utilities', () => { 5 test('should add two numbers', () => { 6 expect(calculate.add(2, 3)).toBe(5); 7 }); 8 9 test('should handle negative numbers', () => { 10 expect(calculate.add(-2, 3)).toBe(1); 11 }); 12}); 13 14// Component unit test 15import React from 'react'; 16import { render, screen } from '@testing-library/react-native'; 17import { UserProfile } from '../components/UserProfile'; 18 19describe('UserProfile Component', () => { 20 test('renders user name correctly', () => { 21 const mockUser = { id: '1', name: 'John Doe', email: 'john@example.com' }; 22 render(<UserProfile user={mockUser} />); 23 24 expect(screen.getByText('John Doe')).toBeTruthy(); 25 }); 26 27 test('handles missing user gracefully', () => { 28 render(<UserProfile user={null} />); 29 expect(screen.getByText(/no user data/i)).toBeTruthy(); 30 }); 31}); 32 33// E2E Testing with Detox 34describe('Login Flow E2E Test', () => { 35 beforeAll(async () => { 36 await device.launchApp(); 37 }); 38 39 beforeEach(async () => { 40 await device.reloadReactNative(); 41 }); 42 43 it('should login successfully with valid credentials', async () => { 44 await waitFor(element(by.id('emailInput'))) 45 .toBeVisible() 46 .withTimeout(5000); 47 48 await element(by.id('emailInput')).typeText('user@example.com'); 49 await element(by.id('passwordInput')).typeText('password123'); 50 await element(by.id('loginButton')).multiTap(); 51 52 await waitFor(element(by.text('Home Feed'))) 53 .toBeVisible() 54 .withTimeout(5000); 55 }); 56 57 it('should show error with invalid credentials', async () => { 58 await element(by.id('emailInput')).typeText('invalid@example.com'); 59 await element(by.id('passwordInput')).typeText('wrongpass'); 60 await element(by.id('loginButton')).multiTap(); 61 62 await waitFor(element(by.text(/invalid credentials/i))) 63 .toBeVisible() 64 .withTimeout(5000); 65 }); 66 67 it('should navigate between tabs', async () => { 68 await element(by.id('profileTab')).tap(); 69 await waitFor(element(by.text('Profile'))) 70 .toBeVisible() 71 .withTimeout(2000); 72 73 await element(by.id('homeTab')).tap(); 74 await waitFor(element(by.text('Home Feed'))) 75 .toBeVisible() 76 .withTimeout(2000); 77 }); 78});

2. iOS Testing with XCTest

swift
1import XCTest 2@testable import MyApp 3 4class UserViewModelTests: XCTestCase { 5 var viewModel: UserViewModel! 6 var mockNetworkService: MockNetworkService! 7 8 override func setUp() { 9 super.setUp() 10 mockNetworkService = MockNetworkService() 11 viewModel = UserViewModel(networkService: mockNetworkService) 12 } 13 14 func testFetchUserSuccess() async { 15 let expectedUser = User(id: UUID(), name: "John", email: "john@example.com") 16 mockNetworkService.mockUser = expectedUser 17 18 await viewModel.fetchUser(id: expectedUser.id) 19 20 XCTAssertEqual(viewModel.user?.name, "John") 21 XCTAssertNil(viewModel.errorMessage) 22 XCTAssertFalse(viewModel.isLoading) 23 } 24 25 func testFetchUserFailure() async { 26 mockNetworkService.shouldFail = true 27 28 await viewModel.fetchUser(id: UUID()) 29 30 XCTAssertNil(viewModel.user) 31 XCTAssertNotNil(viewModel.errorMessage) 32 XCTAssertFalse(viewModel.isLoading) 33 } 34} 35 36class MockNetworkService: NetworkService { 37 var mockUser: User? 38 var shouldFail = false 39 40 override func fetch<T: Decodable>( 41 _: T.Type, 42 from endpoint: String 43 ) async throws -> T { 44 if shouldFail { 45 throw NetworkError.unknown 46 } 47 return mockUser as! T 48 } 49} 50 51// UI Test 52class LoginUITests: XCTestCase { 53 override func setUp() { 54 super.setUp() 55 continueAfterFailure = false 56 XCUIApplication().launch() 57 } 58 59 func testLoginFlow() { 60 let app = XCUIApplication() 61 62 let emailTextField = app.textFields["emailInput"] 63 let passwordTextField = app.secureTextFields["passwordInput"] 64 let loginButton = app.buttons["loginButton"] 65 66 emailTextField.tap() 67 emailTextField.typeText("user@example.com") 68 69 passwordTextField.tap() 70 passwordTextField.typeText("password123") 71 72 loginButton.tap() 73 74 let homeText = app.staticTexts["Home Feed"] 75 XCTAssertTrue(homeText.waitForExistence(timeout: 5)) 76 } 77 78 func testNavigationBetweenTabs() { 79 let app = XCUIApplication() 80 let profileTab = app.tabBars.buttons["Profile"] 81 let homeTab = app.tabBars.buttons["Home"] 82 83 profileTab.tap() 84 XCTAssertTrue(app.staticTexts["Profile"].exists) 85 86 homeTab.tap() 87 XCTAssertTrue(app.staticTexts["Home"].exists) 88 } 89}

3. Android Testing with Espresso

kotlin
1@RunWith(AndroidJUnit4::class) 2class UserViewModelTest { 3 private lateinit var viewModel: UserViewModel 4 private val mockApiService = mock<ApiService>() 5 6 @Before 7 fun setUp() { 8 viewModel = UserViewModel(mockApiService) 9 } 10 11 @Test 12 fun fetchUserSuccess() = runTest { 13 val expectedUser = User("1", "John", "john@example.com") 14 `when`(mockApiService.getUser("1")).thenReturn(expectedUser) 15 16 viewModel.fetchUser("1") 17 18 assertEquals(expectedUser.name, viewModel.user.value?.name) 19 assertEquals(null, viewModel.errorMessage.value) 20 } 21 22 @Test 23 fun fetchUserFailure() = runTest { 24 `when`(mockApiService.getUser("1")) 25 .thenThrow(IOException("Network error")) 26 27 viewModel.fetchUser("1") 28 29 assertEquals(null, viewModel.user.value) 30 assertNotNull(viewModel.errorMessage.value) 31 } 32} 33 34// UI Test with Espresso 35@RunWith(AndroidJUnit4::class) 36class LoginActivityTest { 37 @get:Rule 38 val activityRule = ActivityScenarioRule(LoginActivity::class.java) 39 40 @Test 41 fun testLoginWithValidCredentials() { 42 onView(withId(R.id.emailInput)) 43 .perform(typeText("user@example.com")) 44 45 onView(withId(R.id.passwordInput)) 46 .perform(typeText("password123")) 47 48 onView(withId(R.id.loginButton)) 49 .perform(click()) 50 51 onView(withText("Home")) 52 .check(matches(isDisplayed())) 53 } 54 55 @Test 56 fun testLoginWithInvalidCredentials() { 57 onView(withId(R.id.emailInput)) 58 .perform(typeText("invalid@example.com")) 59 60 onView(withId(R.id.passwordInput)) 61 .perform(typeText("wrongpassword")) 62 63 onView(withId(R.id.loginButton)) 64 .perform(click()) 65 66 onView(withText(containsString("Invalid credentials"))) 67 .check(matches(isDisplayed())) 68 } 69 70 @Test 71 fun testNavigationBetweenTabs() { 72 onView(withId(R.id.profileTab)).perform(click()) 73 onView(withText("Profile")).check(matches(isDisplayed())) 74 75 onView(withId(R.id.homeTab)).perform(click()) 76 onView(withText("Home")).check(matches(isDisplayed())) 77 } 78}

4. Performance Testing

swift
1import XCTest 2 3class PerformanceTests: XCTestCase { 4 func testListRenderingPerformance() { 5 let viewModel = ItemsViewModel() 6 viewModel.items = (0..<1000).map { i in 7 Item(id: UUID(), title: "Item \(i)", price: Double(i)) 8 } 9 10 measure { 11 _ = viewModel.items.filter { $0.price > 50 } 12 } 13 } 14 15 func testNetworkResponseTime() { 16 let networkService = NetworkService() 17 18 measure { 19 let expectation = XCTestExpectation(description: "Fetch user") 20 21 Task { 22 do { 23 _ = try await networkService.fetch(User.self, from: "/users/test") 24 expectation.fulfill() 25 } catch { 26 XCTFail("Network request failed") 27 } 28 } 29 30 wait(for: [expectation], timeout: 10) 31 } 32 } 33}

Best Practices

✅ DO

  • Write tests for business logic first
  • Use dependency injection for testability
  • Mock external API calls
  • Test both success and failure paths
  • Automate UI testing for critical flows
  • Run tests on real devices
  • Measure performance on target devices
  • Keep tests isolated and independent
  • Use meaningful test names
  • Maintain >80% code coverage

❌ DON'T

  • Skip testing UI-critical flows
  • Use hardcoded test data
  • Ignore performance regressions
  • Test implementation details
  • Make tests flaky or unreliable
  • Skip testing on actual devices
  • Ignore accessibility testing
  • Create interdependent tests
  • Test without mocking APIs
  • Deploy untested code

Related Skills

Looking for an alternative to mobile-app-testing or building a Categories.community AI Agent? Explore these related open-source MCP Servers.

View All

widget-generator

Logo of f
f

f.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.

149.6k
0
Design

flags

Logo of vercel
vercel

flags is a Next.js feature management skill that enables developers to efficiently add or modify framework feature flags, streamlining React application development.

138.4k
0
Browser

zustand

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication

data-fetching

Logo of lobehub
lobehub

The ultimate space for work and life — to find, build, and collaborate with agent teammates that grow with you. We are taking agent harness to the next level — enabling multi-agent collaboration, effortless agent team design, and introducing agents as the unit of work interaction.

72.8k
0
Communication