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 ,点击。
selenium+python+unitest实现163邮箱发送邮件_第1张图片
点击“+”,选择python,新建一个配置,填写如下内容,填写完成后保存,然后运行时,选择此配置。
selenium+python+unitest实现163邮箱发送邮件_第2张图片
运行完成后,可点击生成的report查看执行结果:
selenium+python+unitest实现163邮箱发送邮件_第3张图片

附所有代码。
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",
}

你可能感兴趣的:(自动化,python,selenium)