Snake's Home

snake


  • 首頁

  • 歸檔

  • 標籤
Snake's Home

Docker 之 ubuntu 上实践

發表於 2015-03-06 | 分類於 Docker

1. 环境。

我是用13.04 升级上来的。
先用命令看:

/etc/issue```
1
版本为 13.2

然后用命令:
```sudo apt-get update
sudo apt-getdist-upgrade

升级好后,更改ubuntu的源, 原因你懂的。
Ubuntu14.04更新源
Ubuntu14.04 LTS更新源
用的阿里的源,最后成功了。

在Windows 7 下使用 VirtualBox 安装了一个 Ubuntu 14.10 后,碰到了一个 640×480屏幕分辨率的问题。在 ‘DisplaySettings’设置界面的 ‘Detect Displays’按钮无法点击到,因为 640x480的分辨率的确太小了。
解决办法
你需要安装一个 VirtualBox的额外组件到你的 Ubuntu-Guest 中,可运行如下命令:

apt-get install virtualbox-guest-dkms```
1
安装完毕需要重启虚拟机就可以。
[修复 VirtualBox 下 Ubuntu 14.10 屏幕分辨率问题](http://www.oschina.net/question/12_178184?fromerr=HU30mmgo)

# 2. 使用:
参照:
[Docker实践](http://blog.csdn.net/lincyang/article/details/43055061)

实践了一把:
下面说说我在Ubuntu14.04下的安装。        
1.将镜像加入到程序源中:
```~$ sudo sh -c "echo deb http://mirror.yandex.ru/mirrors/docker/ docker main > /etc/apt/sources.list.d/docker.list" ``` 
2.接着update
```$ sudo apt-get update

3.如果报错就fix掉它:

GPG error:docker Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY D8576A8BA88D21E9```
1

解决此错误:
```$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys D8576A8BA88D21E9``` 
4.下载docker:
```$ sudo apt-get install lxc-docker``` 
静静的等待它下载完成吧。
另外,这个命令也许会有帮助:
```$ curl sSL https//get.docker.com/ubuntu/ | sudo sh

然后Docker 还顺利安装成功了。 虽然有点慢。

实践:
搜索仓库中是否有wordpress这个博客镜像,如下:

docker search wordpress```
1

2.下载这个镜像
```$ docker pull wordpress```  

下载镜像的时候,几乎是下载不下来。
然后在pull image的时候,老不成功,等了半天,总是出这样的错误:
```Error pulling image(latest) from mysql, Server error: Status 0 while fetching image laye

百度搜索:
Error in pulling down images indocker: Status 0
找到的解决方案是关防火墙,关了也没起到作用。
然后找到了解决方案:
更改了docker 的镜像源,用国内的了。

