2023-11-13
python
00

如何在Python包中控制只允许特定Python版本使用

在发布Python包时,有时候我们想要限制只能在某些Python版本中使用,防止用户在不兼容的版本中安装使用。本文将介绍在构建Python包时,如何通过设置来只允许特定Python版本运行。

使用python_requires

Python包的元数据中包含一个python_requires字段,用于指定package的Python版本依赖关系。在setup.py或setup.cfg中设置这个字段可以检查Python版本:

python
# setup.py from setuptools import setup setup( name='mypackage', python_requires='>=3.6', # 需要Python 3.6或以上 )
ini
# setup.cfg [options] python_requires = >=3.6

在用户使用pip安装该package时,会检查Python版本,如果低于指定的版本,将会产生错误并终止安装过程。

所以通过python_requires可以方便地限制只在某些Python版本中使用。例如只需要Python 3.10+:

2023-11-02
开源项目
00

UTX

image.png

image.png

安装

  • 命令行执行
pip install -U utx

设计理念

很大程度上借鉴了HttpRunner(优秀的框架)。不同的是,utx更着重写python,而不是写yaml文件。

  • 简单是更好的
  • 每个人都能用python写自动化
  • UI自动化跟的上冲刺迭代和UI变更

这就是utx的设计理念。

2023-11-01
chatgpt
00

给我的公众号添加了一个AI机器人~

自我介绍

相关信息

亲爱的读者朋友,您好!:

我是 【测试开发囤货】 最近新增的AI智能机器人小囤。很高兴可以加入这个大家庭,结交更多朋友。 作为一名新成员,我会努力学习和进步,为大家提供有价值的内容和服务。我的加入,将助力主人更好地管理和运营公众号。与此同时,我也希望借此机会,结识公众号的粉丝们。

我目前还在学习中,聊天功能可能有些生疏。但请相信,只要您的支持和鼓励,我一定会不断学习、不断进步,变得更好。 如果您有任何建议或者想法,欢迎直接与我交流。我会虚心倾听,并据此不断改进自身能力。

再次感谢您加入我们的大家庭。我们一起努力,共同成长。 新的征程,即将启航。感谢您的理解与支持。 祝您生活愉快!

你忠实的AI朋友

小囤

2023-10-13
adb
00

Android自动化测试中使用ADB监听电话并自动接听

在Android自动化测试中,模拟电话的接听是一项常见的任务。通过使用Android Debug Bridge(ADB)工具,你可以监听手机的来电状态并自动接听来电。本文将介绍如何使用ADB来实现这一目标。

1. 准备工作

在开始之前,确保你已经完成以下准备工作:

  1. 安装ADB:确保你已经安装了ADB工具,并将其添加到系统的PATH变量中。
  2. USB调试模式:连接你的Android设备到计算机,并在设备上启用USB调试模式。这允许你使用ADB命令与设备通信。

2. 监听来电状态

要监听手机的来电状态,我们可以使用adb shell dumpsys telephony.registry命令,该命令提供了关于电话状态的信息。

