Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
關注此頭條號“互聯網IT信息”——>私信發送 “京東html” ,即可得到源代碼的獲取方式。
家好,今天分享的是仿京東登錄頁面的簡單實現方法(結構與樣式),首先我們依舊是先看下效果圖
下面是HTML結構
下面是CSS樣式
PS:本人也是小白一枚,自學沒幾天,疏漏之處在所難免,請多擔待!
lask這個框架很輕量,做一些小工具還是可以很快上手的。
1、自動化
某一天你入職了一家高大上的科技公司,開心的做著軟件測試的工作,每天點點點,下班就走,晚上陪女朋友玩王者,生活很愜意。
但是美好時光一般不長,這種生活很快被女主管打破。為了提升公司測試效率,公司決定引入自動化流程,你在網上搜了一套技術方案 python + selenium,迅速寫了一套自動化測試的腳本。
from selenium import webdriver
def test_selenium():
driver=webdriver.Firefox()
driver.get("http://www.baidu.com")
...
driver.quit()
...
編寫腳本的日子很累,你需要每天加班,而且沒有加班工資。 雖然如此,你也沒有太多怨言,因為你能明顯感覺到自己一點點掌握了自動化測試的流程,正在踏入職業發展的新階段。這套腳本很快用于公司的主流程測試,也會在回歸測試中使用。
因為大量的重復勞動都可以用這套自動化測試腳本代替,于是你又有時間陪女朋友了,上班也可以偶爾劃水了,也可以時不時瞄一瞄自己的基金有沒有漲。
當然,美好時光一般不長。在一次大改版中,前端頁面發生了大量變化,你的自動化測試代碼因為沒有做抽象封裝,基本已經不能用了。
又可以加班了,生活又可以充實起來了。你動用了一些像 PageObject 的模式對代碼進行了重新設計,也加入了關鍵字驅動,盡量讓測試邏輯變成可配置的。 設計完成以后,當前端頁面變化時,只需要重點維護關鍵字表格。
你又為公司做了一些貢獻,你已經完全勝任自動化測試的工作,甚至能夠帶一兩個小弟。他們時不時找你問一些問題,但是對于自動化的維護工作還是要靠你自己,當你請假時,這些工作只能停滯。于是公司希望你做一些改進,讓功能測試人員也可以運行這些自動化測試。
2、開始測試平臺
你看到網上有很多人提到測試平臺,想著自己也可以做一個可視化平臺,這樣功能測試人員也可以通過在界面上進行簡單的設置,就可以使用底層的自動化代碼了。很快 flask 出現在你的視線中,你做的第一個功能就是實現類似于 jenkins 的構建功能。
首先,你搭建了一個 flask 服務,服務啟動后,你能順利訪問 5000 端口。
from flask import Flask
app=Flask(__name__)
app.run(port=5000)
然后,你配置了一個 url 地址,當訪問這個 url 地址時,服務會調用一個函數,這個 url 和函數的綁定關系就是路由。函數的返回值可以是普通字符串,可以是 json 數據,也可以是 html 頁面。
@app.route('/')
def index():
"show all projects in workspace dir"
workspace=pathlib.Path(app.root_path) / 'workspace'
projects=[project.name for project in workspace.iterdir()]
return render_template('index.html', projects=projects)
上面的代碼就是模仿 jenkins, 把自動化測試的腳本放在項目的 workspace 目錄下,當訪問 / 根路徑時,index 函數就會被調用。index 函數的作用就是列舉 workspace 目錄下的所有項目名,通過 return 展示在前端界面。具體的前端代碼如下:
<h2>展示所有的項目</h2>
{% for p in projects %}
<div>
{{ p }}
<a href="/build?project={{p}}">構建</a>
</div>
{% endfor %}
在頁面上點擊構建,程序會跳轉到 flask 設置好的 /build 這個 url 中,這個路由負責運行自動化測試的代碼,他會接收用戶傳過來的 project 參數,找到在 workspace 目錄下的項目,再執行自動化測試指令(這里統一用 pytest 指令)。
@app.route("/build", methods=['get', 'post'])
def build():
project_name=request.args.get('project')
pytest.main([f'workspace/{project_name}'])
return "build success"
到目前為止,完整的流程是這樣的:首先,在平臺首頁會展示所有可以構建的項目,這些項目其實就是把 workspace 子目錄當中的目錄名列舉出來;然后,點擊項目旁邊的構建按鈕,跳轉到 /build,根據項目名稱執行自動化指令,等待自動化任務執行完成,返回 build success。
3、優化
你基本上已經實現了功能,現在功能測試人員可以通過你搭建的簡易平臺執行自動化命令。但是這個平臺還存在一些問題:第一、沒有收集到構建信息,無法查看測試之后的結果;第二、用戶必須等待自行測試腳本執行完成,才能返回前端具體的結果,如果自動化測試的執行時間很長,用戶會一直停在這個頁面,無法做其他事情。
你想到了并發編程,創建一個子進程單獨去運行自動化測試腳本,因為子進程可以和主進程獨立,所以不需要等待子進程執行完成,主進程就可以立即給前端返回結果。于是你重新編寫了 build 函數:
@app.route("/build")
def build():
id=uuid.uuid4().hex
project_name=request.args.get('project')
with open(id, mode='w', encoding='utf-8') as f:
subprocess.Popen(
['pytest', f'workspace/{project_name}'],
stdout=f
)
return redirect(f'/build-history/{id}')
1、首先,通過 uuid 生成一個 id 號來表示這一次構建任務,之后可以通過這個 id 號查看此次構建的記錄;
2、通過 subprocess 創建子進程運行自動化任務,把輸出結果保存到文件當中,文件名就是生成的 id 號,之后想查看構建的結果時,只需要讀取這個文件當中的內容;
3、只要子進程創建成功,馬上通過 redirect 重定向到查看結果的 url, 此時并不需要等到子進程執行完就可以查看構建結果。
查看構建結果只需要通過 id 讀取文件中的內容返回。
@app.route("/build-history/<id>")
def build_history(id):
with open(id, encoding='utf-8') as f:
data=f.read()
return data
4、生成器
上面讀取文件的代碼有點問題。當構建重定向到 /build-histrory 后,此時自動化測試腳本才剛剛執行,讀取文件中的內容是空的。只有當測試腳本運行,產生越來越多的運行記錄,文件中才會出現更多的內容,你必須手動刷新頁面才能獲取這些新內容。 當自動化任務執行時間很長的時候,你需要不停的刷新 /build-history 頁面才能獲取最新的構建信息。直到子進程結束,不再有新的內容被寫入文件。
為了動態獲取文件數據,你使用了生成器惰性獲取數據,在 /build-history 的頁面加載過程中,只要運行自動化任務的子進程還在運行,就不停的讀取文件內容,將它們動態的返回給前端頁面。
為了判斷子進程的狀態,在 /build 的時候,把子進程的 pid 傳給 /build-history。
@app.route("/build", methods=['get', 'post'])
def build():
id=uuid.uuid4().hex
project_name=request.args.get('project')
with open(id, mode='w', encoding='utf-8') as f:
proc=subprocess.Popen(
['pytest', f'workspace/{project_name}'],
stdout=f
)
return redirect(f'/build-history/{id}?pid={proc.pid}')
在查看結果時,先編寫一個生成器 stream, 每次讀取文件中 100 長度的數據,直到進程運行結束。除了通過構建后的重定向,你也可以手動輸入 id,查看歷史構建記錄。此時只需傳 id, 不需要傳進程名,直接讀取文件中的數據。就算文件特別大,也可以通過批量加載,不至于因為同時讀取大量數據給服務器造成壓力。
import psutil
@app.route("/build-history/<id>")
def build_history(id):
pid=request.args.get('pid', None)
def stream():
f=open(id, encoding='utf-8')
if not pid:
while True:
data=f.read(100)
if not data:
break
yield data
else:
try:
proc=psutil.Process(pid=int(pid))
except:
return 'no such pid'
else:
while proc.is_running():
data=f.read(100)
yield data
return Response(stream())
最后效果:
5、總結
一般來說,做自動化測試只需要做到第一步,有腳本可以執行,就可以代替重復勞動。做測試平臺只是讓腳本變得更加好用。
但是有很多的測試平臺讓自動化運行起來更加復雜,要配置很多很多參數才能跑一個完整的測試用例,這似乎有點折本求末,也是很多人都在做的事情。
本文通過 flask 程序實現了一個最簡單的 toy jenkins,輔助理解像 jenkins 這樣的工具如何執行任務。其實像簡單的構建任務,做起來也有很多問題需要解決,這些只有在遇到具體業務的時候我們才會去思考。
希望我們做的工具都是實用的,好用的。
文章來自https://www.cnblogs.com/heniu/p/16565781.html
*請認真填寫需求信息,我們會在24小時內與您取得聯系。