发送带伪造经纬度的请求时,参数名须严格匹配接口约定(如lat/lng或location_lat等),坐标值为-90~90、-180~180范围内浮点数,精度通常6位;测试宜用pytest参数化驱动多组坐标,避免硬编码与随机生成;模拟轨迹应预生成合理位移序列;mock地理位置依赖需覆盖成功及超时、权限拒绝等异常路径。

用 requests 发送带伪造经纬度的请求时,参数名必须匹配接口约定
很多地理位置相关接口(比如外卖、打车、LBS搜索)要求在 URL 查询参数或 JSON Body 中传入 lat 和 lng(或 latitude/longitude),但命名不统一。发请求前务必先看文档或抓包确认字段名,否则服务端直接忽略或报 400 Bad Request。
常见错误现象:接口返回“位置无效”或默认返回北京/上海的数据,实际是字段名写错或类型不对(比如传了字符串而非浮点数)。
- 优先检查接口文档里明确写的坐标字段名,例如
lat、lng、location_lat、coordinate(后者可能要传"39.9042,116.4074"这样的字符串) - 坐标值必须是合法浮点数,范围需符合地理常识:
lat在-90.0到90.0之间,lng在-180.0到180.0之间 - 注意精度:高德、百度等地图 API 对小数点后位数有建议(通常 6 位足够),过多反而可能触发校验失败
测试多组坐标时,用 pytest + 参数化避免硬编码
手动改数值测 3 个地点太慢,也容易漏场景。用 pytest.mark.parametrize 把坐标列表和预期结果一起驱动测试,既清晰又可复现。
示例中模拟测试「附近餐厅」接口,验证不同城市坐标的响应状态和数据量:
import pytest
import requests
@pytest.mark.parametrize("lat,lng,city,expected_count", [
(39.9042, 116.4074, "北京", 10),
(31.2304, 121.4737, "上海", 8),
(22.3193, 114.1694, "香港", 5),
])
def test_nearby_restaurants(lat, lng, city, expected_count):
params = {"lat": lat, "lng": lng, "radius": 1000}
resp = requests.get("https://api.example.com/v1/restaurants", params=params)
assert resp.status_code == 200
data = resp.json()
assert len(data.get("list", [])) >= expected_count
关键点:不要把坐标写死在测试函数体里;用参数化让每组数据独立执行,失败时能立刻定位到哪座城市出问题。
需要模拟移动轨迹?用 time.sleep() + 循环发请求不如预生成坐标序列
真机调试时可能需要模拟用户步行/驾车产生的连续坐标流,但测试脚本里盲目加 time.sleep() 既慢又不可控。更稳妥的做法是提前算好一组合理位移的坐标点(比如按直线或圆弧递增),再逐个请求。
- 用 Python 算偏移:从起点
(lat0, lng0)出发,向正北走 100 米,新纬度 ≈lat0 + 0.000899(1 米约 0.00000899 度);经度偏移需结合纬度换算,可用geopy.distance.geodesic精确计算 - 避免用随机数生成“假轨迹”——随机经纬度大概率落在海里或无人区,导致接口返回空或异常数据,干扰测试判断
- 如果接口有频率限制,用
pytest-xdist并行跑多个坐标点会触发限流,此时应加@pytest.mark.serial或控制并发数
Mock 地理位置依赖时,别只 stub get_current_location(),还要覆盖异常路径
当被测代码内部调用了获取 GPS 的函数(如 get_current_location()),单元测试中需 mock 它。但只 mock 成功返回坐标远远不够——真实设备常遇到定位失败、超时、权限拒绝等情况。
用 unittest.mock.patch 模拟不同场景:
from unittest.mock import patch
@patch("myapp.geo.get_current_location")
def test_with_gps_failure(mock_get):
mock_get.side_effect = TimeoutError("GPS timeout")
result = myapp.do_something_based_on_location()
assert result["status"] == "fallback_to_ip"
容易被忽略的点:mock 对象的模块路径必须和运行时导入路径完全一致(比如是 myapp.geo 而不是 utils.geo);另外,某些 SDK 会缓存首次定位结果,测试间需重置状态或用 autospec=True 防止状态污染。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











