crystal's Blog

生活、技术个人博客


  • Home

  • Archives

Gitlab-CI自动化集成测试

Posted on 2019-04-22
yml文件
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
# stages:
# - build
# - test
# - deploy
# job1:
# stage: build
# script:
# - 'pwd && /usr/local/maven/apache-maven-3.2.5/bin/mvn clean package'
# tags:
# - hgr

job2:
stage: test
script:
# - 'D:/apache-maven-3.3.9/bin/mvn test'
# - 'D:/apache-maven-3.3.9/bin/mvn jacoco:report'
# - 'echo \"$(cat target/site/jacoco/testcoverage.txt)% covered\"'
- 'D:/apache-maven-3.3.9/bin/mvn clean test && type E:\GitLab-Runner\builds\jut3BULm\0\caojunjie\test\target\site\jacoco\index.html'
tags:
- Test_ci

# job2:
# stage: deploy
# script:
# - 'pwd && /usr/local/maven/apache-maven-3.2.5/bin/mvn deploy'
# tags:
# - hgr

需要配置的 pom文件

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
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.test.jacoco</groupId>
<artifactId>testJacoco</artifactId>
<version>0.0.1-SNAPSHOT</version>

<name>JaCoCo Examples</name>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

<!-- Sonar -->
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<!-- The destination file for the code coverage report has to be set to the same value
in the parent pom and in each module pom. Then JaCoCo will add up information in
the same report, so that, it will give the cross-module code coverage. -->
<sonar.jacoco.itReportPath>${project.basedir}/target/jacoco.exec</sonar.jacoco.itReportPath>
<sonar.language>java</sonar.language>
</properties>

<dependencies>
<!--
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.5.3.201107060350</version>
</plugin>
</plugins>
</pluginManagement>

<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<configuration>
<includes>com.*</includes>
</configuration>
<executions>
<execution>
<id>pre-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>post-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
</plugins>
</build>

</project>

需要在gitlab ci中配置:

测试覆盖率解析为:

1
Total.*?([0-9]{1,3})%

复制Pipeline status/Coverage report中的html连接到readme.xml中。

直接就会项目首页中显示出来覆盖率和pieline的状态和覆盖率

selenium定位元素之 切换frame(iframe)

Posted on 2019-04-22

selenium定位元素之 切换frame(iframe)

一、怎么切到frame中(switch_to.frame())

selenium提供了switch_to.frame()方法来切换frame

1
2
3
iframe = driver.find_element_by_xpath
("/html/body/modal-container/div/div/app-minigame-modal/div/div/iframe") # 先定位到iframe的窗口
driver.switch_to.frame(iframe) # 即可切换到iframe窗口

reference是传入的参数,用来定位frame,可以传入id、name、index以及selenium的WebElement对象,假设有如下HTML代码 index.html:

1
2
3
4
5
6
7
8
<html>
<head>
<titile>TEST</title>
<body>
<iframe src='a.html' id="iframe1" name="myfame">
</body>
</head>
</html>

二、从frame中切回主文档(switch_to.default_content())

切到frame中之后,我们便不能继续操作主文档的元素,这时如果想操作主文档内容,则需切回主文档。

1
driver.switch_to.default_content() #切换到主窗口

三、嵌套frame的操作(switch_to.parent_frame())

1
2
3
4
5
6
7
8
9
<html>
<head>
<titile>TEST</title>
<body>
<iframe src='a.html' id="iframe1" name="myfame">
<iframe id="iframe2"/>
</body>
</head>
</html>

1、从主文档切到frame2,一层层切进去。

1
2
3
4
iframe = driver.find_element_by_xpath
("/html/body/modal-container/div/div/app-minigame-modal/div/div/iframe") # 先定位到iframe的窗口
driver.switch_to.frame(iframe) # 即可切换到iframe1窗口
driver.switch_to.frame(iframe2) # 切换到ifram2窗口

2、从frame2再切回frame1,这里selenium给我们提供了一个方法能够从子frame切回到父frame,而不用我们切回主文档再切进来。

1
driver.switch_to.parent_frame()  # 切换到ifram1,如果当前为主文档,则无效

有了parent_frame()这个相当于后退的方法,我们可以随意切换不同的frame,随意的跳来跳去了。

Untitled

Posted on 2018-11-26

Python MD5加密

需求:登录接口用户密码:需要在用户输入的密码加盐值。且在盐值的第八位和第九位之间插入密码··

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 读取文件中的接口信息:URL/用户名/密码/账户类型/等
def datacel(filrpath):
try:
file = xlrd.open_workbook(filrpath)
me = file.sheets()[0]
nrows = me.nrows
for i in range(3, nrows):
pwd = me.cell(i, 3).value # 获取excel文件中的第4行第4列的值
url = me.cell(i,4).value # 获取excel文件中的第4行第5列的值
data = json.loads(pwd) # 转化成json格式
data_pwd = data['password'] # 获取data中的password的值
data_account = data['account'] # 获取data中的account的值
data_type = data["accountType"]
datalist = [] # 定义一个新的dict类型的datalist存放账户,密码,类型等
datalist.append(data_pwd) # 追加到datalist
datalist.append(data_account)
datalist.append(data_type)
datalist.append(url)
print(datalist) #返回datalist
return datalist
except Exception as e:
print('打开测试用例失败,原因是:%s'%e)
return
1
2
3
4
5
6
7
8
9
# 生成一个盐值16位的盐值,盐值范围在A-Z 0-9中
def create_salt(length = 16):
salt = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
len_chars = len(chars) - 1
random = Random()
for i in xrange(length): # 每次从chars中随机取一位
salt += chars[random.randint(0, len_chars)]
return salt
1
2
3
4
5
6
7
8
9
10
11
12
13
# 在生成的盐值的第八位和第九位中插入密码,再进行MD5加密
def create_md5(pwd):