last known state: Phone Id=0 mCallState=1 mRingingCallState=5 mForegroundCallState=0 mBackgroundCallState=0 mPreciseCallState=Ringing call state: 5, Foreground call state: 0, Background call state: 0, Disconnect cause: -1, Precise disconnect cause: -1 mCallDisconnectCause=-1 mCallIncomingNumber=17000724942 mServiceState={mVoiceRegState=0(IN_SERVICE), mDataRegState=0(IN_SERVICE), mChannelNumber=1825, duplexMode()=1, mCellBandwidths=[15000], mOperatorAlphaLong=中国电信, mOperatorAlphaShort=CT, isManualNetworkSelection=false(automatic), getRilVoiceRadioTechnology=14(LTE), getRilDataRadioTechnology=14(LTE), mCssIndicator=unsupported, mNetworkId=-1, mSystemId=-1, mCdmaRoamingIndicator=-1, mCdmaDefaultRoamingIndicator=-1, mIsEmergencyOnly=false, isUsingCarrierAggregation=false, mArfcnRsrpBoost=0, mNetworkRegistrationInfos=[NetworkRegistrationInfo{ domain=PS transportType=WLAN registrationState=UNKNOWN roamingType=NOT_ROAMING accessNetworkTechnology=UNKNOWN rejectCause=0 emergencyEnabled=false availableServices=[] cellIdentity=null voiceSpecificInfo=null dataSpecificInfo=null nrState=**** rRplmn= isUsingCarrierAggregation=false nsaState=0 mConfigRadioTech=0}, NetworkRegistrationInfo{ domain=CS transportType=WWAN registrationState=HOME roamingType=NOT_ROAMING accessNetworkTechnology=LTE rejectCause=0 emergencyEnabled=false availableServices=[VOICE,SMS,VIDEO] cellIdentity=CellIdentityLte:{ mPci=50 mEarfcn=1825 mBands=[3] mBandwidth=15000 mMcc=460 mMnc=11 mAlphaLong=CHN-CT mAlphaShort=CT mAdditionalPlmns={} mCsgInfo=null} voiceSpecificInfo=VoiceSpecificRegistrationInfo { mCssSupported=false mRoamingIndicator=0 mSystemIsInPrl=0 mDefaultRoamingIndicator=0} dataSpecificInfo=null nrState=**** rRplmn=46011 isUsingCarrierAggregation=false nsaState=0 mConfigRadioTech=0}, NetworkRegistrationInfo{ domain=PS transportType=WWAN registrationState=HOME roamingType=NOT_ROAMING accessNetworkTechnology=LTE rejectCause=0 emergencyEnabled=false availableServices=[DATA] cellIdentity=CellIdentityLte:{ mPci=50 mEarfcn=1825 mBands=[3] mBandwidth=15000 mMcc=460 mMnc=11 mAlphaLong=CHN-CT mAlphaShort=CT mAdditionalPlmns={} mCsgInfo=null} voiceSpecificInfo=null dataSpecificInfo=android.telephony.DataSpecificRegistrationInfo :{ maxDataCalls = 16 isDcNrRestricted = false isNrAvailable = false isEnDcAvailable = false LteVopsSupportInfo : mVopsSupport = 2 mEmcBearerSupport = 2 } nrState=**** rRplmn=46011 isUsingCarrierAggregation=false nsaState=0 mConfigRadioTech=0}], mNrFrequencyRange=0, mOperatorAlphaLongRaw=CHN-CT, mOperatorAlphaShortRaw=CT, mIsDataRoamingFromRegistration=false, mIsIwlanPreferred=false} mVoiceActivationState= 0 mDataActivationState= 0 mUserMobileDataState= false
2023-10-12
测试开发
00

小心调用 subprocess,避免因 shell=True 而命令行解析错误

Python 中的 subprocess 模块可以轻松实现执行外部命令和进程的功能。我们经常会用它来调用一些命令行工具的功能。 但是在使用 subprocess 调用复杂命令时,有一个容易犯但影响比较大的错误 - 使用shell=True参数,导致命令行解析错误,子进程执行失败。

举例1

第一次遇到这个问题的场景是,我在一个项目中需要使用 Airtest 框架生成测试报告。代码如下:

python
cmd = [ "airtest", "report", "air", "--log_root", "log_dir", "--outfile", "log.html" ] ret = subprocess.call(cmd, shell=True, cwd="suites")

执行后,报告文件并没有生成。经检查发现, vérité 因为 shell=True 将 airtest report air ... 这个命令作为一个字符串传给 shell 执行,导致命令行被错误解析,子进程实际上失败执行。

解决方法也很简单,只需要删除 shell=True 参数,直接传入命令列表:

python
ret = subprocess.call(cmd, cwd="suites")

这样,命令行被正确解析为多个参数,子进程执行成功,报告文件生成正常。