"DOCKER_OPTS=\"\$DOCKER_OPTS --registry-mirror=http://f2d6cb40.m.daocloud.io\"" | sudo tee -alink
1
```sudo service docker restart

然后下载都成功了:

docker pull mysql```
1
```Sudo docker pull wordpress

启动:

1
2
$sudo docker run --name mysql_wordpress -e MYSQL_ROOT_PASSWORD=wordpress  -d  mysql 
$sudo docker run --name docker_wordpress --link mysql_wordpress:mysql -p 8080:80 -d wordpress

接下来就可以在浏览器中输入http://localhost:8080进行wordpress的配置了, 结果真的成功了。

  1. Jenkins:

因为wordpress 将8080 给占用了, 后面找到命令杀掉。

Docker常用命令

1
2
3
docker pull jenkins

docker run -p 8080:8080 jenkins

然后敲入:http://localhost:8080/

Jenkins 也启动起来了。

参考:
jenkins-in-docker

jenkins-cloud-provider

container-solutions

docker-jenkins

如何使用Dockerfile构建镜像

Snake's Home

Jmeter 测试接口及性能

發表於 2014-12-06 | 分類於 performance

一、什么是接口测试?

  接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。
  接口测试适用于为其他系统提供服务的底层框架系统和中心服务系统,主要测试这些系统对外部提供的接口,验证其正确性和稳定性。接口测试同样适用于一个上层系统中的服务层接口,越往上层,其测试的难度越大。
  接口测试实施在多系统多平台的构架下,有着极为高效的成本收益比,接口测试天生为高复杂性的平台带来高效的缺陷监测和质量监督能力。平台越复杂,系统越庞大,接口测试的效果越明显。
  基于接口测试的重要性,以及它比较容易自动化的特性,通过持续集成的接口监控能够及时的发现项目中存在的问题,这对持续运营的项目来说,非常重要。

二、接口测试的流程

  1、 项目启动后,测试人员要尽早找到开发人员拿到接口测试文档
  2、 获取接口测试文档后,就可以进行接口用例的编写和调试
  3、 接口用例编写调试完成后,部署到持续集成的测试环境中,
  4、 设定脚本运行频率,告警方式等基本参数,进行接口的日常监控
  5、 每日进行接口脚本的维护更新,接口异常的处理

三、编写接口测试脚本

大部分性能工具都可以用来进行接口测试,jmeter就是一个好用的性能测试工具,他也同样可以用来进行接口测试,jmeter比较适用于CGI、webservice、DB等类型的接口测试。下面以websevice api接口为例说明如何编写接口测试用例
以下是我弄的一个简单的脚本。
每个请求都加一个响应断言来判断是否达到期望。
如果用命令来执行,也很简单:
jmeter -n -t test.jmx -l test.jtl
四、接口持续集成

在这块卡了好久,主要是report展示。之前是不想再用其他工具(如:Ant, Maven ), 就想将jtl文件的报告展现出来,弄了很久没成功。最后还是向工具屈服,用的Ant来编译.
主要是配置build.xml
一个示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
<?xml version="1.0" encoding="UTF-8"?>

<project name="ant-jmeter-test" default="all" basedir=".">
<tstamp>
<format property="time" pattern="yyyyMMddhhmm" />
</tstamp>
<!-- 需要改成自己本地的 Jmeter 目录-->
<property name="jmeter.home" value="F:\xxxxx\Jmeter" />
<!-- jmeter生成jtl格式的结果报告的路径-->
<property name="jmeter.result.jtl.dir" value="F:\xxxxx\resultLog\jtl" />
<!-- jmeter生成html格式的结果报告的路径-->
<property name="jmeter.result.html.dir" value="F:\xxxxx\resultLog\html" />
<!-- 生成的报告的前缀->
<property name="ReportName" value="TestReport" />
<property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${ReportName}${time}.jtl" />
<property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${time}.html" />

<target name="all">
<antcall target="test" />
<antcall target="report" />
</target>

<target name="test">
<taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" />
<jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">
<!-- 声明要运行的脚本。"*.jmx"指包含此目录下的所有jmeter脚本-->

<testplans dir="D:\test_case_path" includes="*.jmx" />
</jmeter>
</target>

<target name="report">
<xslt in="${jmeter.result.jtlName}"
out="${jmeter.result.htmlName}"
style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl" />


<!-- 因为上面生成报告的时候,不会将相关的图片也一起拷贝至目标目录,所以,需要手动拷贝 -->
<copy todir="${jmeter.result.html.dir}">
<fileset dir="${jmeter.home}/extras">
<include name="collapse.png" />
<include name="expand.png" />
</fileset>
</copy>
</target>
</project>

Jenkins 上安装 “Publish performance test result report” ,“Publish HTML reports” 的插件,配置一下。
运行。
之前一直出了个错:

1
2
3
4
Performance: Recording JMeter reports '**/*.jtl'
Performance: no JMeter files matching '**/*.jtl' have been found. Has the report generated?. Setting Build to FAILURE
Build step 'Publish Performance test result report' changed build result to FAILURE
Finished: FAILURE

导致结果出不来。后面在 Jmeter/bin 下将 jmeter.properties 中的:

1
改成:
```jmeter.save.saveservice.output_format=xml

文章发表在testerhome

Snake's Home

python unit test 的顺序

發表於 2014-12-01 | 分類於 python

之前在IOS上,用python和appium 写case时,发现执行顺序是乱的。

后面用了个程序来测试这个顺序:

