8.1 创建定时任务
为了让自动化测试“自动化”起来,现在我们来创建定时任务,使自动化测试脚本在指定的时间自动化运行。创建定时任务的方法有很多,比如,我们可以写一段程序让其在指定的时间运行all_test.py 文件,或者使用系统的定时任务功能在指定的时间运行all_test.py文件。
在python的os模块中提供了system()用来执行系统命令。比如要执行:UnitTest\Project\run_all.py
可以这样实现:start_run.py
#coding=utf-8 import os os.system(".\\run_all.py")
或者先切换到相应的目录,然后通过Python 命令去执行all_test.py文件更符合我们在cmd 下面的操作顺序。
Start_run.py
#coding=utf-8 import os os.chdir(".\\Test_project") os.system("run_all.py")
定时任务, 通过time 模块了,要实现这个功能非常简单,获取当前时间判断是不是要执行自动化的时间。Start_run.py:start_run.py
#coding=utf-8 import os,time k=1 while k<2: now_time=time.strftime("%H_%M") if now_time=="21_00": print "start to runscritpt!" os.chdir(".\\UnitTest\\Project") os.system("run_all.py") print "Finished andexit!" break else: time.sleep(10) printnow_time
首先定义变量k 的值为1,通过while 判断k 的值是否小于2,在不改变k 的值
的情况下,k 会永远小于二,然后通过strftime()方法获取当前的小时和分钟,然后通过if 判断是否等于21:00,如果不相等,休眠10 秒(这个休眠时间只要不超过60 秒即可,超过了60 秒,可能直接会从20:59 跳到21:01,从而错过了21:00),当前时间为21:00 时执行all_test.py 程序从而执行自动化测试。并且break 结束循环。如果希望想每天21:00 跑自动化测试用例,那么可以不要break ,程序继续运行,直到遇见下一个20:00,自动化测试再次被执行。
Windows添加任务计划:其实操作系统本身也提供了强大的定时任务功能。Window7 为例,Window设置定时任务:通过控制面板—管理工具—任务计划程序(或者在“开始”菜单中搜索“任务计划程序”):
选择菜单栏中的“操作”选项可以选择“创建基本任务” 和“创建任务”,前者创建过程比较简单,我选择后者进行设置:
设置任务名和任务描述,以及执行任务的用例,切换到“触发器”标签页,点击“新建”设置出发任务的条件。
设置每天22:00:00 触发任务,然后点击“确定”。然后,切换到“操作”标签页:点击“新建”设置执行的操作。
选择运行程序或脚本,点击“浏览”按钮找到all_test.py 程序,点击“确定”。然后,我们就创建完成了一个任务计划,在任务计划库中就可以看到创建的任务计划了。
OK,现在我们可以验证一下任务设置的是否成功,在任务计划上右键选择“运行”,任务就可以开始运行了。
8.2 自动发邮件功能
Python的smtplib模块提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。
Smtp协议的命令包括:
HELO 向服务器标识用户身份
MAIL 初始化邮件传输 mail from:
RCPT 标识单个的邮件接收人;通常MAIL命令后面,可以有多个rcpt to:
DATA 在单个或多个RCPT命令后,表示所有的邮件接收人已标识,并初始化数据传输,以“.”结束
VRFY 用于验证指定的用户/邮箱是否存在;由于安全方面的原因,服务器常禁止此命令
EXPN 验证给定的邮箱列表是否存在,扩充邮箱列表,也常被禁用
HELP 查询服务器支持什么命令
NOOP 无操作,服务器应响应OK
QUIT 结束会话
REST 重置会话,当前传输被取消
MAIL FROM 指定发送者地址
RCPT TO 指明的接收者地址
一般smtp会话有两种方式,一种是邮件直接投递,比如发送邮件给:zzz@126.com那就直接连接126.com的邮件服务器,把信投递给zzz@126.com;另一种是验证过后的发信,它的过程是,比如你要发件给zzz@126.com,你不是直接投到126.com,而是通过自己的另一个邮箱来发。
8.2.1 发送HTML格式的邮件
Send_mail.py
#coding=utf-8 import smtplib fromemail.mime.text import MIMEText fromemail.header import Header sender="username @126.com" receiver="username @163.com" subject="Pythonemail test" smtpserver="smtp.126.com" username="username@126.com" password="password" msg=MIMEText('<html><h1>hello</h1></html>','html','utf-8') msg['subject']=Header(subject,'utf-8') smtp=smtplib.SMTP() smtp.connect("smtp.126.com") smtp.login(username,password) smtp.sendmail(sender,receiver,msg.as_string()) smtp.quit()
import smtplib
导入smtplib 发邮件模块,程序中邮件的发送、接收等相关服务,全部由smtplib.SMTP 方法来完成。
from email.mime.text import MIMEText
from email.header import Header
导入email 模块,MIMEText和Header 主要用来完邮件内容与邮件标题的定义。
smtp.connect() 用于链接邮件服务器
smtp.login() 配置发送邮箱的用户名密码
smtp.sendmail() 配置发送邮箱,接收邮箱,以及发送内容
smtp.quit() 关闭发邮件服务
8.2.2 发送带附件的邮件
Send_emai_with_attch.py:
#coding=utf-8 import smtplib fromemail.mime.text import MIMEText fromemail.mime.multipart import MIMEMultipart sender ='testingwtb@126.com' receiver ='xiaoming@126.com' smtpserver ='smtp.126.com' username ='testingwtb@126.com' password ='123456' msgRoot =MIMEMultipart('related') msgRoot['Subject']= 'Python email test' att =MIMEText(open('\\report\\log.txt', 'rb').read(), 'base64', 'utf-8') att["Content-Type"]= 'application/octet-stream' att["Content-Disposition"]= 'attachment; filename="log.txt"' msgRoot.attach(att) smtp = smtplib.SMTP() smtp.connect('smtp.126.com') smtp.login(username,password) smtp.sendmail(sender,receiver, msgRoot.as_string()) smtp.quit()
与上一个实例相比,通过MIMEMultipart 模块构造带附件的邮件,附件本身同样使用MIMEText()方法定义路径和格式
8.2.3 查找最新的测试报告
在report\目录下找到最新生成的测试报告。New_file.py:
#coding=utf-8 import os result_dir=".\\report" lists=os.listdir(result_dir) lists.sort(key=lambda fn: os.path.getmtime(result_dir+"\\"+fn)) print("the lastest receive:"+lists[-1]) file=os.path.join(result_dir,lists[-1]) print file
首先定义测试报告的目录result_dir ,通过os.listdir()可以获取目录下的所有文件。这也只是获取一个目录下的所有文件而已,我们最重要的任务是找到目录下最新生成的文件。
lists.sort(key=lambdafn: os.path.getmtime(result_dir+"\\"+fn))
用lambda 来声明匿名函数,冒号(:)前面表示入参,冒号后面表示返回值。
lists.sort():Python列表有一个内置的列表。sort()方法用于改变列表中元素的位置。还有一个sorted()内置函数,建立了一种新的迭代排序列表。
key=lambda fn:key是带一个参数的函数,用来为每个元素提取比较值.默认为None, 即直接比较每个元素lambda提供了一个运行时动态创建函数的方法。我这里创建了fn 函数。
#定位一个数组
>>>ls=['c.txt','b.txt','d.txt','a.txt']
>>> ls
['c.txt', 'b.txt', 'd.txt', 'a.txt']
#取数组中的key 做排序
>>>ls.sort(key=lambda lists:lists[0])
>>> print ls
['a.txt', 'b.txt', 'c.txt','d.txt']
>>>ls.sort(key=lambda lists:lists[1])
>>> print ls
['c.txt', 'b.txt','d.txt', 'a.txt']
lists:lists[0] 表示取的是每个元组中的前半部分,即为:c、b、d、a ,所以可进行排序。
lists:lists[1] 表示取的是每个元组中的后半部分,即为:txt,不能有效的进行排序规律,所以按照数组的原样输出。
os.path.getmtime():getmtime()返回文件列表中最新文件的时间(最新文件的时间最大,所以我们会得到一个最大时间)
通过上面一行代码的操作,lists 中的文件按照进间重时行的排列组合。如果想获最新的文件就取lists[-1]。
通过os.path.join()方法可以将文件目录与文件名进行拼接,从而打印出目录下最新文件的绝对路径。
8.2.4 整合自动发邮件功能
利用Python 实现发邮件功能,如何查找目录下最新的文件。下面要做的事情就是把这些功能整合到all_test.py 文件。:
#coding=utf-8 import smtplib fromemail.mime.text import MIMEText importunittest importHTMLTestRunner import time,os def send_mail(file_new): mail_from='testingwtb@126.com' mail_to='xiaoming@126.com' f = open(file_new, 'rb') mail_body = f.read() f.close() msg=MIMEText(mail_body,_subtype='html',_charset='utf-8') msg['Subject']=u"自动化测试报告" msg['date']=time.strftime('%a, %d %b %Y%H:%M:%S %z') smtp=smtplib.SMTP() smtp.connect('smtp.126.com') smtp.login('testingwtb@126.com','123456') smtp.sendmail(mail_from,mail_to,msg.as_string()) smtp.quit() print 'email has send out !' def send_report(testreport): result_dir = testreport lists=os.listdir(result_dir) lists.sort(key=lambda fn:os.path.getmtime(result_dir+"\\"+fn)) file_new =os.path.join(result_dir,lists[-1]) print file_new send_mail(file_new) def creatsuite(): testunit=unittest.TestSuite() test_dir='.\\test_case' discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None) for test_suite in discover: for test_case in test_suite: testunit.addTest(test_case) printtestunit returntestunitlp if __name__ =='__main__': now = time.strftime("%Y-%m-%d%H_%M_%S") testreport = '.\\report\\' filename = testreport+now+'result.html' fp = file(filename, 'wb') runner =HTMLTestRunner.HTMLTestRunner( stream=fp, title=u'自动化测试报告', description=u'用例执行情况:') alltestnames = creatsuite() runner.run(alltestnames) fp.close() send_report(testreport)
send_mail(file_new):定义一个sentmail()发邮件函数,接收一个参数file_new,表示接收最新生成的测试报告文件。
open(file_new, 'rb'):以读写(rb)方式打开最新生成的测试报告文件。
mail_body = f.read():读取文件内容,将内容传递给mail_body。
MIMEText(mail_body,_subtype='html',_charset='utf-8'):文件内容写入到邮件正文中。html格式,编码为utf-8。
send_report():定义sendreport()接收一个测试报告的目录,找到目录下最新生成的测试报告文件file_new。调用并将file_new 传给send_mail()函数。
程序执行过程:
首先,调用creatsuit()函数,将所测试用例装载到测试套件中。
其次,调用HTMLTestRunner 模块的run()函数,执行测试套件中的用例,并生成测试报告,然后,fp.close()关闭生成的测试报告文件。
接着,调用send_report()函数,查找测试报告目录下面最新生成的测试报告文件,并将最新报告文件的路径传给send_mail()函数,send_mail()函数实现发邮件功能。
整个过程执行完成,打开我们的接收邮箱将看到最新测试执行的测试报告