md = hashlib.md5()
salt = create_salt()
print(salt)
print(salt[0:8])
print(salt[8:])
new_pwd=salt[0:8].encode()+pwd.encode()+salt[8:].encode() # 在生成的盐值的第八位和第九位之间插入密码
print(new_pwd)
md.update(salt[0:8].encode()+pwd.encode()+salt[8:].encode()) # 生成MD5加密
print(md.hexdigest())
return md.hexdigest()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def login_user():
path = os.getcwd() + '\\case.xlsx'
data = datacel(path)
accountType = data[2]
pwd = data[0]
account = data[1]
url = 'http://47.99.122.85:8081'+data[3]
MD5_pwd = create_md5(pwd) # 将用户密码加密
headers={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:51.0) Gecko/20100101 Firefox/51.0","language":"zh_CN","appId":"1","Content-Type":"application/json"}
param={"account":account, "password":MD5_pwd, "accountType":accountType}
reslut=requests.post(url,json=param,headers=headers)
reslut.encoding = 'UTF-8'
json_response = json.loads(reslut.text)
print(json_response)


if __name__ == '__main__':
login_user()

jmeter之参数化

Posted on 2018-08-13

JMeter—-正则表达式&JSON Path Extractor

不知道你们在使用jmeter的时候有没有遇到过类似于我这样的问题,就是对于json格式的返回值要取其中某个key的value值,如果用正则表达式取的话就往往会取到空值。或者会把所有的匹配的key写出来。因此为了方便提取可以选择使用JSON Extractor进行提取

connect

例如:

请求的接口返回值:

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
{
"code":200,
"data":
{
"list":
[
{
"id":136,
"insertTime":"2018-08-13 10:46:23",
"item":
{
},
"num":1,
"priceType":1,
"skuId":43,
"uid":"745112018080615551",
"updateTime":"2018-08-13 10:46:23"
},
{
"id":101,
"insertTime":"2018-08-07 17:27:55",
"item":
{
"canRefund":0,
"courseId":2,
"courseName":"18328343333 计组",
"icon":"test/pic/1796308711224902736.jpg",
"orgId":1,
"orgName":"18328341111 的学校",
"prices":
[
{
"currency":1,
"gmtCreate":"2018-08-03 14:08:21",
"gmtUpdate":"2018-08-03 14:08:21",
"id":3,
"itemId":2,
"marketPrice":100.20,
"orginPrice":200.20
},

我需要取里面的id值作为参数传递到下一个接口。如图:

connect

Variable names : 名称

JSONPath Expression:JSON表达式

Match Numbers:匹配哪个,可为空即默认第一个

Default Value:未取到值的时候默认值
使用$.data.id 去提取id的值时,发现获取到的数据为空
原来这个responses 的data为数组,故应为$.data.list[0].id 提取第list数组中第1个id值


跨线程组传递变

使用场景:
我们在一个线程组中的一个返回参数只需要获取一次,但是这个返回值需要在其他的线程组中调用。

解决办法:

添加一个后置处理器——Beanshell Prerocessor

1、首先需要在需要获取的参数线程组中添加正则表达式/JSON Extranctor

connect

2、当前线程组中继续添加后置处理器——Beanshell Prerocessor

connect

3、Parameters:引用json表达式提取的变量teacherId

4、Script:具体beanshell语法大家可去查看相关资料,这里很简单,一条语句就搞定。
意思是把获取的变量 ${teacherId}设置为全局变量,并以新的名字newtoken来进行引用。
5、在引用的地方引用全局变量:teacherId

connect

引用方式是${__P(teacherId,)}注意花括号中是两个下划线,newtoken后还跟一个逗号,不要写漏了。

1
2
3
4
5
{
"teacherId":"${__P(teacherId,)}",
"name":"${__P(teachername,)}"

}

6、执行查看结果:

connect

Airtest-IDE

Posted on 2018-08-03

Airtest

Airtest-IDE-Study

简介

1
AirtestIDE 是一个跨平台的UI自动化测试编辑器,适用于游戏和App。

官网: LINK

连接Android手机

1、打开Android手机设置:设置-开发者选项-USB调试
2、AirtestIDE设备面板中点击“刷新ADB钮,查看连接上的设备

connect

3、点击对应设备的 Connect 按钮,进行初始化

注意: FAQ

连接好手机之后出现如下:

connect


Airtest辅助功能

Airtest-IDE-Study

简介Airtest辅助功能

1
Airtest 是一个 基于图像识别 的测试框架,AirtestIDE对Airtest进行了脚本生产支持,提供了图像脚本生成、脚本自动录制等辅助功能。

官网: LINK

Airtest脚本录制辅助窗

操作类型 辅助类型 断言类型
touch keyevent assert_exists
swipe centered assert_not_exists
wait are neat assert_equal
exist sleep assert_not_equal
snapshot \ \

Airtest脚本录制

1、点击 touch/swipe/wait/exists/assert_exists/assert_not_exists 按钮后,在设备画面上按下鼠标左键进行截图框选,抬起鼠标左键完成框选。对应操作语句会自动插入编辑器脚本中。
2、点击自动录制按钮后,使用鼠标操作设备画面,对应操作语句会自动插入到编辑器脚本中。

connect

插入截图功能

点击”插入截图”按钮后,在设备画面上框选截图后,对应图片会自动插入到编辑器脚本。可以使用本功能对图片进行自定义逻辑封装,比如循环识别某几个图片。

connect

123

Crystal_Girl

Thinking....

15 posts
© 2019 Crystal_Girl
Powered by Hexo
|
Theme — NexT.Muse v5.1.4