更新版本:
本文后面会逐步清理
安装
python集成开发环境
Unicode字符串
Python2.0增加了新的用来存储文本数据的类型:Unicode对象。它可以用于存储和操作Uounicode 数据(参见 ),与现有的字符串兼容性良好,必要时能自动转换。
Unicode支持所有字符的表示,之前的ASCII只支持256个字符。更多Unicode相关的资料,参见:。
创建Unicode字符串:
>>> u'Hello World !'u'Hello World !'
引号前的'u'表示Unicode 字符串,转义的方式可以创建其他字符:
>>> u'Hello\u0020World !'u'Hello World !'
转义序列\u0020表示插入编码为0x0020(空格)的Unicode 字符。
其他字符也会直接解释为对应的编码值。 许多西方国家使用的标准Latin-1编码的字符串和编码小于256的Unicode字符和在Unicode编码中的一样。
使用ur可以取消转义,r表示原始格式(raw)。
>>> ur'Hello\u0020World !'u'Hello World !'>>> ur'Hello\\u0020World !'u'Hello\\\\u0020World !'
如果你需要大量输入反斜杠(比如正则表达式),原始模式非常有用。
除了标准编码,Python还支持其他编码。
内置函数unicode()可以访问所有注册的Unicode编码(COders和DECoders),并支持Latin-1 、ASCII、UTF-8和UTF-16 之类的编码可以互相转换,后两个是变长编码。通常默认编码为 ASCII,此编码接受0到127 这个范围的编码,否则报错。Unicode字符串打印或写入到文件,或者使用str()转换时,使用默认编码进行转换操作。
encode()方法可以把Unicode字符串转换为特定编码的8bit字符串,参数为小写的编码名作为参数。
反之可以使用unicode()把其他编码转换为unicode。
>>> u"abc"u'abc'>>> str(u"abc")'abc'>>> u"äöü"u'\xe4\xf6\xfc'>>> str(u"äöü")Traceback (most recent call last): File "", line 1, in UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)>>> u"äöü".encode('utf-8')'\xc3\xa4\xc3\xb6\xc3\xbc'>>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8')u'\xe4\xf6\xfc'
Selenium web自动化简单实例
下面使用python打开火狐,搜索引擎上输入seleniumhq,然后退出。
import timefrom selenium import webdriverfrom selenium.webdriver.common.keys import Keysbrowser = webdriver.Firefox()browser.get('http://www.so.com/')assert '360' in browser.titleelem = browser.find_element_by_name('q') # Find the search boxelem.send_keys('seleniumhq' + Keys.RETURN)time.sleep(3)browser.quit()
pyautogui 模拟按键精灵简单实例
下面脚本在画图软件上画出一系列正方形。Linux上可以用Pinta演示,注意要打开一个空白画图页面在屏幕左上角。
import pyautoguidistance = 100pyautogui.moveTo(300, 300)while distance > 0: pyautogui.dragRel(distance, 0, duration=0.5) # move right distance -= 5 pyautogui.dragRel(0, distance, duration=0.5) # move down pyautogui.dragRel(-distance, 0, duration=0.5) # move left distance -= 5 pyautogui.dragRel(0, -distance, duration=0.5) # move up
自动查询Git,有更新时触发Jenkins构建简单实例
#!/usr/bin/python# -*- coding: utf-8 -*-import loggingimport logging.handlersimport timeimport reimport os.pathimport subprocess32import syssys.path.append('../lib/')from requests.auth import HTTPDigestAuthdial_logger = logging.getLogger('MyLogger')dial_logger.setLevel(logging.DEBUG)fh = logging.handlers.RotatingFileHandler( '../logs/dial_log_server.log', maxBytes=10000000, backupCount=5)fh.setLevel(logging.DEBUG)formatter = logging.Formatter(u'%(asctime)s [%(levelname)s] %(message)s')fh.setFormatter(formatter)dial_logger.addHandler(fh)dial_logger.info("Application starting! \n")while True: for line in open("../conf/url.csv"): try: now = time.strftime("%Y-%m-%d_%H:%M:%S", time.gmtime()) print(now) name, git_url, branch, jenkins_url = line.strip().split(',') # print(name, git_url, branch, jenkins_url) dial_logger.info("Beginning Scan {0}! \n".format(name)) dial_logger.info("{0} {1} {2}! \n".format(git_url, branch, jenkins_url)) cmd = "git ls-remote -h " + git_url result = subprocess32.check_output(cmd,shell=True) #print(result) version = re.findall(r'(\S+)\s+{0}'.format(branch), result, re.MULTILINE)[0] dial_logger.info("current version: {0}! \n".format(version)) file_name = '/tmp/{0}'.format(name) if os.path.exists(file_name): old_version = open(file_name).read().strip() # print(old_version, version) dial_logger.info("old version: {0}! \n".format(old_version)) if old_version == version: dial_logger.info("Don not call {0} \n".format(name)) print("Don not call {0} \n".format(name)) continue f = open(file_name,'w') f.write(version) f.close() dial_logger.info("Call {0} \n".format(jenkins_url)) cmd = "curl --user xurongzhong:123456 -s {0} &".format(jenkins_url) # print(cmd) dial_logger.info("command: {0}! \n".format(cmd)) subprocess32.call(cmd, shell=True) except Exception as e: dial_logger.error(str(e), exc_info=True) dial_logger.info("End Scan! \n") time.sleep(3 * 60)
流程控制
除了前面介绍的 while 语句,Python还更多的流程控制工具。
自动化测试介绍
简介
软件自动化测试是利用特殊软件(跟被测软件比较)来控制测试执行并比较实际结果与预测结果。自动化测试可以在测试过程中自动化一些重复性的但必要的任务, 或者增加手工难以执行的额外的测试,比如性能测试、压力测试,模拟测试、接口测试、单元测试等。自动化测试一般具备准备测试环境、测试控制、判断结果和测试报告的功能。
自动化测试的方法
GUI测试
测试框架生成用户界面的事件,如按键和鼠标点击,并观察用户界面的变化结果,以验证该观测到的行为的程序是否正确。
许多测试自动化工具提供的记录和回放功能,让用户能够记录用户的交互行动和重播。这种方法的优点是它需要很少或根本没有软件开发。但是稍有改变,维护工作就比较大。 web测试是GUI的变种,它是阅读的HTML不是观察窗口事件,使用的技术有很大差异。selenium是知名的web测试工具,selenium有python api,参见:代码驱动的测试
对类,模块或库的公共接口进行测试。一种日益增长的趋势是在软件开发使用的测试框架,如xUnit框架(例如, pytest和unittest)允许代码进行单元测试。
代码驱动的自动化测试是敏捷软件开发的一个重要特点。这种方法的支持者认为,它生产的软件,是更可靠,成本更低。
API驱动的测试
API测试也被广泛使用,因为GUI的自动化测试的成本太高。
测试开发基于框架或者编程调用应用的接口,比如SNMP,COM,HTTP常用的接口,命令行等。
PyAutoGUI
PyAutoGUI跨平台且人性化的GUI自动化工具。
PyAutoGUI是编程控制鼠标和键盘的Python模块。
PyAutoGUI可用pip工具安装在PyPI下载。
PyAutoGUI旨在提供跨平台、人性化的Python GUI自动化模块,API的设计是尽可能的简单。
例如移动屏幕中间:
>>> import pyautogui>>> screenWidth, screenHeight = pyautogui.size()>>> pyautogui.moveTo(screenWidth / 2, screenHeight / 2)
PyAutoGUI可以模拟移动鼠标,点击鼠标,拖动鼠标,按键,按住键和按键盘热键组合。
>>> import pyautogui>>> screenWidth, screenHeight = pyautogui.size()>>> currentMouseX, currentMouseY = pyautogui.position()>>> pyautogui.moveTo(100, 150)>>> pyautogui.click()>>> pyautogui.moveRel(None, 10) # move mouse 10 pixels down>>> pyautogui.doubleClick()>>> pyautogui.typewrite('Hello world!', interval=0.25) # type with quarter-second pause in between each key>>> pyautogui.press('esc')>>> pyautogui.keyDown('shift')>>> pyautogui.press(['left', 'left', 'left', 'left', 'left', 'left'])>>> pyautogui.keyUp('shift')>>> pyautogui.hotkey('ctrl', 'c')
显示对话框
>>> import pyautogui>>> pyautogui.alert('This is an alert box.')'OK'>>> pyautogui.confirm('Shall I proceed?')'Cancel'>>> pyautogui.confirm('Enter option.', buttons=['A', 'B', 'C'])'B'>>> pyautogui.prompt('What is your name?')'Al'>>> pyautogui.password('Enter password (text will be hidden)')'swordfish'
- 截图(需要Pillow支持)
>>> import pyautogui>>> im1 = pyautogui.screenshot()>>> im1.save('my_screenshot.png')>>> im2 = pyautogui.screenshot('my_screenshot2.png')
下面脚本在画图软件上画出一系列正方形。Linux上可以用Pinta演示,注意要打开一个空白画图页面在屏幕左上角。
import pyautoguidistance = 200pyautogui.moveTo(300, 300)while distance > 0: pyautogui.dragRel(distance, 0, duration=0.5) # move right distance -= 5 pyautogui.dragRel(0, distance, duration=0.5) # move down pyautogui.dragRel(-distance, 0, duration=0.5) # move left distance -= 5 pyautogui.dragRel(0, -distance, duration=0.5) # move up
依赖
Windows: 无
OS X: AppKit和Quartz模块需要PyObjC,需要先安装pyobjc-core,再安装pyobjc。 Linux:python-xlib (for Python 2) or python3-Xlib (for Python 3)容错
Linux 的窗口的关闭在左上角,要尽量避免错误地点击到关闭,设置“pyautogui.FAILSAFE = True”即可。
设置sleep: "pyautogui.PAUSE = 2.5", 单位为秒,默认为0.1。
安装Windows: “pip.exe install pyautogui”
OS X:
# sudo pip3 install pyobjc-core# sudo pip3 install pyobjc# sudo pip3 install pyautogui
Linux:
ubuntu
# sudo pip3 install python3-xlib# sudo apt-get scrot# sudo apt-get install python-tk# sudo apt-get install python3-dev# sudo pip3 install pyautogui
ubuntu 14.04安装:
# pip install svn+ # sudo apt-get install scrot# apt-get install python-tk
OS X: AppKit和Quartz模块需要PyObjC,需要先安装pyobjc-core,再安装pyobjc。
Linux:python-xlib (for Python 2) or python3-Xlib (for Python 3)快速入门
通用函数>>> import pyautogui>>> pyautogui.position() # current mouse x and y(968, 56)>>> pyautogui.size() # current screen resolution width and height(1920, 1080)>>> pyautogui.onScreen(300, 300) # True if x & y are within the screen.True
容错
>>> import pyautogui>>> pyautogui.PAUSE = 2.5>>> import pyautogui>>> pyautogui.FAILSAFE = True
fail-safe为True时,移动到左上角会触发pyautogui.FailSafeException异常。
鼠标函数其他实例:
确定图片位置:
>>> import pyautogui>>> button7location = pyautogui.locateOnScreen('button.png') # returns (left, top, width, height) of matching region>>> button7location(1416, 562, 50, 41)>>> buttonx, buttony = pyautogui.center(button7location)>>> buttonx, buttony(1441, 582)>>> pyautogui.click(buttonx, buttony) # clicks the center of where the button was found
返回图片的中心位置:
>>> import pyautogui>>> buttonx, buttony = pyautogui.locateCenterOnScreen('button.png') # returns (x, y) of matching region>>> buttonx, buttony(1441, 582)>>> pyautogui.click(buttonx, buttony) # clicks the center of where the button was found
持续集成介绍
持续集成(Continuous integration CI)是每天合并所有开发的作拷贝到共享主线若干次的软件工程实践。由Grady Booch1991年在的Booch方法提出,尽管Booch的不主张每日多次集成,因此CI未必总是频繁集成。CI被主张每日多次集成XP(extreme programming)采用。CI的主要目的是防止集成问题,在XP早期描述中称为“集成警钟”。
最初在XP中CI是与测试驱动开发的实践中的自动化单元测试结合使用,在开发者的本地环境通过所有单元测试再提交到主线。这有助于防止开发人员的工作的代码相互覆盖。如果有必要可以用实际功能代替Mock等。后面引进了构建服服务器。自动定期甚至每次提交都执行单元测试并报告结果。
除了运行单元测试和集成测试,也引入了质量控制。比如静态和动态测试,衡量和profile性能,从代码提取物文档以方便手工QA流程。
持续交付扩展了持续集成,确保在主线软件始终处于可部署到用户的状态,使实际部署过程非常迅速。Workflow
尽早集成,尽快发现问题。辅以自动单元、集成测试。
最佳实践
-
代码仓库:维护一个代码仓库,管理代码、文档、配置文件等所有产出。尽量少使用分支。
-
自动编译:包含编译的二进制文件,生成文档、网站页面、统计和发布媒体(比如Debian DEB,红帽RPM或Windows MSI文件)等。
-
编译自测。
-
每人每天都提交到基线
-
每次提交都有构建
-
快速构建
-
准上线环境(staging)
-
使容易交付:测试和相关人员可以了解构建、尽早测试。
-
所有人可以看到最近构建结果。
-
自动部署
成本和好处
好处:
-
尽早发现集成错误,容易跟踪,节省了时间和金钱。
-
避免发布日期的混乱。
-
当单元测试失败或bug出现时,如果需要很容易回退。
-
当前构建适合测试,演示,或发布。
-
频繁的check-in推动开发创建模块化的,不太复杂的代码。
-
强制频繁执行自动化测试
-
本地更改,即时反馈系统范围的影响。
-
自动化测试与CI的指标(如度量代码覆盖率,代码的复杂性和特性完整性等)引导开发人员开发功能完整,高质量的代码。
自动化测试需要大量的工作、涉及框架开发、新功能的覆盖和旧功能的维护。
自动编译与python
python中有不少自动编译工具。 列出了不少自动编译工具,其中buildbot、scons等工具为python书写。比较出名的为buildbot、scons、buildout及jenkins相关插件。
waftools
waf TravisPy taschenmesser cuppa numscons PyScons teamcity-messages syncloud-image-ci mac jenkinsapi django-jenkins platformio gump buildbot tunir zc.buildoutscons简介
SCons是能自动分析源代码文件的依赖性和操作系统的要求计算机软件构建工具,并生成最终的二进制文件。它类似于基于make和autoconf的传统的GNU编译系统。
SCons基于Python,软件项目配置和构建过程的实现都是Python脚本。
主要特点如下:
-
配置文件是Python脚本。
-
内置C,C ++和Fortran自动依赖分析的。依赖性分析是可扩展的,通过用户定义的依赖扫描器可以支持其他语言或类型的文件。而GNU编译器集的(GCC) 的内建依赖分析基于正则表达式扫描。
-
内置支持C,C ++,D,Java,Fortran,Objective-C,Yacc的,Lex,Qt和SWIG,以及TeX和LaTeX文档的支持。
-
支持中央库源代码和预先构建。
-
内置支持从版本控制系统,如SCCS,RCS,CVS,Subversion,BitKeeper和Perforce。
-
内置支持微软的Visual Studio,包括生成DSP,.DSW,的.sln和的.vcproj文件。
-
使用MD5签名检查文件内容的变化,可配置传统的时间戳。比如设置SourceSignatures('timestamp')。
-
支持并行构建。
-
集成类Autoconf支持来查找#include文件,库、函数和typedef。
-
支持所有依赖的全局视图,因此不需要多次编译和和重新序的目标文件。
-
在cache共享构建文件。
-
跨平台。
scons快速入门
此部分参考资料:
编辑文件: helloscons.c
#include#include int main(int argc, char* argv[]) { printf("Hello, SCons!\n"); return 0; }
现在我们想编译helloscons.c为二进制文件helloscons,即类似gcc helloscons.c -o helloscons的功能。
创建文件:SConstruct
Program('helloscons.c')
编译
$ sconsscons: Reading SConscript files ...scons: done reading SConscript files.scons: Building targets ...gcc -o helloscons.o -c helloscons.cgcc -o helloscons helloscons.oscons: done building targets.$ sconsscons: Reading SConscript files ...scons: done reading SConscript files.scons: Building targets ...scons: `.' is up to date.scons: done building targets.
编译类型:
-
Program: 编译成可执行程序(在 Windows 平台上即是 exe 文件),这是最常用的一种编译类型。
-
Object: 只编译成目标文件。使用这种类型,编译结束后,只会产生目标文件。在 POSIX 系统中,目标文件以 .o 结尾,在 Windows 平台上以 .OBJ 结尾。
-
Library: 编译成库文件。SCons 默认编译的库是指静态链接库。
-
StaticLibrary: 显示的编译成静态链接库,与上面的 Library 效果一样。
-
SharedLibrary: 在 POSIX 系统上编译动态链接库,在 Windows 平台上编译 DLL。
-
Java: 编译Java程序。比如 Java(‘classes’,‘src’),其中的src表示源码目录。
修改可执行文件名字
Program('myscons, 'helloscons.c')
静默模式
$ scons -Q gcc -o helloscons.o -c helloscons.c gcc -o myscons helloscons.o
多文件编译
Program('helloscons2', ['helloscons2.c', 'file1.c', 'file2.c'], LIBS = 'm', LIBPATH = ['/usr/lib', '/usr/local/lib'], CCFLAGS = '-DHELLOSCONS
模糊匹配:
Program('helloscons2', Glob('*.c')
配置文件中 LIBS,LIBAPTH 和 CCFLAGS 是 SCons 内置的关键字,它们的作用如下:
-
LIBS: 显示的指明要在链接过程中使用的库,如果有多个库,应该把它们放在一个列表里面。这个例子里,我们使用一个称为 m 的库。
-
LIBPATH: 链接库的搜索路径,多个搜索路径放在一个列表中。这个例子里,库的搜索路径是 /usr/lib 和 /usr/local/lib。
-
CCFLAGS: 编译选项,可以指定需要的任意编译选项,如果有多个选项,应该放在一个列表中。这个例子里,编译选项是通过 -D 这个 gcc 的选项定义了一个宏 HELLOSCONS。
$ scons -Q gcc -o file1.o -c -DHELLOSCONS file1.c gcc -o file2.o -c -DHELLOSCONS file2.c gcc -o helloscons2.o -c -DHELLOSCONS helloscons2.c gcc -o helloscons2 helloscons2.o file1.o file2.o -L/usr/lib -L/usr/local/lib -lm
环境变量
env = Environment()env.Append(CPPFLAGS=['-Wall','-g'])env.Program('hello', ['hello.c', 'main.c'])
参考资料
-
作者博客:
-
联系作者:徐荣中 python开发自动化测试群113938272 微博 。
-
python 2.7 英文官方教程:
-
IBM scons 中文介绍:
-
维基百科 scons 英文介绍
-
scons github地址:
-
维基百科GNU build system英文介绍:
-
scons bitbucket wiki:
-
rtthread-manual-doc scons 中文简介:
-
scons主页: