最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Android端驗(yàn)證碼自動(dòng)獲取與填充的實(shí)戰(zhàn)方案

 更新時(shí)間:2025年08月29日 08:33:05   作者:chunchun1221  
在移動(dòng)應(yīng)用自動(dòng)化測(cè)試過程中,我們經(jīng)常會(huì)遇到一個(gè)棘手的問題:正式環(huán)境的接口由于安全考慮,不愿意向測(cè)試團(tuán)隊(duì)開放測(cè)試賬號(hào),傳統(tǒng)的解決方案要么依賴mock數(shù)據(jù)要么手動(dòng)查看手機(jī)短信并輸入驗(yàn)證碼,針對(duì)這一痛點(diǎn),我開發(fā)了一個(gè)基于ADB的Android短信驗(yàn)證碼自動(dòng)獲取工具

解決正式環(huán)境測(cè)試賬號(hào)受限的優(yōu)雅方案

背景與痛點(diǎn)

在移動(dòng)應(yīng)用自動(dòng)化測(cè)試過程中,我們經(jīng)常會(huì)遇到一個(gè)棘手的問題:正式環(huán)境的接口由于安全考慮,不愿意向測(cè)試團(tuán)隊(duì)開放測(cè)試賬號(hào)。這意味著我們需要使用真實(shí)賬號(hào)進(jìn)行測(cè)試,而其中最麻煩的環(huán)節(jié)就是驗(yàn)證碼的獲取與填寫。

傳統(tǒng)的解決方案要么依賴mock數(shù)據(jù)(在正式環(huán)境不可行),要么手動(dòng)查看手機(jī)短信并輸入驗(yàn)證碼(效率低下且無法自動(dòng)化)。針對(duì)這一痛點(diǎn),我開發(fā)了一個(gè)基于ADB的Android短信驗(yàn)證碼自動(dòng)獲取工具,完美解決了正式環(huán)境下的驗(yàn)證碼自動(dòng)化測(cè)試問題。

技術(shù)方案概述

本方案的核心思路是通過ADB命令訪問Android系統(tǒng)的短信內(nèi)容提供器(Content Provider),獲取短信內(nèi)容后通過正則表達(dá)式提取驗(yàn)證碼,最后自動(dòng)填充到應(yīng)用輸入框中。

主要技術(shù)組件:

  • ADB命令操作
  • Android Content Provider訪問
  • 正則表達(dá)式匹配
  • 自動(dòng)化測(cè)試集成

核心代碼實(shí)現(xiàn)

短信工具類 (SmsUtils)

import subprocess
import time
import re
from utils.logger_until import Logger

class SmsUtils:
    def __init__(self):
        self.logger = Logger(name=__name__).logger

    def get_sms_data_from_device(self):
        """從安卓設(shè)備讀取所有短信"""
        command = "adb shell content query --uri content://sms/inbox --projection _id,address,date,body"
        result = subprocess.run(command, shell=True, capture_output=True, text=True, encoding="utf-8")
        
        if result.returncode != 0:
            raise Exception("設(shè)備獲取短信失敗,請(qǐng)檢查ADB連接")
        
        # 解析短信數(shù)據(jù)
        parsed_sms = []
        for line in result.stdout.splitlines():
            sms_dict = {}
            for item in line.split(","):
                key_value = item.split("=")
                if len(key_value) == 2:
                    sms_dict[key_value[0].strip()] = key_value[1].strip()
            parsed_sms.append(sms_dict)
        
        return parsed_sms

    @staticmethod
    def filter_sms_by_keyword(sms_data, keyword):
        """根據(jù)關(guān)鍵字篩選短信"""
        return [sms for sms in sms_data if keyword in sms.get("body", "")]

    def get_latest_sms_by_timestamp(self, sms_data):
        """獲取最新時(shí)間戳的短信"""
        sms_data_with_date = [sms for sms in sms_data if 'date' in sms]
        sorted_sms = sorted(sms_data_with_date, key=lambda x: int(x['date']), reverse=True)
        
        if not sorted_sms:
            return None
            
        # 驗(yàn)證短信時(shí)效性(10分鐘內(nèi))
        latest_sms = sorted_sms[0]
        sms_timestamp = int(latest_sms['date'])
        current_timestamp = int(time.time() * 1000)
        time_diff = current_timestamp - sms_timestamp
        
        if time_diff <= 600000:  # 10分鐘
            return latest_sms
        else:
            self.logger.error(f"驗(yàn)證碼已過期,時(shí)間差:{time_diff//60000}分鐘")
            return False

    def extract_verification_code(self, sms_body):
        """從短信內(nèi)容提取驗(yàn)證碼"""
        try:
            if isinstance(sms_body, dict):
                number_body = str(sms_body.get("body", ""))
                self.logger.info(f"原始短信內(nèi)容: {number_body}")
                match = re.search(r"\d{6}", number_body)
                if match:
                    return match.group(0)
            return None
        except Exception as e:
            self.logger.error(f"驗(yàn)證碼提取錯(cuò)誤: {e}")
            raise

    @staticmethod
    def get_latest_verification_code(keyword="魔意科技"):
        """獲取最新驗(yàn)證碼(整合方法)"""
        sms = SmsUtils()
        sms_data = sms.get_sms_data_from_device()
        filtered_sms = sms.filter_sms_by_keyword(sms_data, keyword)
        latest_sms = sms.get_latest_sms_by_timestamp(filtered_sms)
        
        if latest_sms:
            return sms.extract_verification_code(latest_sms)
        else:
            return False

登錄頁面集成 (LoginPage)

