微信对方微信通讯录删除联系人把我删除了显示出对方开启了好友验证,我和对方说话,对方能来信息吗

& & 今天笔者就要归纳总结下一整套测试流程,从无到有,实现零突破,包括如何编写测试用例,定时执行测试用例,查找最新生成的测试报告文件,自动发送最新测试报告邮件,一整套完整的测试流程。以后各位只要着重如何编写测试用例即可,其他模板可以套用的,希望帮助到大家。
环境准备:
操作系统:Windows7
集成开发环境:eclipse+pydev
一、编写测试用例
& & 可以直接使用Python自带的单元测试框架unittest来编写自动化测试用例,利用其组织测试用例,断言预期结果,以及批量执行测试用例等功能,可以很好的进行Web自动化测试的开发。
& & 可以直接查看我另外一篇博文总结:
& & 里边详细总结了和。
& & 目录结构如下组织:
& & 如上图:test_case目录下有两个测试用例,其中test_baidu.py实例代码在博文&unittest单元测试框架总结&中有贴出。其他实例,可以参考模板实现,就不全部贴出代码了。
& & 而这次需要测试的就是test_baidu.py和test_youdao.py这两个测试用例。
二、执行测试用例,查找最新测试用例,自动发送测试报告
& & 整个代码执行过程可以分成三个步骤:
& & 1.通过unittest框架的discover()找到匹配的测试用例(以test_开头的脚本),由HTMLTestRunner的run()方法执行测试用例并生成最新测试报告。HTMLTestRunner是Python标准卡unittest单元测试框架的一个扩展,主要用于生成HTML测试报告,以便生成一份通俗易懂的测试报告来展示自动化测试成果。
HTMLTestRunner模块下载地址:/software/HTMLTestRunner.html
将下载的文件保存在C:\Python27\Lib目录下即可。
& & 2.先定义new_file()函数(找到某目录最新文件),调用new_file()函数找到测试报告目录下最新生成的测试报告,返回最新测试报告的路径。
& & 3.先定义send_email()函数(发送指定路径下某文件的邮件),将得到的最新测试报告的完整路径传给send_email()函数,实现发邮件功能。
& & 关于发邮件功能,也可以参考我另外一篇博文:
& & 代码如下:注释中包括实现的过程说明以及一些在测试过程中遇到的问题。
& & 文件命名为runtest_htmltestrunner_autosendemail.py
# coding=utf-8
Created on
@author: Jennifer
Project:整合自动发邮件功能,执行测试用例生成最新测试报告,取最新的测试报告,发送最新测试报告
问题,邮件始终不能显示html:将电脑时间改为北京时间即可
import unittest
from HTMLTestRunner import HTMLTestRunner
import time
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
#2.定义:取最新测试报告
def new_file(test_dir):
#列举test_dir目录下的所有文件,结果以列表形式返回。
lists=os.listdir(test_dir)
#sort按key的关键字进行排序,lambda的入参fn为lists列表的元素,获取文件的最后修改时间
#最后对lists元素,按文件修改时间大小从小到大排序。
lists.sort(key=lambda fn:os.path.getmtime(test_dir+'\\'+fn))
#获取最新文件的绝对路径
file_path=os.path.join(test_dir,lists[-1])
L=file_path.split('\\')
file_path='\\\\'.join(L)
return file_path
#3.定义:发送邮件,发送最新测试报告html
def send_email(newfile):
f=open(newfile,'rb')
#读取文件内容
mail_body=f.read()
print u'打印'
print mail_body
#发送邮箱服务器
smtpserver = ''
#发送邮箱用户名/密码
password='XXX'
#多个接收邮箱,单个收件人的话,直接是receiver=''
receiver=['','','.cn']
#发送邮件主题
subject = '自动定时发送测试报告'
#编写 HTML类型的邮件正文
#MIMEText这个效果和下方用MIMEMultipart效果是一致的,已通过。
msg = MIMEText(mail_body,'html','utf-8')
msg=MIMEMultipart('mixed')
#注意:由于msg_html在msg_plain后面,所以msg_html以附件的形式出现
text = "Dear all!\nThe attachment is new testreport.\nPlease check it."
#中文测试ok
text = "Dear all!\n附件是最新的测试报告。\n麻烦下载下来看,用火狐浏览器打开查看。\n请知悉,谢谢。"
msg_plain = MIMEText(text,'plain', 'utf-8')
msg.attach(msg_plain)
msg_html1 = MIMEText(mail_body,'html','utf-8')
msg.attach(msg_html1)
msg_html = MIMEText(mail_body,'html','utf-8')
msg_html["Content-Disposition"] = ' filename="TestReport.html"'
msg.attach(msg_html)
#以附件的方式发送:但是会报554,倍163退信。--此路不通。
msg_html = MIMEText(mail_body,'base64','utf-8')
msg_html["Content-Type"] = 'application/octet-stream'
msg_html.add_header('Content-Disposition', 'attachment', filename='testreport.html')
msg.attach(msg_html)
#要加上msg['From']这句话,否则会报554的错误。
#要在163有限设置授权码(即客户端的密码),否则会报535
msg['From'] = ' &&'
msg['To'] = '.cn'
#多个收件人
msg['To'] = ";".join(receiver)
msg['Subject']=Header(subject,'utf-8')
#连接发送邮件
smtp=smtplib.SMTP()
smtp.connect(smtpserver,25)
smtp.login(user, password)
smtp.sendmail(sender, receiver, msg.as_string())
smtp.quit()
if __name__=='__main__':
print '=====AutoTest Start======'
#1.执行测试用例,生成最新的测试用例
#指定测试用例为当前文件夹下的test_case目录
#如果用/可以不用r
test_dir='./test_case'
#Windows的cmd执行:python "D:\system files\workspace\selenium\test_project\runtest_htmltestrunner_autosendemail.py"
#不用绝对路径会报:ImportError: Start directory is not importable: './test_case'
test_dir = 'D:\\system files\\workspace\\selenium\\test_project\\test_case'
#知道测试报告的路径
test_report_dir='D:\\pythontest\\testresult'
discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')
now=time.strftime('%Y-%m-%d_%H_%M_%S_')
filename = test_report_dir+'\\'+ now + 'result.html'
fp=open(filename ,'wb')
#需屏蔽fp中的中文文字说明。否则在windows下执行会报:UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 553: ordinal not in range(128)
runner = HTMLTestRunner(stream=fp,title=u'测试报告',description=u'用例执行情况:')
runner.run(discover)
#注意:调用函数一定要加括号,一个括号害死个人,哎,查了几天的问题,才发现导致html文件始终显示空白,就是因为close函数调用不正确,漏了括号。
fp.close()
#2.取最新测试报告
new_report=new_file(test_report_dir)
print new_report
#3.发送邮件,发送最新测试报告html
send_email(new_report)
print '=====AutoTest Over======'
& & 直接在eclipse运行,运行结果如下:
& & ..表示两个测试用例都执行通过。
三、定时执行测试用例
方案一:直接使用Windows任务计划执行Python测试脚本。
1.创建runner.bat
& & 由于runtest_htmltestrunner_autosendemail.py脚本目录为D:\system files\workspace\selenium\test_project,
& & 所以在该目录下创建runner.bat,runner.bat的内容如下:
& & python runtest_htmltestrunner_autosendemail.py
& & 建议:可以事先在cmd命令行下执行runtest_htmltestrunner_autosendemail.py,确保该脚本能够在Windows下正常运行。如不能正常运行,请继续调试,找出问题,直到能够正常运行。如下:
2.创建任务计划
2.1右键计算机,点击管理,点击任务计划程序,再点击右方的创建任务。
2.2常规中,填写名称,如:定时执行Python脚本
& & 触发器中,指定执行脚本时间。
& & 最重要的是操作设置:
& & 程序和脚本填写runner.bat这个文件的名称
& & 起始于填写runner.bat所在路径,D:\system files\workspace\selenium\test_project
& & 如下:
& & 在任务计划程序库中,就会出现该任务。
方案二:使用Jenkins定时执行脚本
& &&Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,所以可用于定时执行python脚本。
环境准备:jdk1.7及以上+Jenkins[+tomcat(可选)]
& & Jenkins的安装可以通过tomcat作为容器安装,由于Jenkins包就自带了servlet,所以我们只需要下载安装就可以直接启动。&
& & jenkins下载地址:http://jenkins-ci.org & 选择LTS(长期支持的版本),比较稳定,下载war包。
第一种启动方法,切换到jenkins.war存放的目录(随便哪个目录),输入如下命令:
& java -jar jenkins.war & #这样的话默认端口是8080
若要指定端口,则:
&java -jar jenkins.war --httpPort=8080
然后在浏览器中(推荐用火狐)输入localhost:8080,localhost可以是本机的ip,也可以是计算机名。就可以打开jenkins.
我就是用第一种方法安装Jenkins。
第二种方法是用tomcat打开
tomcat下载地址:http://tomcat.apache.org/
解压tomcat到某个目录,如D:\tomcat9,进入tomcat下的/bin目录,启动tomcat:即双击startup.bat文件
将jenkins.war文件放入tomcat下的webapps目录下,启动jenkins时,会自动在webapps目录下建立jenkins目录,所以在地址栏上需要输入的地址于上一种方法有点不一样。
点击左方的&新建&。
下方为配置说明:
说明:日程表依次是 分钟 小时 日 月 星期
*:表示每,每分钟,每小时,每天,每月,每星期等
, :表示指定列表范围。
- :表示区间范围&
所以0 1 * * &1-5 表示 每个月的星期一到星期五,凌晨一点定时执行脚本。
说明:执行脚本的命令。
上面配置完成后点击保存即可。
可先手动构建项目,查看项目是否能够执行通过。
点击左方的&立即构建&
&构建完成后,Build History就会有一条记录。
点击这条历史记录进去
再点击Console Output,可查看到日志,Finished: SUCCESS,说明已成功。
四、成果验收
& & 然后只需要静静的等待,测试报告邮件的到来。
& & 在此需要感谢虫师编著的&selenium2 自动化测试实战 基于Python语言&。
(尊重笔者的劳动哦,转载请说明出处哦。)
阅读(...) 评论()温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
&上图中,在build.xml文件中,定义好多个target,每个target运行不同的jmx脚本,并生成不同的测试报告。jenkins中的配置如下图:&在红框处指定需要运行的target名称,多个target分行即可邮件发送部分需要从生成的测试报告所载目录去取测试报告然后作为附件发送,配置如下:&多个测试报告之间以逗号分隔当然也可以用类似target/*.html这样的方式去匹配所有报告,全部发送
阅读(231)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'ant+jmeter+jenkins接口自动化测试框架如何实现指定target运行,生成并发送多份测试报告',
blogAbstract:'废话不多说,直接上图:&上图中,在build.xml文件中,定义好多个target,每个target运行不同的jmx脚本,并生成不同的测试报告。jenkins中的配置如下图:',
blogTag:'ant,jmeter,jenkins,自动化测试,接口',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:4,
publishTime:3,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}使用Ant执行程序
- ITeye技术网站
博客分类:
&&& 之前我们讲解了一个构建过程来编译和测试JAVA源代码,在测试表明代码是正确的之后,我们就该运行它了。这意味着应该探索Ant执行外部程序的能力的时候了。这些可外部程序可以是JAVA程序也可以是本地程序。
1.&&&&&& 使用Ant执行外部程序的原因:
由于Ant得益于其内置的任务,所以可以自己完成很多工作而不需要求助于外部代码。但是在大型工程中,很快就会发现它们需要使用外部程序,既可能使用本地程序,又可能使用JAVA应用程序。
&&&&& 实际的构建或测试应用程序是最常见的Ant内部运行的程序,这些程序的任务就是在主程序中进行单元测试、系统测试和载入测试。其他常见的外部程序就是“遗留构建步骤”:软件的某些部分需要一个本地编译器、Perl脚本或仅仅是一些用在构建中的本地工具程序。
&&&&& 从Ant内部运行程序时,有两个方案:
l&&&&&&&& 编写一个定制的Ant任务来调用程序,适用于需要在很多构建文件中使用同一个外部程序的情况。(适用于长期项目,经常工程编写Ant任务包装器)。
l&&&&&&&& 编写一个新的Ant任务,这个任务只是从构建文件中调用程序。从构建文件中直接调用程序是编写定制任务的基础。
Ant可以包装本地应用程序,而JAVA应用程序可以在Ant的JVM中运行,也可以在其外部运行。无论执行什么类型的应用程序,也无论怎样执行它,Ant都会挂起构建本身直至程序结束。程序的所有控制台输出都会加入到Ant的日志工具里,通常显示到屏幕里。被包装的程序无法读取控制台的输出,因此需要用户输入的程序无法运行。
2.&&&&&& 运行JAVA程序:
启动JAVA程序是Ant的拿手好戏。这种方法最好的一个特性就是可以轻而易举的指定classpath。它比在编写批处理或者是SHELL脚本时手工指定每个类库要容易得多;它可以将classpath中的lib/**/*.jar拥有的 所有文件统统包含近来。
Ant执行JAVA程序另一个好处是它可以在当前的JVM中运行程序。即使指定的classpath是由定制的类载入器提供的,也可以做到。在当前的JVM内运行的程序可以减少启动延迟;它只在载入新类时消耗时间,因此有助于构建保持快速。然而,在新的JVM中执行代码也有很多理由,”forking”(建立新进程),它在一些情形下更适用:
l&&&&&&&& 如果不建立新进程,就无法指定一个新的工作路径。
l&&&&&&&& 当你在建立新进程时,如果遇到与类载入器有关的奇怪的错误或者安全冲突,这很可能是因为在两个载入器里载入了同一个类:原先Ant中的类载入器和一个新的类载入器。在父类载入器或子类载入器中建立新进程或者追踪错误的JAR,然后移除它。
l&&&&&&&& 不能在同一个的JVM中执行JAR;而必须建立新的进程。
l&&&&&&&& 需要大量内存或leaky的JAVA程序应当运行在它们自己的JVM里,并给这个JVM分配适当的内存空间。
l&&&&&&&& 建立一个新进程也允许在另一个版本的虚拟机中运行代码。这个版本可以不同于启动ANT的虚拟机版本。
a)&&&&&& 首先介绍一下&java&任务:
建立一个JAVA类,然后打印入口参数,为了讲解classpath,这里我们引入一个记录日志的软件包,log4j来记录日志:
工程目录如下:
类代码如下:
package com.neusoft.
import org.apache.log4j.L
publicclass TestJava {
&&&&& privatestatic Logger logger = Logger.getLogger(TestJava.class);
&&&&& /**
&&&&&& *enterpointmethod
&&&&&& *
&&&&&& *@paramargs
&&&&&& *&&&&&&&&&&& enterpoingarguments
&&&&&& */
&&&&& publicstaticvoid main(String[] args) {
&&&&&&&&&& if (args.length &= 0) {
&&&&&&&&&&&&&&&& logger.error("Bad arguments!");
&&&&&&&&&&&&&&&& System.out.println("Usage:\n\tjava TestJava arg1 args2 ...");
&&&&&&&&&&&&&&&& System.exit(-1);
&&&&&&&&&& }
&&&&&&&&&& for (int i = 0; i & args. i++) {
&&&&&&&&&&&&&&&& ("arg" + i + "=" + args[i]);
&&&&&&&&&&&&&&&& System.out.println("arg" + i + "=" + args[i]);
&&&&&&&&&& }
&&&&& }
}
在不输入入口参数的情况下,打印帮助信息,并退出程序,在输入入口参数的情况下,执行程序,并打印参数。
其中log4j需要一个配置文件,示例如下:
&?xml version="1.0" encoding="UTF-8" ?&
&!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"&
&log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"&
&&&&& &appender name="error" class="org.apache.log4j.FileAppender"&
&&&&&&&&&& &param name="File" value="${user.dir}/logs/error.log" /&
&&&&&&&&&& &layout class="org.apache.log4j.PatternLayout"&
&&&&&&&&&&&&&&&& &param name="ConversionPattern"
&&&&&&&&&&&&&&&&&&&&& value="%d{yyyy/MM/dd HH:mm:ss},%p,%C.%M,%m%n" /&
&&&&&&&&&& &/layout&
&&&&& &/appender&
&&&&& &root&
&&&&&&&&&& &priority value="DEBUG" /&
&&&&&&&&&& &appender-ref ref="error" /&
&&&&& &/root&
&/log4j:configuration&
这里设置了一个文件类型的日志输出器,所有日志输出都将被输出到用户目录的logs/error.log文件中,关于log4j的知识,请参考本blog其他文章。运行完成后的工程目录如下图所示:
error.log中将记录日志信息。
下面我们来创建构建文件:
&target name="run " depends="compile"&
&echo&running a search&/echo&
&java classname="com.neusoft.test.TestJava"&
&arg value="The"/&
&arg value="current"/&
&arg value="dir"/&
&arg value="is"/&
&arg file="."/&
&/java&
&/target&
这样设置还不够,还需要指定classpath,否则可能会出现如下错误:
Buildfile: C:\eclipse\workspace\Ant_Chapater5\build.xml
init:
&&& [mkdir] Created dir: C:\eclipse\workspace\Ant_Chapater5\build
&&& [mkdir] Created dir: C:\eclipse\workspace\Ant_Chapater5\build\classes
compile:
&&& [javac] Compiling 1 source file to C:\eclipse\workspace\Ant_Chapater5\build\classes
run:
&&&& [java] Could not find com.neusoft.test.TestJava. Make sure you have it in your classpath
&&&&& ……
BUILD SUCCESSFUL
Total time: 4 seconds
因为我们没有配置classpath。当任何指定的classpath都不存在时,&java&任务就使用Ant自身的classpath:诸如ant.jar以及其他任何位于ANT_HOME/lib目录下的类库,再加上系统CLASSPATH环境变量的内容。就几乎所有&java&任务而言,应该另外指定一个classpath。当这样做的时候,已经存在的所有非java和javax包的classpath中的内容就不再可用了。这种方式与&javac&不同,在&javac&中如果够文件不指定其他值,则自动包含Ant运行时classpath。
添加classpath很容易:在&classpath&元素中写路径或者提供classpath属性一个字符串形式的路径。如果想做多个不同的地方使用classpath,最好先设置好classpath,然后再通过classpathref属性引用它。一个常见的惯例是:
用第二个包含有新的生成类的classpath来扩展第一个编译时classpath,而不管这个新的生成类是档案文件形式还是.class文件的目录树形式。
我们也采用这种办法,一个用于编译,一个用于执行:
&path id="compile.classpath"&
&pathelement path="src/log4j-1.2.13.jar"/&
&/path&
&path id="run.classpath"&
&path refid="compile.classpath"/&
&pathelement location="${build.dir}/classes"/&
&/path&
第一个classpath包含编译时所需要的类库,第二个添加我们刚刚编写的代码。易于维护,任何编译时所需要新的类库都会自动传递到运行时classpath。
&&&&& 此时可以修改&java&任务如下:
&java classname=" com.neusoft.test.TestJava"
classpathref="run.classpath"&
&arg value="The"/&
&arg value="current"/&
&arg value="dir"/&
&arg value="is"/&
&arg file="."/&
&/java&
现在构建文件如下:
&?xml version="1.0" encoding="UTF-8" ?&
&projectname="run-java-application"default="run"&
&&&&& &propertyname="build.dir"value="build"/&
&&&&& &pathid="compile.classpath"&
&&&&&&&&&& &pathelementlocation="src/log4j-1.2.13.jar"/&
&&&&& &/path&
&&&&& &pathid="run.classpath"&
&&&&&&&&&& &pathrefid="compile.classpath"/&
&&&&&&&&&& &pathelementlocation="${build.dir}/classes"/&
&&&&& &/path&
&&&&& &targetname="init"&
&&&&&&&&&& &deletedir="${build.dir}"/&
&&&&&&&&&& &deletedir="logs"/&
&&&&&&&&&& &mkdirdir="${build.dir}"/&
&&&&&&&&&& &mkdirdir="${build.dir}/classes"/&
&&&&& &/target&
&&&&& &targetname="compile"depends="init"&
&&&&&&&&&& &javacsrcdir="src"destdir="${build.dir}/classes"&
&&&&&&&&&&&&&&&& &classpathrefid="compile.classpath"/&
&&&&&&&&&& &/javac&
&&&&& &/target&
&&&&& &targetname="run"depends="compile"&
&&&&&&&&&& &javaclassname="com.neusoft.test.TestJava"&
&&&&&&&&&&&&&&&& &classpathrefid="run.classpath"/&
&&&&&&&&&&&&&&&& &argvalue="The"/&
&&&&&&&&&&&&&&&& &argvalue="current"/&
&&&&&&&&&&&&&&&& &argvalue="dir"/&
&&&&&&&&&&&&&&&& &argvalue="is"/&
&&&&&&&&&&&&&&&& &argfile="."/&
&&&&&&&&&& &/java&
&&&&& &/target&
&/project&
构建过程运行如下:
Buildfile: C:\eclipse\workspace\Ant_Chapater5\build.xml
init:
&&& [mkdir] Created dir: C:\eclipse\workspace\Ant_Chapater5\build
&&& [mkdir] Created dir: C:\eclipse\workspace\Ant_Chapater5\build\classes
compile:
&&& [javac] Compiling 1 source file to C:\eclipse\workspace\Ant_Chapater5\build\classes
run:
&&&& [java] log4j:WARN No appenders could be found for logger (com.neusoft.test.TestJava).
&&&& [java] log4j:WARN Please initialize the log4j system properly.
&&&& [java] arg0=The
&&&& [java] arg1=current
&&&& [java] arg2=dir
&&&& [java] arg3=is
&&&& [java] arg4=C:\eclipse\workspace\Ant_Chapater5
BUILD SUCCESSFUL
Total time: 4 seconds
执行完成后工程目录如下:
但是,可以看到,由于构建过程中不能找到log4j的配置文件,所以有如下警告:
[java] log4j:WARN No appenders could be found for logger (com.neusoft.test.TestJava).
[java] log4j:WARN Please initialize the log4j system properly.
也就没有生成logs/error.log日志文件。这个原因本人也在探索中,试图将log4j.xml添加到classpath中,但是还是出问题。如果有遇到类似问题的朋友,希望帮忙解决。
个人初步分析原因是:不能在同一个的JVM中执行JAR;而必须建立新的进程。因为写日志相当于执行了log4j档案文件中的类,所以不能在同一个JVM中运行。
3.&&&&&& 参数:
在&java&任务中,最重要的可选参数是嵌套参数列表。可以通过一个简单值,一行文本,一个用于参数列表优先级解析的文件,或者一个路径来命名一个参数。可以在任务的&arg&元素里指定它们,&arg&元素支持以下四个属性,Ant按这些参数声明的顺序将它们传递给JAVA程序:
value:字符串值。(对XML的特殊记号要进行转义:&变为&&& 
代表换行)
file:文件或目录,在使用之前解析为绝对地址。然后再传递。
line:传递给程序的整个行
path:一个字符串,包含有用冒号或分号隔开的文件或目录。
4.&&&&&& 定义系统特性:
系统是那些要传给JAVA命令行(如:-Dproperty=value)的参数的定义。嵌套的&sysproperty&元素可以用来定义要传递的特性。
&sysproperty key="socksProxyHost" value="socks-server"/&
&sysproperty key="socksProxyPort" value="1080"/&
有两种可选方法能代替value参数:file和path。就如带参数一样,file属性为文件命名;Ant对相对引用进行解析并传入绝对文件名,并使用本地平台的文件分隔符。path属性与之类似,只是允许列入多个文件:
&sysproperty key="configuration.file" file="./config.properties"/&
&sysproperty key="searchpath" path="build/classes:lib/j2ee.jar" /&
5.&&&&&& 在新的JVM中运行程序
&java&任务将运行在当前的JVM中,除非fork属性被设置为true,这将减少程序启动的时间。做为实验,我们可以将TestJava放在一个新的JVM中运行。
&target name="run-search-fork" depends="create-jar"&
&echo&running a search&/echo&
&java classname="com.neusoft.test.TestJava"
classpathref="run.classpath"
fork="true"&
&argvalue="The"/&
&&&&&&&&&&&&&&&& &argvalue="current"/&
&&&&&&&&&&&&&&&& &argvalue="dir"/&
&&&&&&&&&&&&&&&& &argvalue="is"/&
&argfile="."/&
&/java&
&/target&
6.&&&&&& 设置环境变量:
你可以在一个建立新进程的JVM里使用嵌套元素&env&来设置环境变量。这个元素的语法与&sysproperty&元素是一样的。
7.&&&&&& 控制新的JVM
可以选择不同于Ant的JAVA运行时环境,只要通过jvm属性设置JVM命令就可以了,这对与从一个旧的JVM中运行程序时是非常有用的,诸如运行在JAVA1.1系统里的测试,或者可能在JAVA的一个未来版本的BETA版。可以给这个JVM指定参数来控制它,最常用的选项就是设置内存数量,属性maxmemory,这个属性具有一些幕后只能 可以区分JAVA 1.1和1.2系统,生成合适的命令。
可以通过&java&嵌套的&jvmarg&元素提供通用的 JVM参数。这些参数的确切用法与&arg&元素相同。
&target name="run-search-jvmargs" depends="create-jar"&
&property name="Search.JVM.extra.args" value="-Xincgc"/&
&java classname=" com.neusoft.test.TestJava"
classpathref="run.classpath"
fork="true"
maxmemory="64m"&
&jvmarg line="${Search.JVM.extra.args}"/&
&argvalue="The"/&
&&&&&&&&&&&&&&&& &argvalue="current"/&
&&&&&&&&&&&&&&&& &argvalue="dir"/&
&&&&&&&&&&&&&&&& &argvalue="is"/&
&argfile="."/&
&/java&
&/target&
当fork=”false”时,所有的JVM选项都不起作用;仅仅显示一行警告信息。
8.&&&&&& 使用failonerror处理错误
尽管核心的构建步骤(compile和JAR)必须完成后才可以认为整个构建是成功的,但是一些其他的构建过程中的任务,它们的失败并不重要。例如发送进度报告的电子邮件并不因为邮件服务器确实而终止构建,同样配置过程中的很多方面,诸如停止一个WEB服务器等,并不会因失败而终止构建。
一些Ant任务有一个共同的属性,failonerror,它可以控制当任务失败时是否终止构建。多数任务的默认值是”true”,意思是任何构建过程中任务的失败都会导致构建失败,并导致ANT的BUILD FAILED信息。
&java&任务支持这个属性,但仅在新的JVM中才支持,如果JAVA程序的返回值不等于0,则终止构建。当JVM内部调用System.exit()时,整个构建过程会因为JAVA停止运行而突然停止并且不显示BUILD FAILED信息:这个调用退出了ANT以及程序。
例如我们将failonerror设置为true,并且不传递任何参数给程序,将调用System.exit(-1),此时JAVA程序的输出为:
&target name="run-search-invalid" depends="compile"&
&echo&running a search&/echo&
&java classname="com.neusoft.test.TestMain"
classpathref="run.classpath"
failonerror="true"
fork="true"&
&argvalue="The"/&
&&&&&&&&&&&&&&&& &argvalue="current"/&
&&&&&&&&&&&&&&&& &argvalue="dir"/&
&&&&&&&&&&&&&&&& &argvalue="is"/&
&argfile="."/&
&/java&
&/target&
构建输出如下:
run-search-invalid:
[echo] running a search
[java] Usage:
java TestJava arg1 args2 ...
BUILD FAILED
C:\AntBook\app\tools\build.xml:532: Java returned: -1
9.&&&&&& 执行JAR文件:
当一个JAR文件由命令行中的java –jar命令启动时,该JAR文件可以在清单(manifest)上列出一个类的名字做为执行入口,ANT也可以类似地运行JAR文件,但只能在建立新进程的JVM中。这是因为执行JAR文件的过程会载入classpath列表中所列的文件,而其他细节则与JAVA的“扩展”有关。通过一个jar属性设置为文件的文职可以运行JAR文件:
&target name="run-search-jar" depends="create-jar"&
&echo&running a search&/echo&
&java
jar="${jarfile.path}"
classpathref="run.classpath"
failonerror="true"
fork="true"&
&arg value="The" /&
&&&&&&&&&&&&&&&& &arg value="current" /&
&&&&&&&&&&&&&&&& &arg value="dir" /&
&&&&&&&&&&&&&&&& &arg value="is" /&
&arg file="." /&
&/java&
&/target&
这个目标并不能实际工作,因为还没有设置清单(manifest),这些内容等到下一章再讲解。
10.&&&&&& 调用第三方程序:
可以使用任务运行由第三方提供的程序,假设我们部署过程的一个环节中包含了停止WEB SERVER的操作,比如TOMCAT 5.5,这在部署中是个常见的动作;为了从构建中进行部署,必须实现自动化每个步骤。幸运的是多数WEB SERVER都提供了这样或那样的方法来做到这一点:从TOMCAT的启动脚本中提取命令来完成&javac&任务:
&property environment="env"/& //获取环境变量
&target name="stop-tomcat"
description="stop tomcat if it is running"&
&java classname="org.apache.tomcat.startup.Tomcat"&
&classpath&
&fileset dir="${env.TOMCAT_HOME}/lib"&
&include name="**/*.jar"/&
&/fileset&
&/classpath&
&arg value="-stop"/&
&sysproperty key="tomcat.home"
value="${env.TOMCAT_HOME}"/& //将TOMCAT的HOME目录向下传递
&/java&
&/target&
执行该目标有以下几种结果:
l&&&&&&&& TOMCAT存在而且库文件位于预先假设的位置,成功停止TOMCAT
l&&&&&&&& 本地目前没有任何版本的TOMCAT在运行,无法停止TOMCAT
l&&&&&&&& 即使已经设置classpath,但是因为TOMCAT未安装或者环境变量未正确设置,因此造成库目录确实而无法创建classpath
这时我们需要预先判断。
11.&&&&&& 在调用之前探察JAVA程序:
在准备调用一个JAVA类之前,在classpath上查找它是很容易的,这样做使得显示警告信息成为可能。对于TOMCAT问题,可以使用&available&任务,或者采用&condition&任务会更好,后者能够通过检测环境变量组合&available&测试:
&target name="validate-tomcat"
&condition property="tomcat.available"&
&and&
&isset property="env.TOMCAT_HOME"/&
&available classname="org.apache.tomcat.startup.Tomcat"&
&classpath&
&fileset dir="${env.TOMCAT_HOME}/lib"&
&include name="**/*.jar"/&
&/fileset&
&/classpath&
&/available&
&/and&
&/condition&
&echo&tomcat.available=${tomcat.available}&/echo&
&/target&
这里声明了,当且仅当env.TOMCAT_HOME已经定义,且要调用的类org.apache.tomcat.startup.Tomcat位于TOMCAT目录下的classpath时,特性tomcat.available才会被设置成true。由于&and&的捷径效应,第一个测试失败时不运行第二个,因为第一个失败时,classpath是不合法的。
&&&&& 这个测试可以用语带条件的任务,或者当一个程序必须存在时,带条件的&fail&任务将被用于立即终止构建。当找不到TOMCAT时,通过使用将目标依赖于检验目标,且将条件设置为tomcat.available特性而选择了简单的略过测试:
&target name="stop-tomcat"
if="tomcat.available"
depends="validate-tomcat"
description="stop tomcat if it is running"&
&java classname="org.apache.tomcat.startup.Tomcat"&
&classpath&
&fileset dir="${env.TOMCAT_HOME}/lib"&
&include name="**/*.jar"/&
&/fileset&
&/classpath&
&arg value="-stop"/&
&!— 传递给JAVA命令行的参数的定义 --&
&sysproperty key="tomcat.home"
value="${env.TOMCAT_HOME}"/&
&/java&
&/target&
12.&&&&&& 设置超时
Ant1.5为&java&任务扩展了timeout属性,允许以毫秒的方式指定一个JAVA应用程序最大的运行时间。只能在建立新进程的JVM中使用这一个特性。
第二部分:使用&exec&启动本地程序
&&&&& JAVA执行并不能给予构建文件访问底层操作系统的全部能力,或者访问本地平台的构建步骤,除非JAVA程序调用本地程序。由于本地程序的移植性很差,因此为了实现以跨平台的方式定制任务,应提供可移植性的包装方式。
&&&&& 在运行程序之前让构建文件去探测这些程序存在与否(用上一节的知识)。这是个功能强大的技巧,就如同多数与维护相关的编码,通过不懈的努力能满足绝大部分的情形。
&&&&& 要在Ant内运行一个外部程序,应该使用&exec&任务,它可以执行以下操作:
l&&&&&&&& 指定程序名称和要传入的参数
l&&&&&&&& 命名运行目录
l&&&&&&&& 使用failonerror标志来控制当应用程序失败时是否终止构建
l&&&&&&&& 指定一个最大程序持续时间,时间超过则终止程序。任务在这时被认为是失败,但是至少构建会终止,而不是挂起,这对于自动构建是很重要的。
l&&&&&&&& 将输出存入一个文件或特性
l&&&&&&&& 指定JAVA调用本地程序时需要预先设定的环境变量
有一件事是它所做不到的,那就是使用一个OsFamily标志将操作限制到操作系统家族,诸如Windows或者Unix,否则将是非常方便的。&condition&任务确实拥有一个OsFamily测试可用于具有条理性的操作系统测试,但是这样的话整个目标都变成有条件的。
将&exec&与特定的操作系统绑定在一起是不好的做法,除非这个调用直接对应操作系统的底层功能。而检测相应程序,如果存在就调用它则好的多。
例子:
&exec executable="ln"&
&arg value="-s"/&
&arg location="execution.xml"/&
&arg location="symlink.xml"/&
&/exec&
这个任务的用途是给文件创建符号连接,因为内置JAVA命令没有这个功能。如果可执行程序在当前路径或者在系统path目录中,则无需指定其完整路径。
1.&&&&&& 设置环境变量:
正如&java&任务支持将系统属性作为嵌套元素一样,&exec&任务允许&env&子元素设置环境变量。它与&sysproperty&元素具有相同的语法,以不同的元素名分隔。&exec&的一个特别的功能,是你可以选择程序是否继承当前的环境。通常情况下继承当前的所有设置是有意义的,诸如PATH和TEMP,但是有时候可能希望通过参数进行绝对控制:
&exec executable="preprocess"
newenvironment="true" &
&env key="PATH" path="${dist.dir}/win32;${env.PATH}"/&
&env key="TEMPLATE" file="${src.dir}/include/template.html"/&
&env key="USER" value="self"/&
&/exec&
即使通过newenvironment=”false”(默认值)继承已有的环境,任何显示定义的环境变量也将覆盖所传入环境变量的值。
2.&&&&&& 处理错误
&exec&属于这样一类Ant任务:这类任务默认情况下failonerror=”false”。这是有原因的:最初没有返回值校验,因此当它被实现时,校验将被设为false以避免与已有构建冲突。即使JAVA任务与其他多数任务不同,但它至少和本地执行任务有统一的默认值。
&&&&& 声明failonerror为true和false,而忽略其默认值,这样使构建文件可读性好。”什么情况下出错就终止”/”什么情况下出错但不终止”。
&&&&& failonerror并不控制在程序运行时系统对失败如何反映,在Ant 1.5中,&exec&加入了第二个失败检查,failIfExecuteFails,它控制了实际的执行失败是否被忽略。
3.&&&&&& 处理超时
运行超时杀死任务,以免陷入挂起。&exec&支持一个timeout属性,以毫秒为单位。如果设置了该属性则一个监视计时器就会启动运行。当外部程序占用时间超时后就“杀死”它。当超时发生时,监视器不会明确告诉你超时发生了,但是执行文件的返回代码被设为”1”。如果failonerror被设置,则将会终止构建。如果没有设置,那么它就会悄悄的不被忽略。
&target name="sleep-fifteen-seconds" &
&echo message="sleeping for 15 seconds" /&
&exec executable="sleep"
failonerror="true"
timeout="2000"&
&arg value="15" /&
&/exec&
&/target&
运行该目标,当遇到超时就会产生一个错误:
sleep-fifteen-seconds:
[echo] sleeping for 15 seconds
[exec] Timeout: killed the sub-process
BUILD FAILED
execution.xml:18: exec returned: 1
如果外部程序设置成将结果传入一个特性,并将failonerror设置为off,那么就没办法将为1的结果和超时区分开。
需要在构建中插入一个暂停时,可以使用&sleep&任务,该任务可以工作在所有平台上。
4.&&&&&& 运行shell命令
使用:
&exec executable="cmd" failonerror="true"/&
&arg line="/c echo hello & hello.txt"/&
&/exec&
而不是
&exec command="/c echo hello & hello.txt" failonerror="true"/&
&/exec&
在shell中也是一样:应该使用
&exec command="ps -ef | grep java & processes.txt"
failonerror="false"/&
而不是
&exec executable="sh" failonerror="true"/&
&arg line="-c 'ps -ef | grep java & processes.txt'"/&
&/exec&
因为整个一行的内容需要shell来解释。
5.&&&&&& 在程序被调用之前进行探测
有时候当程序不可用时,可以略过一个构建步骤,或者提供有帮助的错误并终止。如果你知道程序所在的位置,就可以调用&available&任务对其进行测试,但是假如只是要求该程序在指定目录中怎么办呢?&available&任务可以在整个文件路径下搜索指定的文件,因此探测一个程序是否存在就是个简单的事情了,只要沿着环境变量PATH查找程序名字就可以了,当然,在跨平台的方式下,这并不简单:MS-DOC和UNIX系统以不同的方式命名可执行文件,有时甚至连路径变量也不同。将这些纳入考虑之中,对文件的探测就变成了一个多情况的测试,测试必须以带.exe和不带.exe扩展名两种方式来寻找可执行文件,并且MS-DOC/Windows可执行文件必须同时通过环境变量的两个选项进行搜索。Path和PATH:
&target name="probe_for_gcc" &
&condition property="found.gcc"&
&or&
&available file="gcc" filepath="${env.PATH}" /&
&available file="gcc.exe" filepath="${env.PATH}" /&
&available file="gcc.exe" filepath="${env.Path}" /&
&/or&
&/condition&
&/target&
可以通过编写依赖的目标,如果程序不存在,要么使用&fail&任务,要么仅仅跳出某个执行步骤:
&target name="compile_cpp" depends="verify_gcc" if="found.gcc"&
&exec executable="gcc" ... /&
&/target&
第三部分: 使用&apply&进行批量运行
将一个文件列表传递给外部可执行文件程序的特性问题,可以使用&apply&任务来解决,这个任务接受一个文件集并将其传递给指定的应用程序,既可以一次传完,也可以逐个传递。
&&&&& &apply&是作为&exec&的一个子类而被实现,所以&exec&任务的所有属性,都可以用于&apply&;除此之外,它还包括一个批处理的附加功能。
例如有一个本地程序,可以将XML文件转换为PDF,它有两个参数:XML文件的路径,以及对应的PDF文件的路径:
&apply executable="cmd" dest="docs"&
&arg line="/c echo"/&
&arg value="convert"/&
&srcfile/&
&targetfile/&
&fileset dir ="." includes="*.xml"/&
&mapper type="glob" from="*.xml" to="*.pdf"/&
&/apply&
在Windows平台上运行,并使用内置echo命令,必须将可执行文件设置为cmd以便echo可以正常工作,打开/c开关使得命令行shell在echo完成后自动退出。对于同一个目录下数个xml文件的执行,输出如下:
[apply] convert C:\AntBook\Sections\Learning\callingotherprograms\apply.xml
C:\AntBook\Sections\Learning\callingotherprograms\docs\apply.pdf
[apply] convert C:\AntBook\Sections\Learning\callingotherprograms\execution.
xml C:\AntBook\Sections\Learning\callingotherprograms\docs\execution.pdf
[apply] convert C:\AntBook\Sections\Learning\callingotherprograms\java.xml C
:\AntBook\Sections\Learning\callingotherprograms\docs\java.pdf
[apply] convert C:\AntBook\Sections\Learning\callingotherprograms\probes.xml
C:\AntBook\Sections\Learning\callingotherprograms\docs\probes.pdf
[apply] convert C:\AntBook\Sections\Learning\callingotherprograms\shells.xml
C:\AntBook\Sections\Learning\callingotherprograms\docs\shells.pdf
到目前为止,它所做的全部工作就是显示我们要执行的命令,但是并没有实际执行它。
&apply&隐含依赖关系检查。目标文件新于源文件,它就被忽略。
一旦对echo的输出结果满意,看到它为每个文件将执行预期的命令行,就可以把属性值由convert修改为executable,去掉/c echo参数,然后再回到正题。
该任务的parallel选项的意思是”一次传入全部的文件”,而不是”并行执行该任务多次”。
第四部分:处理输出:
以上介绍的三个任务:&java&,&exec&和&apply&这三个任务,都允许你使用output参数将输出结果保存到文件中,可以将这个文件传入别的程序,或者一个ant任务,其中的两个任务&exec&和&apply&,还可以将调用的值存入特性,该特性接下来可以被扩展应用为其他任务的参数。例如:可以将构建阶段的结果发email给其他人:
&exec executable="unregbean" output="beans.txt" &
&arg value="-d"/&
&/exec&
&mail from="build" tolist="operations"
subject="list of installed beans for ${user.name}"
failonerror="false"
files="beans.txt"/&
这种将生成的文件和报告用email发出去的办法,在自动化的构建和测试系统中是常见的功能。
lijiang0072001
浏览: 20148 次
来自: 重庆}

我要回帖

更多关于 微信通讯录删除联系人 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信