最近在學習python自動化,嘗試着寫了一個使用pycharm+python+selenium實現的163郵箱登錄,發送郵件的自動化。
工具:pycharm
語言:python
框架:selenium
py file:
1.allDriver,用於封裝登錄和退出的方法
2.smokeCase,用於書寫測試用例
3.runCase,用於執行用例集和定義測試報告
字典文件:Common,用於存儲一些常用的值
在開始實現代碼之前,首先進行環境搭建,環境搭建的步驟大家可以在網上搜索一下,網上有很多教程都可以直接使用。
以下爲實現163郵箱發送郵件的步驟及代碼:
第一步,封裝登錄和退出的方法【在allDriver文件中實現】。之所以單獨封裝一下登錄和退出的方法,主要是考慮到執行多個用例時,可能反覆用到登錄和退出
1.定義一個類,python定義類的語法爲【class ClassName:】,所以我先創建一個類,類名稱爲Mail:
class Mail:
2.定義類之後,在類中初始化driver:
def __init__(self, driver):
self.driver = driver
init() 是一個特殊的方法,包含兩個形參:self 和driver。在這個方法的定義中,形參self 必不可少,還必須位於其他形參的前面。因爲Python調用這個__init__() 方法來創建driver實例時,將自動傳入實參self 。每個與類相關聯的方法調用都自動傳遞實參self ,它是一個指向實例本身 的引用,讓實例能夠訪問類中的屬性和方法。
def是定義方法的關鍵字。
3.初始化driver之後,就可以進行方法封裝。首先進行登錄方法的封裝。
定義一個login的方法,可傳入參數登錄名和密碼:
def login(self, username, password):
方法定義之後,就可以在方法中實現登錄。
因爲打開163郵箱登錄界面之後呢,默認的是二維碼登錄,所以要給他切換到用戶名和密碼登錄界面:
定位“密碼登錄”,使用id定位:
self.driver.find_element_by_id("switchAccountLogin").click()
這一步執行之後就會切換到密碼登錄界面。
首先打開管理者工具,觀察用戶名輸入框和密碼輸入框的屬性。可以發現兩者都在一個frame上,所以我們要定位用戶名和密碼框,需要首先定位並鎖定他們所在的frame。
定位到並切換到frame上:
iframe = self.driver.find_element_by_xpath("//div[@id='loginDiv']/iframe")
self.driver.switch_to.frame(iframe)
鎖定frame之後,便可以開始進行用戶名和密碼輸入框的定位和輸入。
首先定位密碼輸入框並進行輸入用戶名:
self.driver.find_element_by_name("email").clear()
self.driver.find_element_by_name("email").send_keys(username)
密碼框:
self.driver.find_element_by_name("password").clear()
self.driver.find_element_by_name("password").send_keys(password)
輸入完成後,點擊登錄按鈕:
self.driver.find_element_by_id("dologin").click()
以上就是封裝的登錄方法。登錄方法封裝完成以後,開始封裝退出方法。
def logout(self):
self.driver.find_element_by_link_text('退出').click()
至此,登錄和退出的方法已經封裝完成了。在下面的用例執行中,便可以進行引用了。
第二步,實現發送郵件的用例【在smokeCase中實現】。
1.定義全局變量driver,並繼承於Mail類:
global driver
driver = webdriver.Chrome()
mail = Mail(driver)
2.定義全局變量dic,用於字典取值:
"""定義全局變量dic"""
global dic
"""讀取文件"""
with open("./CommonFolder/Common", "r") as f:
data = f.read()
dic = {}
dic = json.loads(data)
3.定義用例的類,繼承於testcase:
class TestEmail(unittest.TestCase):
3.在類裏先把執行用例前後需要執行的寫進去:
@classmethod
def setUpClass(cls):
這個是執行用例之前執行一次的方法。
因爲我們需要添加一個發郵件的用例,所以在執行用例之前,需要進行登錄,我們索性把登錄作爲用例執行前的一個操作:
@classmethod
def setUpClass(cls):
url = dic['testURL']
username = dic['userName1']
password = dic['password1']
print(url + username + password)
driver.get(url)
driver.maximize_window()
mail.login(username, password)
上面的代碼中,username和password是從一個字典裏取出來的,因爲我的用戶名和密碼是存儲在字典內的,所以我需要從字典裏取出來。這也是我上面爲什麼定義一個全局變量dic的原因。大家也可以不用字典存儲,直接使用username="永魂"進行賦值。
在用例執行完成以後,肯定需要退出登錄,關閉瀏覽器,下面是退出的,這個方法是所以用例執行完成以後,執行一次:
"""所有用例執行完之後,執行一次"""
@classmethod
def tearDownClass(cls) -> None:
sleep(5)
mail.logout()
sleep(2)
driver.quit()
上面這個方法是所有用例都全部執行完成後,執行的。
除了上面這兩個方法,還有另外兩個方法是每個執行用例前/後執行一次。大家有興趣可以上網搜索一下。
下面開始實現發送郵件的用例:
定義用例方法,注意每個用例的方法都必須包含test,否則執行可能會出錯
def test_case1(self):
點擊寫信按鈕:
driver.find_element_by_xpath("//div[@id='dvNavContainer']/nav/div/ul/li[2]/span[2]").click()
清空收件人輸入框:
driver.find_element_by_xpath("//div[@title='發給多人時地址請以分號隔開']/div/input").clear()
輸入收件人:
driver.find_element_by_xpath("//div[@title='發給多人時地址請以分號隔開']/div/input").send_keys("[email protected]")
輸入主題:
driver.find_element_by_xpath("//div[@aria-label='郵件主題輸入框,請輸入郵件主題']/input").send_keys("測試發送郵件主題")
在輸入框內輸入內容:
"""定位到寫信的frame"""
iframe = driver.find_element_by_xpath("//div[@class='APP-editor-edtr']/iframe")
driver.switch_to.frame(iframe)
"""輸入郵件內容"""
driver.find_element_by_xpath("//html/body/p").send_keys("你好,我給你發送了一個郵件,請注意查收!")
"""退出寫信的frame"""
driver.switch_to.default_content()
點擊發送按鈕:
driver.find_element_by_xpath("//div[@aria-label='寫信']/header/div/div/div/span[text()='發送']").click()
以上就是發送郵件的用例。
第三步,在用例設計完成之後,要進行用例執行,及生成報告【runCase】。
定義測試集,繼承於testSuit,加載smokeCase中所有的用例:
suit = unittest.TestSuite()
suit.addTests(unittest.TestLoader().loadTestsFromTestCase(TestEmail))
定義html報告:
if __name__ == '__main__':
with open('./CommonFolder/HTMLReport.html', 'wb+') as fp:
runner = HTMLTestRunner(stream=fp, verbosity=2)
runner.run(suit)
fp.close()
因爲生成的html報告需要用到HTMLTestRunner,所以在之前,需要把HTMLTestRunner配置完成。
另外,我的common文件中是按照字典方式存儲的,格式爲,大家可以不使用這個進行存儲,直接進行賦值:
{
"testURL": "http://mail.163.com"
}
以上就已經實現了,163郵箱的登錄功能。
第四步,配置執行:
找到Edit Configurations ,點擊。
點擊“+”,選擇python,新建一個配置,填寫如下內容,填寫完成後保存,然後運行時,選擇此配置。
運行完成後,可點擊生成的report查看執行結果:
附所有代碼。
alldriver:
from selenium import webdriver
from time import sleep
class Mail:
"""定義一個driver"""
def __init__(self, driver):
self.driver = driver
"""登錄方法"""
def login(self, username, password):
"""使用用戶名和密碼登錄"""
self.driver.find_element_by_id("switchAccountLogin").click()
"""爲了避免切換界面後,找不到元素,先等待兩秒"""
sleep(2)
"""先定位到登錄用戶名和密碼框所在的frame"""
iframe = self.driver.find_element_by_xpath("//div[@id='loginDiv']/iframe")
"""定位到frame之後,切換至frame"""
self.driver.switch_to.frame(iframe)
"""定位用戶名輸入框之後,清空輸入框,輸入用戶名"""
self.driver.find_element_by_name("email").clear()
self.driver.find_element_by_name("email").send_keys(username)
"""定位用戶名輸入框之後,清空輸入框,輸入用戶名"""
self.driver.find_element_by_name("password").clear()
self.driver.find_element_by_name("password").send_keys(password)
"""點擊登錄按鈕"""
self.driver.find_element_by_id("dologin").click()
"""退出方法"""
def logout(self):
"""點擊退出按鈕"""
self.driver.find_element_by_link_text('退出').click()
smokeCase:
import unittest
import json
from time import sleep
from selenium import webdriver
from allDriver import Mail
global driver
driver = webdriver.Chrome()
mail = Mail(driver)
"""定義全局變量dic"""
global dic
"""讀取文件"""
with open("./CommonFolder/Common", "r") as f:
data = f.read()
dic = {}
dic = json.loads(data)
class TestEmail(unittest.TestCase):
"""執行用例前執行一次"""
@classmethod
def setUpClass(cls):
url = dic['testURL']
username = dic['userName1']
password = dic['password1']
print(url + username + password)
driver.get(url)
driver.maximize_window()
mail.login(username, password)
def test_case1(self):
sleep(3)
print("寫信按鈕")
"""點擊寫信按鈕"""
driver.find_element_by_xpath("//div[@id='dvNavContainer']/nav/div/ul/li[2]/span[2]").click()
"""定位並清空收件人"""
driver.find_element_by_xpath("//div[@title='發給多人時地址請以分號隔開']/div/input").clear()
"""輸入收件人"""
driver.find_element_by_xpath("//div[@title='發給多人時地址請以分號隔開']/div/input").send_keys("[email protected]")
sleep(2)
"""輸入主題"""
driver.find_element_by_xpath("//div[@aria-label='郵件主題輸入框,請輸入郵件主題']/input").send_keys("測試發送郵件主題")
"""定位到寫信的frame"""
iframe = driver.find_element_by_xpath("//div[@class='APP-editor-edtr']/iframe")
driver.switch_to.frame(iframe)
"""輸入郵件內容"""
driver.find_element_by_xpath("//html/body/p").send_keys("你好,我給你發送了一個郵件,請注意查收!")
"""退出寫信的frame"""
driver.switch_to.default_content()
"""點擊發送按鈕"""
list1 = driver.find_elements_by_xpath("//div[@aria-label='寫信']/header/div/div/div/span[text()='發送']")
print(len(list1))
driver.find_element_by_xpath("//div[@aria-label='寫信']/header/div/div/div/span[text()='發送']").click()
def test_case2(self):
print("test2")
self.assertEqual(1, 1)
"""所有用例執行完之後,執行一次"""
@classmethod
def tearDownClass(cls) -> None:
sleep(5)
mail.logout()
sleep(2)
driver.quit()
if __name__ == '__main__':
unittest.main
runCase:
import unittest
from HTMLTestRunner import HTMLTestRunner
from smokeCase import TestEmail
"""定義一個測試集suit, 包含smokeCase裏的所有測試用例"""
suit = unittest.TestSuite()
suit.addTests(unittest.TestLoader().loadTestsFromTestCase(TestEmail))
"""HTMLTestRunner生成報告"""
if __name__ == '__main__':
with open('./CommonFolder/HTMLReport.html', 'wb+') as fp:
runner = HTMLTestRunner(stream=fp, verbosity=2)
runner.run(suit)
fp.close()
common:
{
"testURL": "http://mail.163.com",
"userName1": "name1",
"password1": "pass1",
}