发现它是按照case的名字的,而不是按照先后顺序的。

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#encoding=utf-8
from selenium import webdriver
import unittest
import time
import HTMLTestRunner
class test_class(unittest.TestCase):
def setUp(self):
print "开始测试"
def test_ie(self):
self.driver = webdriver.Ie()
self.url="http://www.baidu.com"
self.driver.get(self.url)
print "ie"
self.driver.quit()
def test_chrome(self):
self.driver = webdriver.Chrome()
self.url="http://www.163.com"
self.driver.get(self.url)
print "chrome"
self.driver.quit()
def test_print1(self):
print "1什么玩意"
self.driver = webdriver.Chrome()
self.url="http://www.sina.com.cn"
self.driver.get(self.url)
self.driver.quit()
def test_print2(self):
print "2我到!"
self.driver = webdriver.Chrome()
self.url="http://www.tianya.cn"
self.driver.get(self.url)
self.driver.quit()
def tearDown(self):
print "结束测试"
pass
if __name__=="__main__":
testsuite=unittest.TestSuite()
testsuite.addTest(test_class("test_ie"))
testsuite.addTest(test_class("test_chrome"))
testsuite.addTest(test_class("test_print2"))
testsuite.addTest(test_class("test_print1"))
filename="D:\\test\\result.html"
fp=file(filename,'wb')
runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title='Result',description='Test_Report')
runner.run(testsuite)

总算解决了个问题。

Snake's Home

git

發表於 2014-10-19 | 分類於 git

偶尔想提代码,就会需要用到git.

工作中用到:

1
git merge origin/master
1
2
3
git stash
git rebase origin/master
git stash pop

以下有几个比较好的教程:

Github 简明教程

廖雪峰Git教程

命令速查

Snake's Home

python实现自动化构件和持续集成Android

發表於 2014-10-10 | 分類於 python

公司的打包效率太低下了, 没有持续构建和集成。
每次要等开发打包。碰到那个开发请假,其他的开发又不会,要等。
而且没有版本管理。想找一个以前的版本,都没有。
开始想用gradle打包,当时还是1.0.0,坑太多。
用maven,有个依赖总是不成功。
最后还是用原始的Ant打包,实现了自动化构建。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
from os import walk as oswalk  
from os import chdir as oschdir
from os import popen as ospopen
from os.path import exists as pathexists
from os.path import join as pathjoin
from shutil import copyfile as shcopy
from shutil import rmtree as shrmtree
import shutil
import sys
import time
import os

#consts
LIBRARY = "library"
TRUNK = "trunk"
CIRCLE = "Circle"
PROJECT_PROPERTY = "project.properties"
BIN = "bin"
OBJ = "obj"
APK = "Circle-debug.apk"
remote_path=r"\\10.21.101.100\XXX\build\android"
local_path=r"D:\dailyAPK"

class AndroidBuilder:
__base_path = ""
__output_path = ""
__use_ndk = False

def __init__(self, base_path, output_path, use_ndk):
self.__base_path = base_path
self.__output_path = output_path
self.__use_ndk = use_ndk

def __execmd(self, cmd):
ret = ospopen(cmd).readlines()
for line in ret:
print(line)

def __re_native(self):
print("re-build shared objects")
if (pathexists(OBJ)):
shrmtree(OBJ)
self.__execmd("ndk-build clean")
self.__execmd("ndk-build")


def __move_qrcode(self):
zxing_path = pathjoin(self.__base_path, TRUNK, CIRCLE, "qrcode", "com", "XXX", "zxing")
dest_path = pathjoin(self.__base_path, TRUNK, CIRCLE, "src", "com", "XXX")
print "aaa",zxing_path
print "bbb",dest_path
shutil.copy(zxing_path, dest_path)
#shutil.copy2(zxing_path, dest_path)
#shutil.copytree(zxing_path, dest_path,True)
print "wo cao"
if (pathexists(dest_path)):
shrmtree(dest_path)
print "ccc",zxing_path
print "ddd",dest_path
shcopy(zxing_path, dest_path)


def __re_ant(self):
idx = 0
project_properties = "target=android-19\n\n"
for dirpath, dirname, filename in oswalk(pathjoin(self.__base_path, LIBRARY)):
print "------------------",dirname
for dir in dirname:
print("re-ant project %s" % (dir))
oschdir(pathjoin(self.__base_path, LIBRARY, dir))
idx += 1
project_properties += "android.library.reference.%d=../../%s/%s\n" % (idx, LIBRARY, dir)
self.__execmd("android update project -n %s -p . -t android-19" % (dir))
self.__execmd("ant clean")
break
print("re-ant project Circle")
oschdir(pathjoin(self.__base_path, TRUNK, CIRCLE))
self.__execmd("android update project -n Circle -p . -t android-19")
property_file = open(PROJECT_PROPERTY, "w")
property_file.write(project_properties)
property_file.flush()
property_file.close()


