用Python脚本实现SIM800L短信自动化测试的工程实践

在物联网设备开发中,GSM模块的短信功能测试往往需要反复发送AT指令并检查响应。传统串口调试工具的手动操作方式不仅效率低下,也难以实现测试用例的批量执行和结果记录。本文将分享如何通过Python脚本构建一个完整的SIM800L短信自动化测试框架,涵盖从基础通信到PDU模式中文短信处理的完整解决方案。

1. 硬件准备与环境搭建

1.1 SIM800L模块基础配置

SIM800L作为一款经典的GSM/GPRS模块,其稳定性和性价比使其在物联网领域广泛应用。在实际部署前,需要特别注意以下硬件配置要点:

  • 电源管理:模块要求3.7-4.2V供电,峰值电流可达2A
    • 推荐使用5V/2A电源配合低压差稳压器(如AMS1117-3.3)
    • 电源输入端并联1000μF电容可有效抑制电压跌落
  • 串口连接:只需连接4根核心线缆
    • TXD → 主机RXD
    • RXD → 主机TXD
    • GND → 共地
    • VCC → 3.8V电源
  • 天线选择:务必外接PCB天线或弹簧天线
    • 信号强度(AT+CSQ)应大于10(理想值≥20)

提示:首次上电建议先通过AT指令检查模块状态,依次执行AT、AT+CPIN?、AT+CSQ确认模块就绪。

1.2 Python开发环境准备

自动化测试脚本依赖以下关键库:

pip install pyserial==3.5  # 串口通信
pip install smspdu==1.0.4  # PDU编解码
pip install pytest==7.1.2  # 测试框架

创建基础通信类SIM800LController

import serial
import time

class SIM800LController:
    def __init__(self, port, baudrate=115200):
        self.ser = serial.Serial(
            port=port,
            baudrate=baudrate,
            timeout=1
        )
        time.sleep(0.5)  # 等待串口稳定
        
    def send_at(self, command, wait=1):
        self.ser.write((command + '\r\n').encode())
        time.sleep(wait)
        return self.ser.read_all().decode()

2. AT指令自动化封装

2.1 基础指令封装实践

将常用AT指令封装为高阶方法,提升代码可读性:

def check_sim_status(self):
    response = self.send_at("AT+CPIN?")
    return "READY" in response

def get_signal_quality(self):
    response = self.send_at("AT+CSQ")
    if "CSQ" in response:
        return int(response.split(':')[1].split(',')[0])
    return 0

2.2 短信模式配置

SIM800L支持两种短信模式:

模式指令特点适用场景
文本模式AT+CMGF=1可读性强英文短信测试
PDU模式AT+CMGF=0支持中文生产环境

配置示例代码:

def set_pdu_mode(self):
    self.send_at('AT+CMGF=0')  # 设置为PDU模式
    self.send_at('AT+CSCS="GSM"')  # 设置字符集
    self.send_at('AT+CSMP=17,167,0,0')  # 设置文本模式参数

3. PDU短信编解码实战

3.1 短信发送全流程实现

PDU模式中文短信发送需要经过编码转换:

  1. 将接收号码转换为PDU格式
  2. 使用Unicode编码短信内容
  3. 计算TPDU长度
  4. 组合完整PDU字符串
  5. 发送AT+CMGS指令

完整发送函数示例:

def send_pdu_sms(self, number, message):
    # 号码处理:补位并反转
    processed_num = ''.join(['91', self._format_number(number)])
    
    # 短信内容Unicode编码
    encoded_msg = message.encode('utf-16-be').hex().upper()
    
    # 计算TPDU长度
    tpdu_length = len(encoded_msg) // 2
    
    # 组合PDU字符串
    pdu_data = f'0891{processed_num}0008AA{encoded_msg}'
    
    # 发送指令
    self.ser.write(f'AT+CMGS={tpdu_length}\r\n'.encode())
    time.sleep(0.5)
    self.ser.write((pdu_data + '\x1A').encode())
    return self.ser.read_all().decode()

3.2 接收短信解析方案

短信接收处理流程:

def parse_received_pdu(self, pdu_str):
    # 提取短信中心号码
    smsc_length = int(pdu_str[:2], 16) * 2
    smsc = pdu_str[4:4+smsc_length]
    
    # 提取发送方号码
    sender_length = int(pdu_str[smsc_length+4:smsc_length+6], 16)
    sender = pdu_str[smsc_length+8:smsc_length+8+sender_length]
    
    # 解码短信内容
    msg_start = smsc_length + 8 + sender_length + 8
    hex_msg = pdu_str[msg_start:-2]
    return bytes.fromhex(hex_msg).decode('utf-16-be')

4. 自动化测试框架构建

4.1 测试用例设计

典型测试场景矩阵:

测试类型测试项预期结果校验方法
基础功能模块初始化AT响应OK响应包含OK
SIM卡状态已就绪+CPIN:READY
短信发送英文短信发送成功返回+CMGS
中文短信发送成功返回+CMGS
短信接收读取收件箱正确解析内容匹配
压力测试连续发送100条无丢包计数器验证

4.2 实现自动化测试脚本

基于pytest的测试用例示例:

import pytest

@pytest.fixture
def sim800l():
    dev = SIM800LController('/dev/ttyUSB0')
    dev.send_at('AT')  # 测试连接
    yield dev
    dev.ser.close()

def test_sms_roundtrip(sim800l):
    test_msg = "自动化测试消息"
    sim800l.send_pdu_sms('13800138000', test_msg)
    
    # 模拟接收过程
    received = sim800l.parse_received_pdu('0791...AA...') 
    assert test_msg in received

4.3 测试报告生成

集成Allure生成可视化报告:

pytest --alluredir=./report
allure serve ./report

关键指标监控建议:

  • 信号强度变化曲线
  • 短信成功率统计
  • 平均响应时间
  • 异常错误分类

在实际项目中,这套自动化方案将测试效率提升了约15倍。一个原本需要2小时的手动测试流程,现在只需8分钟即可完成,且能生成详细的测试日志和性能报告。对于需要批量部署的物联网设备,这种自动化方法显著降低了人工验证的成本和错误率。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