Sử dụng Monkey để kiểm thử ngẫu nhiên
Monkey là công cụ dòng lệnh giúp tạo hành vi người dùng ngẫu nhiên trên ứng dụng Android. Dưới đây là một số ví dụ cơ bản:
adb shell monkey -p com.lqr.wechat -v 500 > log1.txt
adb shell monkey -p com.lqr.wechat -vvv 5000 > log2.txt
adb shell monkey -p com.lqr.wechat -vvv 5000 --seed=1556166765229 --throttle 500 > log3.txt
adb shell monkey -p com.lqr.wechat -vvv 5000 --seed=1556166765229 --ignore-crashes > log4.txt
Các tham số phổ biến
-p: Chỉ định package ứng dụng-v: Mức độ ghi log (có thể lặp lại để tăng chi tiết)--seed: Thiết lập hạt giống để tái hiện kịch bản--throttle: Thời gian chờ giữa các sự kiện (ms)--ignore-crashes: Tiếp tục khi ứng dụng crash--ignore-timeouts: Bỏ qua ANR (Application Not Responding)--kill-process-after-error: Kết thúc tiến trình sau lỗi--monitor-native-crashes: Theo dõi lỗi native
Tùy chỉnh tỷ lệ sự kiện
--pct-touch # Sự kiện chạm (click)
--pct-motion # Sự kiện vuốt kéo
--pct-trackball # Di chuyển trackball
--pct-nav # Điều hướng cơ bản (lên/xuống/trái/phải)
--pct-majornav # Nút điều hướng chính (quay lại, menu, OK)
--pct-syskeys # Phím hệ thống (Home, Back, Volume...)
--pct-appswitch # Chuyển đổi ứng dụng
--pct-anyevent # Sự kiện bất kỳ
Dừng Monkey thủ công
adb shell
ps | grep monkey
kill [PID]
Sử dụng Appium Inspector
Công cụ này hỗ trợ xác định phần tử giao diện và ghi lại thao tác tương tác.
- Khởi động và cấu hình phiên làm việc
- Xác định vị trí phần tử bằng nhiều phương pháp
- Ghi lại chuỗi hành động để tái sử dụng
Định vị phần tử trong Appium
Có nhiều cách để truy vấn phần tử giao diện:
# Theo ID tài nguyên
element = driver.find_element(By.ID, "resource_id")
# Theo mô tả truy cập
element = driver.find_element(By.ACCESSIBILITY_ID, "description")
# Theo XPath
element = driver.find_element(By.XPATH, "//android.widget.TextView[@text='Login']")
# Tìm nhiều phần tử + chỉ mục
elements = driver.find_elements(By.CLASS_NAME, "android.widget.Button")
elements[1].click()
# Định vị lồng ghép
parent = driver.find_element(By.ID, "container")
child = parent.find_element(By.CLASS_NAME, "item")
Sử dụng UiSelector (Android UI Automator)
# Theo ID
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiSelector().resourceId("com.example:id/button")')
# Theo nội dung văn bản
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiSelector().text("Đăng nhập")')
# Văn bản chứa chuỗi con
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiSelector().textContains("Nhập")')
# Nhiều điều kiện kết hợp
driver.find_element(AppiumBy.ANDROID_UIAUTOMATOR,
'new UiSelector().className("android.widget.TextView").text("Tùy chỉnh")')
Thao tác với phần tử
element.click() # Nhấn vào phần tử
element.send_keys("nội dung") # Nhập liệu
element.clear() # Xóa nội dung
element.is_displayed() # Kiểm tra hiển thị
element.get_attribute("text") # Lấy thuộc tính
element.text # Lấy nội dung văn bản
element.location # Tọa độ phần tử
element.size # Kích thước phần tử
Ví dụ thực hành: Kiểm tra trạng thái đăng nhập WeChat
try:
login_btn = driver.find_element(By.ID, "login_button")
print("Tìm thấy nút đăng nhập")
print(f"Text: {login_btn.text}")
print(f"Enabled: {login_btn.is_enabled()}")
login_btn.click()
# Nhập thông tin
username_field = driver.find_element(By.ID, "username")
password_field = driver.find_element(By.ID, "password")
username_field.send_keys("user123")
password_field.send_keys("pass456")
submit_btn = driver.find_element(By.ID, "submit_login")
if submit_btn.is_enabled():
submit_btn.click()
try:
contacts_tab = driver.find_element(By.XPATH, "//*[contains(@text, 'Liên hệ')]")
print("Đăng nhập thành công!")
except:
print("Đăng nhập thất bại!")
else:
print("Nút đăng nhập không khả dụng")
except NoSuchElementException:
print("Đã đăng nhập - Truy cập tab Liên hệ")
contacts = driver.find_element(By.XPATH, "//*[contains(@text, 'Liên hệ')]")
print(f"Resource ID: {contacts.get_attribute('resource-id')}")
print(f"Class: {contacts.get_attribute('class-name')}")
print(f"Có thể nhấn: {contacts.is_enabled()}")
finally:
driver.quit()
Thao tác bàn phím và thiết bị
driver.press_keycode(4) # Nút Back
driver.press_keycode(3) # Nút Home
driver.press_keycode(24) # Tăng âm lượng
driver.press_keycode(25) # Giảm âm lượng
Bài tập: Đăng nhập → Quét mã QR → Chụp ảnh → Quay lại màn hình chính
# Đăng nhập
driver.find_element(By.ID, "username").send_keys("18010181267")
driver.find_element(By.ID, "password").send_keys("123456")
driver.find_element(By.ID, "login_btn").click()
# Vào trang cá nhân → Mã QR
driver.find_element(By.XPATH, "//*[contains(@text, 'Tôi')]").click()
driver.find_element(By.XPATH, "//*[contains(@text, 'Mã QR')]").click()
# Chụp màn hình
driver.save_screenshot("d:/screenshot/VCODE.png")
# Đẩy file vào thiết bị
driver.push_file("/sdcard/images/VCODE.png", "d:/screenshot/VCODE.png")
# Quay lại + tăng âm lượng + về home
driver.press_keycode(4)
driver.press_keycode(24)
driver.press_keycode(24)
driver.press_keycode(3)
Thao tác màn hình cảm ứng
# Lấy kích thước màn hình
screen = driver.get_window_size()
width = screen['width']
height = screen['height']
# Vuốt màn hình
def swipe_up():
driver.swipe(width*0.5, height*0.8, width*0.5, height*0.2, 500)
def swipe_down():
driver.swipe(width*0.5, height*0.2, width*0.5, height*0.8, 500)
def swipe_left():
driver.swipe(width*0.8, height*0.5, width*0.2, height*0.5, 500)
def swipe_right():
driver.swipe(width*0.2, height*0.5, width*0.8, height*0.5, 500)
Bài tập: Tìm mục "Giới thiệu" trong Cài đặt
driver.start_activity("com.android.settings", ".Settings")
found = False
while not found:
try:
about = driver.find_element(By.XPATH, "//*[contains(@text, 'Giới thiệu')]")
about.click()
found = True
except:
swipe_up()
time.sleep(1)
# Lấy thông tin phiên bản
version = driver.find_element(By.XPATH, "//*[contains(@text, 'Phiên bản')]")
print(f"Phiên bản hệ thống: {version.text}")
driver.quit()
Quản lý ứng dụng và tệp tin
# Kiểm tra ứng dụng đã cài
if driver.is_app_installed("com.tencent.mm"):
driver.remove_app("com.tencent.mm")
else:
driver.install_app("/path/to/wechat.apk")
# Khởi chạy ứng dụng
driver.launch_app()
driver.start_activity("com.android.browser", ".BrowserActivity")
# Chuyển nền
driver.background_app(5)
# Lấy activity hiện tại
current = driver.current_activity
print(f"Activity hiện tại: {current}")
# Thao tác tệp tin
driver.pull_file("/sdcard/test.txt", "local_test.txt")
driver.push_file("/sdcard/upload.txt", "local_content.txt")
Trạng thái mạng
network = driver.network_connection
print(f"Trạng thái mạng: {network}")
# Các giá trị có thể:
# 0: Không có kết nối
# 1: Chỉ dữ liệu di động
# 2: Chỉ WiFi
# 4: Airplane mode
# 6: WiFi + Airplane
Tìm Activity chính của ứng dụng
adb shell
logcat | grep cmp=
# Sau đó mở ứng dụng trên thiết bị để xem log