def make_apk(self):
self.__re_ant()
oschdir(pathjoin(self.__base_path, TRUNK, CIRCLE))
if (self.__use_ndk == True):
self.__re_native()
print("build apk")
#self.__move_qrcode()
self.__execmd("ant debug")
apk_path = pathjoin(self.__base_path, TRUNK, CIRCLE, BIN, APK)
if pathexists(apk_path):
shcopy(apk_path, pathjoin(self.__output_path, APK))
print("Build completed.!")
else:
print("Build failed.")

def move_remote(self, base_path, output_path,oldname):
print "aaa",base_path
print "bbb",output_path
base_file = base_path + '\\'+oldname
output_file=output_path+ '\\'+oldname
print base_file
shutil.copy2(base_file, output_file)
now1 = time.strftime('%Y-%m-%d-%H_%M_%S', time.localtime(time.time()))
newfname="%sCircle-debug.apk"%(now1)
newfpath="%s/%s"%(output_path,newfname)
oldfpath="%s/%s"%(output_path,oldname)
os.rename(oldfpath, newfpath)

pass


def print_help():
print("usage:")
print(" python make_android.py <base_path> <output_path> <use-ndk>")
print(" path must be absolute path, do NOT accept relative path")
print("sample:")
print(" python make_android.py /home/XXX/android /home/XXX/Desktop true")
pass

if __name__ == "__main__":
if len(sys.argv) != 4:
print_help()
exit()
# base_path, output_path
base_path = sys.argv[1]
output_path = sys.argv[2]
use_ndk = sys.argv[3]
if (base_path.startswith(".") or output_path.startswith(".")):
print_help()
exit()
ab = AndroidBuilder(base_path, output_path, use_ndk == "true")
ab.make_apk()
ab.move_remote(local_path, remote_path, APK)

公司的source管理工具,是svn,结果每次拉的代码不是最新的。
后面找到原因了,就是要在命令里面加@head.

文章发表在 testerhome

Snake's Home

python接口测试

發表於 2014-09-09 | 分類於 python

当时做的一个项目,开始是用postman,手工改参数来测试接口请求。
后面改进了一下,把请求和参数,以及期望结果写在了一个Excel里面,然后生成PDF报告。

APItest.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#encoding:utf-8  

import ConfigParser
import os
import xlrd
import re
import httplib
import urllib
from urlparse import urlparse
import json
import time
import unittest
import pdf

currentdir=os.path.split(os.path.realpath(__file__))[0]
class test_class():
def getexcel(self):
casefile=currentdir + '/case.xls'
if ((os.path.exists(casefile))==False):
print "当前路径下没有case.xls,请检查!"
data=xlrd.open_workbook(casefile)
table = data.sheet_by_name('login')
nrows = table.nrows #行数
ncols = table.ncols #列数
#colnames = table.row_values(1) #某一行数据
for rownum in range(1,nrows):
for col in range (3, ncols):
value=table.cell(rownum,col).value
if (col==3):
method=value
if (col==4):
url=value
return table,nrows,ncols

def getexceldetail(self,table,row,ncols):
#rownum = table.row_values(row) #某一行数据

for col in range (0, ncols):
value=table.cell(row,col).value
if (col==0):
caseid=value
print caseid
if (col==3):
method=value
print method
if (col==4):
url=value
return method,url,caseid

def httpget(self,url):
httpClient = None
conn = urlparse(url)
url=url.encode('utf-8')
try:
httpClient = httplib.HTTPConnection(conn.netloc, timeout=10)
httpClient.request('GET', url)

# response是HTTPResponse对象
response = httpClient.getresponse()
print response
d0=response.read()
d0=d0.decode('unicode_escape')
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()
return response.status,d0

def httppost(self,url):
httpClient = None
conn = urlparse(url)
url=url.encode('utf-8')
try:
header = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}

httpClient = httplib.HTTPConnection(conn.netloc, timeout=30)
httpClient.request("POST", url)
response1 = httpClient.getresponse()
d1=response1.read()
d1=d1.decode('unicode_escape')
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()
return response1.status,d1

