mobile-app-testing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseMobile App Testing
移动应用测试
Implement comprehensive testing strategies for mobile applications.
为移动应用实施全面的测试策略。
Testing Pyramid
测试金字塔
| Level | Tools | Coverage |
|---|---|---|
| Unit | Jest, XCTest, JUnit | 70% |
| Integration | Detox, Espresso | 20% |
| E2E | Appium, Detox | 10% |
| 层级 | 工具 | 覆盖率 |
|---|---|---|
| 单元测试 | Jest, XCTest, JUnit | 70% |
| 集成测试 | Detox, Espresso | 20% |
| 端到端测试 | Appium, Detox | 10% |
React Native (Jest + Detox)
React Native(Jest + Detox)
javascript
// Unit test
describe('CartService', () => {
it('calculates total correctly', () => {
const cart = new CartService();
cart.addItem({ price: 10, quantity: 2 });
expect(cart.getTotal()).toBe(20);
});
});
// E2E test (Detox)
describe('Login flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should login successfully', async () => {
await element(by.id('email-input')).typeText('user@example.com');
await element(by.id('password-input')).typeText('password123');
await element(by.id('login-button')).tap();
await expect(element(by.id('dashboard'))).toBeVisible();
});
});javascript
// Unit test
describe('CartService', () => {
it('calculates total correctly', () => {
const cart = new CartService();
cart.addItem({ price: 10, quantity: 2 });
expect(cart.getTotal()).toBe(20);
});
});
// E2E test (Detox)
describe('Login flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should login successfully', async () => {
await element(by.id('email-input')).typeText('user@example.com');
await element(by.id('password-input')).typeText('password123');
await element(by.id('login-button')).tap();
await expect(element(by.id('dashboard'))).toBeVisible();
});
});iOS (XCTest)
iOS(XCTest)
swift
func testLoginSuccess() {
let app = XCUIApplication()
app.launch()
app.textFields["email"].tap()
app.textFields["email"].typeText("user@example.com")
app.secureTextFields["password"].typeText("password123")
app.buttons["Login"].tap()
XCTAssertTrue(app.staticTexts["Welcome"].exists)
}swift
func testLoginSuccess() {
let app = XCUIApplication()
app.launch()
app.textFields["email"].tap()
app.textFields["email"].typeText("user@example.com")
app.secureTextFields["password"].typeText("password123")
app.buttons["Login"].tap()
XCTAssertTrue(app.staticTexts["Welcome"].exists)
}Android (Espresso)
Android(Espresso)
kotlin
@Test
fun loginSuccess() {
onView(withId(R.id.email)).perform(typeText("user@example.com"))
onView(withId(R.id.password)).perform(typeText("password123"))
onView(withId(R.id.loginButton)).perform(click())
onView(withId(R.id.dashboard)).check(matches(isDisplayed()))
}kotlin
@Test
fun loginSuccess() {
onView(withId(R.id.email)).perform(typeText("user@example.com"))
onView(withId(R.id.password)).perform(typeText("password123"))
onView(withId(R.id.loginButton)).perform(click())
onView(withId(R.id.dashboard)).check(matches(isDisplayed()))
}Best Practices
最佳实践
- Test business logic first (unit tests)
- Mock external dependencies
- Test both success and failure paths
- Automate critical user flows
- Maintain >80% code coverage
- Test on real devices periodically
- 优先测试业务逻辑(单元测试)
- 模拟外部依赖
- 同时测试成功和失败路径
- 自动化关键用户流程
- 保持代码覆盖率>80%
- 定期在真实设备上测试
Avoid
需避免的情况
- Testing implementation details
- Hardcoded test data
- Interdependent tests
- Skipping error case testing
- 测试实现细节
- 硬编码测试数据
- 相互依赖的测试用例
- 跳过错误场景测试