import time
from functools import wraps
from utils.sms_util import SmsUtils

# 重試裝飾器
def retry(times=3, delay=2):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            last_exception = None
            for attempt in range(times):
                try:
                    return func(*args, **kwargs)
                except Exception as e:
                    last_exception = e
                    time.sleep(delay)
                    print(f"第{attempt+1}次重試失敗,剩余{times - attempt - 1}次重試")
            if last_exception:
                raise last_exception
        return wrapper
    return decorator

class LoginPage(BasePage):
    def __init__(self, device_manager):
        super().__init__(device_manager)
        self.logger = Logger(name=__name__).logger
    
    @retry(times=3, delay=15)
    def auto_fill_verification_code(self, keyword="魔意科技"):
        """自動(dòng)填充驗(yàn)證碼(帶重試機(jī)制)"""
        verification_code = SmsUtils.get_latest_verification_code(keyword)
        if verification_code:
            self.logger.info(f"驗(yàn)證碼提取成功: {verification_code}")
            self.input_text("phone_code_input", verification_code)
            self.logger.info(f"驗(yàn)證碼已自動(dòng)填充")
        else:
            self.logger.error("未找到有效驗(yàn)證碼")
            raise ValueError("驗(yàn)證碼提取失敗")
    
    def _perform_login_flow(self, account: str, locator_prefix: str):
        """執(zhí)行登錄流程"""
        # 確保在正確的登錄方式頁面
        if not self.assert_element_visible(f"{locator_prefix}_input"):
            self.click_element(f"switch_to_{locator_prefix}")
        
        # 輸入賬號(hào)并獲取驗(yàn)證碼
        self.input_text(f"{locator_prefix}_input", account)
        self.click_element("phone_code_get_captcha")
        
        # 等待并自動(dòng)填充驗(yàn)證碼
        time.sleep(10)  # 等待短信發(fā)送
        self.auto_fill_verification_code()
        
        # 后續(xù)登錄操作...

關(guān)鍵技術(shù)點(diǎn)解析

1. ADB訪問短信內(nèi)容提供器

通過adb shell content query命令直接訪問Android系統(tǒng)的短信數(shù)據(jù)庫,這是本方案的核心:

adb shell content query --uri content://sms/inbox --projection _id,address,date,body

2. 短信時(shí)效性驗(yàn)證

考慮到驗(yàn)證碼的有效期,我們添加了時(shí)間戳檢查邏輯,確保只使用10分鐘內(nèi)的最新驗(yàn)證碼。

3. 重試機(jī)制

通過裝飾器實(shí)現(xiàn)了優(yōu)雅的重試機(jī)制,應(yīng)對(duì)短信延遲到達(dá)的情況,提高測(cè)試穩(wěn)定性。

4. 關(guān)鍵字過濾

支持通過關(guān)鍵字過濾短信,確保獲取到的是目標(biāo)應(yīng)用發(fā)送的驗(yàn)證碼,避免其他短信干擾。

應(yīng)用效果與價(jià)值

  1. 完全自動(dòng)化:解決了正式環(huán)境驗(yàn)證碼測(cè)試的最后一公里問題
  2. 提高效率:無需人工干預(yù)查看和輸入驗(yàn)證碼
  3. 增強(qiáng)穩(wěn)定性:重試機(jī)制和時(shí)效驗(yàn)證確保測(cè)試可靠性
  4. 易于集成:模塊化設(shè)計(jì),可以輕松集成到現(xiàn)有測(cè)試框架中

注意事項(xiàng)與優(yōu)化方向

  1. 權(quán)限要求:需要授予應(yīng)用讀取短信的權(quán)限(Android 6.0+需要?jiǎng)討B(tài)申請(qǐng))
  2. 兼容性:不同Android版本短信數(shù)據(jù)庫結(jié)構(gòu)可能略有差異
  3. 安全考慮:正式環(huán)境中使用需注意隱私保護(hù)問題
  4. 擴(kuò)展性:可考慮支持多種驗(yàn)證碼格式(4位、8位等)

未來可考慮擴(kuò)展為支持多種驗(yàn)證方式(郵箱驗(yàn)證碼、語音驗(yàn)證碼等)的統(tǒng)一驗(yàn)證碼獲取平臺(tái)。

結(jié)語

這個(gè)Android驗(yàn)證碼自動(dòng)獲取方案已經(jīng)在我們項(xiàng)目中穩(wěn)定運(yùn)行,大大提升了正式環(huán)境自動(dòng)化測(cè)試的效率和可靠性。希望這個(gè)方案對(duì)大家有所啟發(fā),也歡迎交流更好的實(shí)現(xiàn)思路。

以上就是Android端驗(yàn)證碼自動(dòng)獲取與填充的實(shí)戰(zhàn)方案的詳細(xì)內(nèi)容,更多關(guān)于Android驗(yàn)證碼自動(dòng)獲取與填充的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論

黄浦区| 昌乐县| 龙口市| 彰化市| 米易县| 绵竹市| 天台县| 慈溪市| 新乡市| 桂林市| 普陀区| 秦皇岛市| 新蔡县| 杨浦区| 清丰县| 嘉兴市| 阳原县| 乐至县| 阿鲁科尔沁旗| 广灵县| 隆安县| 北海市| 集安市| 鹿邑县| 温泉县| 当雄县| 丰宁| 高唐县| 威远县| 青海省| 宁城县| 西丰县| 滨海县| 平凉市| 弥渡县| 华宁县| 阳谷县| 连城县| 乌鲁木齐县| 永川市| 布尔津县|