def compare(self,status,actualljson):
if (status==200):
print "request pass"
if ( actualljson['response'] =='100'):
print "pass"
result="pass"
else:
print "fail"
result="fail"
else:
print "request fail"
result="fail"
return result

def transferlist2dict(self,data):
#index=data.find(":")
text=data.replace('=',':')
strList=text.split(',')
strDict={}
for strItem in strList:
strCh=strItem.split(':')
strDict[strCh[0]]=strCh[1]
return strDict

def testapi(self):
table,number,ncolor=self.getexcel()
pcount=0
fcount=0
failidlist=[]
for n in range(1,number):
Start=time.time()
method,url,caseid=self.getexceldetail(table,n,ncolor)
print Start
if (method=="GET"):
status,readvalue=self.httpget(url)
#readvalue=json.loads(readvalue)
#self.compare(status,readvalue)
if (method=="POST"):
status,readvalue=self.httppost(url)
readvalue=json.loads(readvalue)
result=self.compare(status,readvalue)
if (result=="pass"):
pcount=pcount+1
else:
fcount=fcount+1
print caseid
failidlist.append(caseid)
End=time.time()
diff= End-Start
print "The time is " +str(diff)
return pcount,fcount,failidlist

now1 = time.strftime('%m-%d-%H_%M_%S', time.localtime(time.time()))
t=test_class()
pcount,fcount,failidlist=t.testapi()
datas=[(0,fcount),(0,pcount)]
now2 = time.strftime('%m-%d-%H_%M_%S', time.localtime(time.time()))
ytype=[now1,now2]
des="API test result"
des1="Pass:%s,Fail:%s,Failed ID: %s"%(pcount,fcount,failidlist)
print des1
f=pdf.pdfreport()
f.createpdf(datas,ytype,des,des1)

pdy.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
from reportlab.graphics.shapes import Drawing  
from reportlab.graphics.charts.barcharts import VerticalBarChart
from urllib import urlopen
from reportlab.graphics.shapes import *
from reportlab.graphics.charts.lineplots import LinePlot
from reportlab.graphics.charts.textlabels import Label
from reportlab.graphics import renderPDF
class pdfreport():
def createpdf(self,datas,ytype,des,des1):
drawing = Drawing(400, 200)
#data = [(13, 5, 20),(14, 6, 21)]
data=datas
bc = VerticalBarChart()
bc.x = 50
bc.y = 50
bc.height = 125
bc.width = 300
bc.data = data
bc.strokeColor = colors.black
bc.valueAxis.valueMin = 0
bc.valueAxis.valueMax = 50
bc.valueAxis.valueStep = 10
bc.categoryAxis.labels.boxAnchor ='ne'
bc.categoryAxis.labels.dx = 8
bc.categoryAxis.labels.dy = -2
bc.categoryAxis.labels.angle = 30
#bc.categoryAxis.categoryNames = ['Jan-99','Feb-99','Mar-99']
bc.categoryAxis.categoryNames =ytype
drawing.add(bc)

#drawing.add(String(250,150,"ss", fontSize=14,fillColor=colors.red))
drawing.add(String(250,150,des, fontSize=14,fillColor=colors.black))
drawing.add(String(50,140,des1, fontSize=14,fillColor=colors.red))
renderPDF.drawToFile(drawing,'APIReport.pdf','API')
#renderPDF.drawToFile(drawing,'APIReport.pdf','API')

本文发表在: Testerhome

Snake's Home

python解析json

發表於 2014-08-11 | 分類於 python

做接口测试的时候,就要对json请求进行解析。

1. python 解析 json

1
2
3
4
5
6
7
8
9
10
import urllib2  
import json

html = urllib2.urlopen(r'http://api.douban.com/v2/book/isbn/9787218087351')

hjson = json.loads(heml.read())

print hjson['rating']
print hjson['images']['large']
print hjson['summary']

2. python 中文乱码的解决:

1
2
3
4
5
6
7
8
9
10
11
12
import sys,codecs, types  
def code():
var1 = "nihao"
var2 = "你好"
print var1
print var2
var2 = var2.decode('utf-8').encode('gbk')
print var2


if __name__ == "__main__":
code()

