selenium+python+unitest實現163郵箱發送郵件

最近在學習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",
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章