pytest + 登錄禪道 :自動提交bug-編輯bug-確認bug-解決bug-關閉bug
一、Pycharm中創建項目結構
1.新建一個工程,工程名稱自己定義,如:zentao
2.在工程的根目錄下新建一個conftest.py(測試用例的一些fixture配置)和pytest.ini(改變pytest的運行方式)
3.在工程下創建以下package包:
--case:這個包放test開頭的測試用例,也可以放一些非test開頭的封裝接口方法
--common:這個包放一些公共的方法,如:讀取excel文件方法,讀取mysql、oracle的腳本
--config:放一些配置文件,如郵箱的一些參數:收件人,發件人,密碼等
4.在工程下創建以下文件夾:
--logs:這里存放日志信息
--report:這里存放測試報告
二、開始寫腳本
思考:1.登錄之后,需要提bug,然后操作bug,如何保持登錄了?s=requests.session()可以實現保持會話;
2.假如登錄,提bug,操作bug,都寫在一個.py文件,可以使用s.get(...),s.post(...)操作所有請求,那若是這些操作在不同的.py文件呢?fixture自定義測試用例前置條件可以實現; 作用范圍session(多個文件調用一次,可以跨.py文件調用),conftest.py文件在當前所在目錄及以下目錄生效;
3.若是請求地址寫死,線下線上切換不方便,怎么辦?當然fixture可以搞定了
2.1 由此,conftest.py腳本的內容確定了,如下:
#注意這里的ip改為自己服務器的ip哦
#conftest.py import requests import pytest @pytest.fixture(scope="session") def s(): ss=requests.session() return ss @pytest.fixture(scope="session") def host(): host="http://47.98.66.11:8899" return host
2.2 編寫登錄的腳本
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
|
# coding:utf-8
#test_login.py
import
re
import
pytest
import
hashlib
import
allure
@allure
.severity(
"blocker"
)
@allure
.epic(
"禪道登錄,增刪改查測試"
)
@allure
.feature(
"禪道登錄"
)
@allure
.issue(
"http://47.98.66.11:8899/bug-browse-1-0-all.html"
)
class
Test_login:
@pytest
.fixture()
def
getrand(
self
,s,host):
while
True
:
r
=
s.get(host
+
"/user-login.html"
)
# print(r.text)
rand
=
re.findall(
"id='verifyRand' value='(.+?)'"
, r.text)
#print(rand)
if
len
(rand[
0
])
=
=
10
:
#break
print
(rand[
0
])
return
rand[
0
]
@pytest
.fixture()
def
md5(
self
,getrand):
first
=
hashlib.md5(
"P@ssw0rd"
.encode(
'utf-8'
)).hexdigest()
+
getrand
print
(first)
pwd
=
hashlib.md5(first.encode(
'utf-8'
)).hexdigest()
print
(pwd)
return
(getrand,pwd)
@allure
.title(
"登錄用例"
)
def
test_login(
self
,md5,s,host):
data
=
{
"account"
:
"admin"
,
"password"
:md5[
1
],
"passwordStrength"
:
1
,
"referer"
:
"/"
,
"verifyRand"
:md5[
0
],
"keepLogin"
:
1
}
r
=
s.post(host
+
"/user-login.html"
,data
=
data)
#print(r.__dict__)
# print(dir(r))
# # print(r.text)
r1
=
s.get(host
+
"/my/"
)
#print(r1.text)
assert
'退出'
in
r1.text
|
2.3 提交bug
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
|
# coding:utf-8
#test_newbug.py
import
pytest
import
re
import
random
import
allure
@pytest
.fixture()
def
uppic_steps(s,host):
#上傳圖片
f
=
{
"localUrl"
:
"D:\\ch.jpg"
,
"imgFile"
:(
"ch.jpg"
,
open
(
"D:\\ch.jpg"
,
"rb"
),
"image/jpeg"
)}
r
=
s.post(host
+
"/file-ajaxUpload-5f37e08f8d109.html?dir=image"
,files
=
f)
#print(r.text)
print
(r.json())
#picurl=re.findall(',"url":"(.+?)"}',r.text)[0].replace("\\","")
picurl
=
r.json()[
"url"
]
print
(
"上傳圖片地址:{}"
.
format
(picurl))
return
picurl
@pytest
.fixture()
def
get_uid(s,host):
#獲取uid
r
=
s.get(host
+
"/bug-create-1-0-moduleID=0.html"
)
uid
=
re.findall(
"kuid = '(.+?)'"
,r.text)
return
uid
@allure
.severity(
"critical"
)
@allure
.title(
"提bug"
)
def
test_newbug(s,uppic_steps,host,get_uid):
data
=
{
"product"
:
1
,
"module"
:
0
,
"project"
:
1
,
"openedBuild[]"
:
"trunk"
,
"assignedTo"
:
"admin"
,
"type"
:
"codeerror"
,
"title"
:
"接口自動化bug0815_15_附圖片、附件:"
+
str
(random.randint(
0
,
1000
)),
"severity"
:
3
,
"pri"
:
3
,
"steps"
:
"<p>[步驟]<img src={} alt="
" /></p><br/><p>[結果]</p><br/><p>[期望]</p><br/>"
.
format
(uppic_steps),
"oldTaskID"
:
0
,
"status"
:
"active"
,
"uid"
:get_uid,
"caseVersion"
:
0
,
"case"
:
0
,
"result"
:
0
,
"testtask"
:
0
}
f
=
{
(
"files[]"
,(
"中國氣候.jpg"
,
open
(
"D:\\中國氣候.jpg"
,
"rb"
),
"image/jpeg"
)),
(
"labels[]"
,
"中國氣候.jpg"
),
(
"files[]"
,(
"hl.jpeg"
,
open
(
"D:\\hl.jpeg"
,
"rb"
),
"image/jpeg"
)),
(
"labels[]"
,
"hl.jpeg"
)
}
r
=
s.post(host
+
"/bug-create-1-0-moduleID=0.html"
,data
=
data,files
=
f)
print
(
"提交bug,響應內容:{}"
.
format
(r.text))
|
2.4 編輯bug-確認bug-解決bug-關閉bug
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
|
# coding:utf-8
#test_operate.py
import
pytest
from
lxml
import
etree
import
re
import
time
import
allure
import
random
@pytest
.fixture()
def
get_id(s,host):
#查找未關閉狀態的第一條bug的id
r
=
s.get(host
+
"/bug-browse-1-0-unclosed-0-id_desc.html"
)
er
=
etree.HTML(r.text)
id
=
er.xpath(
'//*[@id="bugList"]/tbody/tr[1]/td[1]/a'
)[
0
].text
#查找第一個的id
print
(
"提取第一個id為:{}"
.
format
(
id
))
return
id
def
get_idstatus(s,get_id,host):
#根據id,獲取bug的狀態
r
=
s.get(host
+
"/bug-browse-1-0-all.html"
)
er2
=
etree.HTML(r.text)
idtitle
=
er2.xpath(
'//*[@id="bugList"]/tbody/tr[@data-id={}]/td[6]'
.
format
(get_id))[
0
].get(
"title"
)
print
(get_id,idtitle)
return
idtitle
@allure
.title(
"修改bug"
)
def
test_edit(s,get_id,host):
r
=
s.get(host
+
"/bug-edit-{}.html"
.
format
(get_id))
kuid
=
re.findall(
"var kuid = '(.+?)'"
,r.text)
lasted
=
re.findall(
"id='lastEditedDate' value='(.+?)'"
,r.text)
data
=
{
"product"
:
1
,
"module"
:
0
,
"project"
:
1
,
"openedBuild[]"
:
"trunk"
,
"duplicateBug"
:
0
,
"assignedTo"
:
"admin"
,
"deadline"
:
"0000-00-00"
,
"type"
:
"codeerror"
,
"title"
:
"0818bug:"
+
str
(random.randint(
0
,
1000
)),
"severity"
:
3
,
"pri"
:
3
,
"steps"
:
"<p>[步驟]</p><br/><p>[結果]</p><br/><p>[期望]</p><br/>"
,
"status"
:
"active"
,
"lastEditedDate"
:lasted,
"uid"
: kuid,
"caseVersion"
:
0
,
"comment"
:
"修改bug"
}
s.post(r.url,data
=
data)
assert
get_idstatus(s, get_id, host)
=
=
"激活"
@allure
.title(
"確認bug"
)
def
test_confirm(s,get_id,host):
r
=
s.get(host
+
"/bug-confirmBug-{}.html?onlybody=yes"
.
format
(get_id))
kuid
=
re.findall(
"var kuid = '(.+?)'"
, r.text)[
0
]
data
=
{
"assignedTo"
:
"admin"
,
"type"
:
"codeerror"
,
"pri"
:
3
,
"status"
:
"active"
,
"comment"
:
"ok,稍后修復"
,
"uid"
:kuid
}
r1
=
s.post(r.url, data
=
data)
print
(
"確認后,響應內容:{}"
.
format
(r1.text))
print
(get_id)
assert
get_idstatus(s, get_id, host)
=
=
"激活"
@allure
.title(
"解決bug"
)
def
test_resolve(s,get_id,host):
#解決bug
r
=
s.get(host
+
"/bug-resolve-{}.html?onlybody=yes"
.
format
(get_id))
kuid
=
re.findall(
"var kuid = '(.+?)'"
,r.text)[
0
]
print
(
type
(kuid),kuid,r.url)
datas
=
{
"resolution"
:
"bydesign"
,
"resolvedBuild"
:
"trunk"
,
"resolvedDate"
:time.strftime(
"%Y-%m-%d %H:%M:%S"
,time.localtime()),
"assignedTo"
:
"admin"
,
"status"
:
"resolved"
,
"comment"
:
"不予修復"
,
"uid"
:kuid
}
r1
=
s.post(r.url, data
=
datas)
print
(
"修改為已解決,響應內容:{}"
.
format
(r1.text))
print
(get_id)
assert
get_idstatus(s,get_id,host)
=
=
"已解決"
@allure
.title(
"關閉bug"
)
def
test_close(s,host,get_id):
#關閉bug
url
=
host
+
"/bug-close-{}.html?onlybody=yes"
.
format
(get_id)
r
=
s.get(url)
kuid
=
re.findall(
"kuid = '(.+?)'"
,r.text)
data
=
{
"status"
:
"closed"
,
"comment"
:
"ok"
,
"uid"
:
"kuid"
}
r1
=
s.post(url,data
=
data)
print
(r1.text)
assert
get_idstatus(s,get_id,host)
=
=
'已關閉'
|
2.5 為了展示自己的勞動成果,報告是不可少的
1
2
3
4
5
6
7
8
|
#pytest.ini
[pytest]
#pytest-html生成報告
#addopts=-s --html=report/a.html --self-contained-html
#allure-pytest 生成報告
addopts
=
-
s
-
-
alluredir report
/
b
|
2.6 zentao文件下,打開cmd,執行pytest
pytest執行完畢,繼續輸入allure serve report/b 自動展示html格式報告(注意:report/b可以隨意命名,但必須與pytest.ini中的內容一致)
注意:pytest可以在zentao目錄下執行,也可以在case目錄下執行,但這樣report/b所在的目錄就不同了;根據pytest.ini,執行pytest會在pytest當前所在目錄生成report/b目錄,若是report/b不存在則直接創建,若是存在則使用已有的;
執行pytest時,一定要刪除b目錄,不然可能會產生冗余數據;
三、寫代碼過程中,想要調試某個腳本;如,提交bug;
那么需要執行登錄腳本和提交bug腳本;
在case目錄下,打開cmd,執行pytest -s test_login.py test_newbug.py
若是想要調試登錄,那直接執行pytest -s test_login.py
原文地址https://www.cnblogs.com/canglongdao/p/13526810.html