程序中“你好”默认用UTF-8 编码,程序中先将var2以UTF-8解码再以gbk编码,就可以输出正确的中文

3. python 用httplib发送请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#httplib是Python的http协议的内置,实现模块,使用它可以很简洁的实现http发送请求。   
import httplib
import urllib

#连接服务器

conn=httplib.HTTPConnection('www.python.org')

#发送HTTP请求

conn.request('GET','url')

#得到结果

result=conn.getresponse()

#获取HTTP请求结果值。200为成功

resultStatus=result.status

#获取请求的页面内容

content=result.read()

#关闭连接

conn.close()

#如果要模拟客户端进行请求,可以发送HTTP请求头

headers={"Content-Type":"text/html;charset=gb2312"}

conn.request('POST','url',headers=headers)

#带参数传送

params = urllib.urlencode({'pname':'pvalue'});

conn.request('POST','url',body=params)

发送get 请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python  
#coding=utf8

import httplib

httpClient = None

try:
httpClient = httplib.HTTPConnection('localhost', 80, timeout=30)
httpClient.request('GET', '/test.php')

#response是HTTPResponse对象
response = httpClient.getresponse()
print response.status
print response.reason
print response.read()
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()

发送post请求

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/env python  
#coding=utf8

import httplib, urllib

httpClient = None
try:
params = urllib.urlencode({'name': 'tom', 'age': 22})
headers = {"Content-type": "application/x-www-form-urlencoded"
, "Accept": "text/plain"}

httpClient = httplib.HTTPConnection("localhost", 80, timeout=30)
httpClient.request("POST", "/test.php", params, headers)

response = httpClient.getresponse()
print response.status
print response.reason
print response.read()
print response.getheaders() #获取头信息
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
def httpget(self,url):
httpClient = None
conn = urlparse(url)
url=url.encode('utf-8')
try:
httpClient = httplib.HTTPConnection(conn.netloc, timeout=10)
httpClient.request('GET', url)

response = httpClient.getresponse()
print response
d0=response.read()
d0=d0.decode('unicode_escape')
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()
return response.status,d0



def httppost(self,host,path,params):
httpClient = None
# conn = urlparse(url)
# url=url.encode('utf-8')
try:

body=json.dumps(params)
header = {"Content-type": "application/json", "Accept": "text/plain"}

httpClient = httplib.HTTPConnection(host, timeout=30)
httpClient.request('POST', path, body, header)
response = httpClient.getresponse()
print response.status
#print response.read()

d1=response.read()
#d1=d1.decode('unicode_escape')
d1=json.loads(d1)
except Exception, e:
print e
finally:
if httpClient:
httpClient.close()
return d1
Snake's Home

python操作excel

發表於 2014-07-20 | 分類於 python

一、安装xlrd模块

到xlrd官网下载模块安装,前提是已经安装了python 环境。

我在windows 上用的是 pip install xlrd

二、使用介绍

1、导入模块

import xlrd

2、打开Excel文件读取数据

data = xlrd.open_workbook('excelFile.xls')

3、使用技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
        获取一个工作表

table = data.sheets()[0] #通过索引顺序获取

table = data.sheet_by_index(0) #通过索引顺序获取


table = data.sheet_by_name(u'Sheet1')#通过名称获取

获取整行和整列的值(数组)
  table.row_values(i)

table.col_values(i)

获取行数和列数
  
nrows = table.nrows

ncols = table.ncols

循环行列表数据
for i in range(nrows ):
print table.row_values(i)

单元格
cell_A1 = table.cell(0,0).value

cell_C4 = table.cell(2,3).value

使用行列索引
cell_A1 = table.row(0)[0].value

cell_A2 = table.col(1)[0].value

简单的写入
row = 0

col = 0
<!-- 类型 0 empty,1 string, 2 number, 3 date, 4 boolean, 5 error-->

ctype = 1 value = '单元格的值'

xf = 0 # 扩展的格式化

table.put_cell(row, col, ctype, value, xf)

table.cell(0,0) #单元格的值'

table.cell(0,0).value #单元格的值'

三、Demo代码

Demo代码其实很简单,就是读取Excel数据。

1
2
3
4
5
6
7
8
9
 # -*- coding: utf-8 -*-   
import xlrd
data=xlrd.open_workbook('aa.xls')
table=data.sheets()[0]
nrows = table.nrows
ncols = table.ncols
print table
print nrows
print ncols

另一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 # -*- coding: utf-8 -*-   
import xdrlib ,sys
import xlrd
def open_excel(file= 'file.xls'):
try:
data = xlrd.open_workbook(file)
return data
except Exception,e:
print str(e)
#根据索引获取Excel表格中的数据 参数:file:Excel文件路径 colnameindex:表头列名所在行的所以 ,by_index:表的索引
def excel_table_byindex(file= 'file.xls',colnameindex=0,by_index=0):
data = open_excel(file)
table = data.sheets()[by_index]
nrows = table.nrows #行数
ncols = table.ncols #列数
colnames = table.row_values(colnameindex) #某一行数据
list =[]
for rownum in range(1,nrows):

row = table.row_values(rownum)
if row:
app = {}
for i in range(len(colnames)):
app[colnames[i]] = row[i]
list.append(app)
return list

#根据名称获取Excel表格中的数据 参数:file:Excel文件路径 colnameindex:表头列名所在行的所以 ,by_name:Sheet1名称
def excel_table_byname(file= 'file.xls',colnameindex=0,by_name=u'Sheet1'):
data = open_excel(file)
table = data.sheet_by_name(by_name)
nrows = table.nrows #行数
colnames = table.row_values(colnameindex) #某一行数据
list =[]
for rownum in range(1,nrows):
row = table.row_values(rownum)
if row:
app = {}
for i in range(len(colnames)):
app[colnames[i]] = row[i]
list.append(app)
return list

def main():
tables = excel_table_byindex()
for row in tables:
print row

tables = excel_table_byname()
for row in tables:
print row

if __name__=="__main__":
main()

先引入xlwt模块
然后实验了一下,成功了一些,用的是: pip install xlwt

1
2
3
4
5
6
7
8
9
 # -*- coding: utf-8 -*-   
import xlwt
book=xlwt.Workbook(encoding='utf-8',style_compression=0)
sheet=book.add_sheet('dede',cell_overwrite_ok=True)
sheet.write(0,0,'fuck')
txt='输入中文'
txt.decode('gbk')
sheet.write(1,1,txt.decode('gbk'))
book.save('D:\\e\\API\\aa.xls')

目前的版本只支持Excel2010, 高版本的支持不了。

Snake's Home

自动化测试与持续集成方案--IOS Daily Build

發表於 2014-07-06 | 分類於 IOS

首先你得有Mac的电脑,xcode, 开发者证书。
安装 xctool.

配置好证书,然后在命令行转到项目目录.

1
2
3
4
5
6
1.清除  
EthantekiiMac:CTest ethan$ xcodebuild clean
2.编译
EthantekiiMac:CTest ethan$ xcodebuild -target CTest -configuration Release
3.打包ipa
EthantekiiMac:CTest ethan$ xcrun -sdk iphoneos PackageApplication -v /Volumes/workildCommand/test/CTestild/Release-iphoneos/CTest.app -o /Volumes/workildCommand/test/CTest/CTest.ipa

跟 android ant 打包一样,也是三条命令

#!/bin/sh
#  autoBuild.sh
#  Created by Anderson on 14-04-28. 
#  Copyright (c) 2014年 Anderson. All rights reserved.
###############################################
#使用方法
#./autoBuild.sh arg1 arg2
#arg1 项目的路径,例如:/Users/apple/code
#arg2 为项目编译ID
###############################################

###############################################

#参数检查
if [ -z "$1" ]; 
then
echo "error:项目路径为空"
exit 1
fi
if [ -z "$2" ]; 
then 
echo "error:项目编译ID为空"
exit 1
fi
#日志地址
logPath="${1}/log.txt"
#ipa地址 
ipaPath="${1}/${2}.ipa"
##############################################

#清理项目 
cd $1
xcodebuild clean

###############################################

#编译并将日志写到文件 正式使用需要修改 Debug/Release
xcodebuild -target XXXX -configuration Debug > ${logPath}
#判断是否编译成功
if [[ $? -eq 0 ]];  
then
echo "build success"
else
cho "build error"
exit 2
fi

###############################################
#生成ipa
xcrun -sdk iphoneos PackageApplication -v build/Debug-iphoneos/*.app -o ${ipaPath}
if [[ $? -eq 0 ]];  then
rm -rf build
echo "create ipa success"
exit 0
else
echo "create ipa error"
exit 2
fi

打包能成功。通过Debug/Release来控制签名和不签名。

Jenkins 上要装xcode 的插件。 配置好后,你会发现一直失败,每次都会在codsign出错。然后你不在jenkins中调用,只用命令执行是通过的。这个问题困惑了我好久,最后找到了方案:
在jenkins中设置Unlock Keychain.

本文发表在:Testerhome

Snake's Home

cmd中之行adb 

發表於 2014-06-21 | 分類於 python

在用python编写脚本对android操作时,有时需要通过cmd命令直接对app操作。这样的好处是,如果你想对一页界面操作,不用一步一步的进行界面跳转,可以从主界面一下子调到你想要操作的界面。
通过os.popen()方法打开一个cmd命令

1、os.popen(“adb wait-for devices”):等待连接设备

2、os.popen(“adb shell screencap -p /data/local/tmp.png”):截屏后将图片以.png格式放在 /data/local/文件夹下

3、os.popen(“adb shell pull /data/local/“ +PATH(path+”/“ +timestamp + “.png”)):将手机/data/local/文件夹下文件传到手机文件夹下,并对图片以当时时间命名

4、os.popen(“adb shell am start -n com.xxx.xxx/com.xxx.xxx.plugins.PluginCenterActicity”):直接跳转并打开com.xxx.xxx下的com.xxx.xxx.plugins.PluginCenterActicity界面

下边是手机截屏并上传到电脑中的代码:

#!/usr/bin/pyton
#encoding=utf-8
import time
import sys
import os


timestamp = time.strftime('%Y-%m-%d-%H-%M-%S',time.localtime(time.time()))

type = """
    1. screenshot
    2. logcat
    3. tracefile
    4. device information
"""
print type
yourtype = raw_input("Please choose type: ")

def getlogcat():
        path = os.getcwd()+"/output/logcat"
        if not os.path.isdir(path):
            os.makedirs(path)
        logcatname=path+"/"+timestamp+r"logcat.log"
        cmdlogcat="adb logcat -d >%s" %(logcatname)  
        os.popen(cmdlogcat)   

def gettracefile():  
        path = os.getcwd()+"/output/trace"
        if not os.path.isdir(path):
            os.makedirs(path)
        tracename = path+"/"+timestamp+r"trace.log"
        cmd="adb shell cat /data/anr/traces.txt>%s" %(tracename)
        os.popen(cmd) 

def screenshot():
        path = os.getcwd()+"/output/pic"
        if not os.path.isdir(path):
            os.makedirs(path)


        os.popen("adb shell screencap -p /sdcard/monkey_run.png")

        cmd="adb pull /sdcard/monkey_run.png %s" %(path)
        os.popen(cmd)  
        os.popen("adb shell rm /sdcard/monkey_run.png")
        oldname = path+"/" + "monkey_run.png"
        newname= path+"/" + timestamp +r".png"
        os.rename(oldname, newname)

        print "success"

def getdeviceinfo():
        cmd = 'adb shell cat /system/build.prop'
        deviceinfo = os.popen(cmd)
        infoList = deviceinfo.readlines()
        #print infoList

        dict ={}

        param = ['ro.product.manufacturer','ro.build.version.release','ro.build.version.sdk','ro.product.model','ro.product.brand','ro.product.locale.language','ro.product.locale.region']

        for info in infoList:
            for each_param in param:
                if str(each_param) in str(info):
                    k = info.split('=')[0]
                    s = k.split('.')
                    dict[s[-1]] = info.split('=')[1].strip()
        print dict.items()


deviceText = os.popen('adb devices')
textList = deviceText.readlines()
deviceName = textList[1].split()[0]

if deviceName == '':
    print "please connect devices!"

else:

    if yourtype == '1':
        screenshot()

    if yourtype == '2':
        getlogcat()

    if yourtype == '3':
        gettracefile()

    if yourtype == '4':
        getdeviceinfo()
1…567
Snake

Snake

不要被困难击倒,除非你躺着睡大觉

69 文章
17 分類
57 標籤
© 2017 Snake
由 Hexo 強力驅動
主題 - NexT.Muse