Web自动化(二)

unittest单元测试框架

setUp()和tearDown()方法可以在测试运行前后做一些操作,每次执行一条用例都会调用setUp和tearDown方法

 

常用断言方法

1、assertEqual(a,b,[msg='']):断言a和b是否相等,相等时用例通过,msg为当测试用例不通过时的返回信息

2、assertNotEqual(a,b,[msg='']):断言a和b是否相等,不相等时用例通过,msg为当测试用例不通过时的返回信息

3、assertTrue(x,[msg='']):断言x是否为True,是True则测试用例通过

4、assertFalse(x,[msg='']):断言x是否为False,是False则测试用例通过

5、assertIs(a,b,[msg='']):断言a是否是b,是则测试用例通过

6、assertNotIs(a,b,[msg='']):断言a是否是b,不是则测试用例通过

7、assertIsNone(x,[msg='']):断言x是否为None,是则测试用例通过

8、assertIsNotNone(x,[msg='']):断言x是否为None,不是则测试用例通过

9、assertIn(a,b,[msg='']):断言a是否在b中,是则测试用例通过

10、assertNotIn(a,b,[msg='']):断言a是否在b中,不是则测试用例通过

11、assertIsInstance(a,b,[msg='']):断言a是否为b的一个实例,是则用例通过

 

import unittest
from selenium import webdriver


class testCase(unittest.TestCase):
    def setUp(self):
        self.dr = webdriver.Chrome()

    def test_QQlogin(self):
        self.dr.get('https://mail.qq.com')
        self.assertEqual(self.dr.title, '登录QQ邮箱', '页面跳转失败')
        print('第一条用例')

    def test_MaoyanMovie(self):
        self.dr.get('http://maoyan.com/')
        self.assertEqual(self.dr.title, '电影院票房购票_评分_选座_经典影视推荐-猫眼电影', '页面跳转失败')
        print('第二条用例')

    def tearDown(self):
        self.dr.quit()


if __name__ == '__main__':
    unittest.main()
View Code

 

引入setUpClass()和tearDownClass()测试固件,可保证执行用例前和执行完所有用例后的操作

import unittest
from selenium import webdriver


class testCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.dr = webdriver.Chrome()

    def test_QQlogin(self):
        self.dr.get('https://mail.qq.com')
        self.assertEqual(self.dr.title, '登录QQ邮箱', '页面跳转失败')
        print('第一条用例')

    def test_MaoyanMovie(self):
        self.dr.get('http://maoyan.com/')
        self.assertEqual(self.dr.title, '电影院票房购票_评分_选座_经典影视推荐-猫眼电影', '页面跳转失败')
        print('第二条用例')

    @classmethod
    def tearDownClass(cls):
        cls.dr.quit()


if __name__ == '__main__':
    unittest.main()
View Code

 

生成HTML测试报告

将HTMLTestRunner.py复制到Python安装目录的Lib下

 

编写allTest.py文件,运行所有测试脚本

目录结构如下:

...\TestCases:存放测试用例\

...\TestCases\__init__:声明TestCases包文件

...\TestCases\testUnit.py:自动化测试用例

...\TestCases\Myunit.py:存放测试固件

...\Reports:存放HTML测试报告

...\allTest.py:运行所有测试用例主程序文件

import os, time, unittest
from HTMLTestRunner import HTMLTestRunner


def getAllCases():
    #获取TestCases下的所有测试模块
    Testsuite = unittest.defaultTestLoader.discover(start_dir=os.path.join(os.path.dirname(__file__),'TestCases'),pattern='test*.py')
    return Testsuite


def RunMain():
    #生成测试报告,写入指定Reports目录
   fp = open(os.path.join(os.path.dirname(__file__),'Reports',time.strftime('%Y-%m-%d-%H-%M-%S')+'report.html'),'wb')
   HTMLTestRunner(stream=fp,title='测试报告',description='使用unittest完成').run(getAllCases())

if __name__ == '__main__':
    RunMain()
    
'''discover()函数用于读取TestCases目录下的以test开头的.py文件,并返回所有测试模块下的测试用例'''
View Code

 

 

数据驱动测试

需在测试类上使用@ddt.ddt装饰器,在测试用例上使用@ddt.data装饰器,@ddt.data可以把参数作为测试数据,可以是单个值,或字典、列表、元组。对于列表和元组,需要使用@ddt.unpack装饰器把列表或者元组解析成多个参数

单个参数示例

import ddt
import unittest

Data = [
    {'name': 'keep learning'},
    {'age': 18},
    {'address': '上海地区'}
]


@ddt.ddt
class TestModules(unittest.TestCase):
    @classmethod
    def setUp(self):
        print('begin')

    @classmethod
    def tearDown(self):
        print('over')

    @ddt.data(*Data)
    def test_DataDriver(self,Data):
        print('DDT数据驱动',Data)

if __name__ == '__main__':
    unittest.main()
View Code

列表或者元组示例

import ddt
import unittest

Data = [
    ['admin', 'admin', '登录失败'],
    ['admin','admin123','登录成功'],
    ['','','登录失败']
]


@ddt.ddt
class TestModules(unittest.TestCase):
    def setUp(self):
        print('testcase begining')

    def tearDown(self):
        print('testCase over')

    @ddt.data(*Data)
    @ddt.unpack
    def test_DataDriver(self,user,pwd,msg):
        print('DDT数据驱动', user)
        print('DDT数据驱动', pwd)
        print('DDT数据驱动', msg)

if __name__ == '__main__':
    if __name__ == '__main__':
        unittest.main()
View Code

 

Excel读取测试数据并执行用例示例

import unittest, xlrd, ddt
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def readUserName(row):
    book = xlrd.open_workbook('测试数据.xlsx', 'r')
    table = book.sheet_by_index(0)
    return table.row_values(row)[0]


def readPasswd(row):
    book = xlrd.open_workbook('测试数据.xlsx', 'r')
    table = book.sheet_by_index(0)
    return table.row_values(row)[1]


def readMsg(row):
    book = xlrd.open_workbook('测试数据.xlsx', 'r')
    table = book.sheet_by_index(0)
    return table.row_values(row)[2]


class TestSouHuLogin(unittest.TestCase):
    def setUp(self):
        self.dr = webdriver.Chrome()
        self.dr.maximize_window()
        self.test_url = 'http://mail.sohu.com/fe/#/login'

    def tearDown(self):
        self.dr.quit()

    def by_css(self, usernameloc):
        # 重写css定位
        return self.dr.find_element_by_css_selector(usernameloc)

    def getassertText(self):
        try:
            sleep(2)
            loctor = (By.CSS_SELECTOR, '.topHolder.ng-binding')
            WebDriverWait(self.dr, 5, 0.5).until(EC.presence_of_element_located(loctor))
            return self.by_css('.topHolder.ng-binding').text
        except Exception as e:
            print('元素定位失败,报错原因{}'.format(e))

    def souhuLogin(self, user, passwd):
        #封装登录操作
        self.by_css('.addFocus.ipt-account.ng-pristine.ng-valid').send_keys(user)
        self.by_css('.addFocus.ng-pristine.ng-valid').send_keys(passwd)
        self.by_css('.btn-login.fontFamily').click()

    def test_souHuLogin_001(self):
        self.dr.get(self.test_url)
        sleep(3)
        self.souhuLogin(readUserName(0),readPasswd(0))
        self.assertEqual(self.getassertText(),readMsg(0),msg='错误')
    def test_souHuLogin_002(self):
        self.dr.get(self.test_url)
        sleep(3)
        self.souhuLogin(readUserName(1),readPasswd(1))
        self.assertEqual(self.getassertText(),readMsg(1),msg='错误')
    def test_souHuLogin_003(self):
        self.dr.get(self.test_url)
        sleep(3)
        self.souhuLogin(readUserName(2),readPasswd(2))
        self.assertEqual(self.getassertText(),readMsg(2),msg='错误')

if __name__ == '__main__':
    unittest.main()
View Code

 

Excel整合成一个列表

import xlrd
def readData():
    book = xlrd.open_workbook('测试数据.xlsx','r')
    table = book.sheet_by_index(0)
    newRows = []
    for rowValue in range(1,table.nrows): #行数进行迭代
        newRows.append(table.row_values(rowValue,0,table.ncols))
    return newRows
View Code

 

使用yaml读取并执行用例

import yaml
import unittest, ddt
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def readyaml():
    f = open('data.yaml', 'r', encoding='utf-8')
    data = yaml.load(f.read())
    f.close()
    return data


class TestSouHuLogin(unittest.TestCase):
    def setUp(self):
        self.dr = webdriver.Chrome()
        self.dr.maximize_window()
        self.test_url = 'http://mail.sohu.com/fe/#/login'

    def tearDown(self):
        self.dr.quit()

    def by_css(self, usernameloc):
        # 重写css定位
        return self.dr.find_element_by_css_selector(usernameloc)

    def getassertText(self):
        try:
            sleep(2)
            loctor = (By.CSS_SELECTOR, '.tipHolder.ng-binding')
            WebDriverWait(self.dr, 5, 0.5).until(EC.presence_of_element_located((loctor)))
            return self.by_css('.tipHolder.ng-binding').text

        except Exception as e:
            print('元素定位失败,报错原因{}'.format(e))

    def souhuLogin(self, user, passwd):
        # 封装登录操作
        self.by_css('.addFocus.ipt-account.ng-pristine.ng-valid').send_keys(user)
        self.by_css('.addFocus.ng-pristine.ng-valid').send_keys(passwd)
        self.by_css('.btn-login.fontFamily').click()

    def test_souHuLogin_001(self):
        self.dr.get(self.test_url)
        sleep(3)
        self.souhuLogin(readyaml()['userNull']['username'], readyaml()['userNull']['password'])
        self.assertEqual(self.getassertText(), readyaml()['userNull']['assertText'], msg='错误')
    # def test_souHuLogin_002(self):
    #     self.dr.get(self.test_url)
    #     sleep(3)
    #     self.souhuLogin(readUserName(1),readPasswd(1))
    #     self.assertEqual(self.getassertText(),readMsg(1),msg='错误')
    # def test_souHuLogin_003(self):
    #     self.dr.get(self.test_url)
    #     sleep(3)
    #     self.souhuLogin(readUserName(2),readPasswd(2))
    #     self.assertEqual(self.getassertText(),readMsg(2),msg='错误')


if __name__ == '__main__':
    unittest.main()
View Code

 

parameterized参数化

import unittest
from selenium import webdriver
from time import sleep
from parameterized import parameterized

class LoginTest(unittest.TestCase):
    def setUp(self):
        self.dr = webdriver.Chrome()
        self.dr.maximize_window()
        self.test_url = 'http://mail.sohu.com/fe/#/login'

    def tearDown(self):
        self.dr.quit()

    def by_css(self, usernameloc):
        # 重写css定位
        return self.dr.find_element_by_css_selector(usernameloc)

    def getassertText(self):
        try:
            return self.by_css('.tipHolder.ng-binding').text

        except Exception as e:
            print('元素定位失败,报错原因{}'.format(e))

    def souhuLogin(self, user, passwd):
        # 封装登录操作
        self.by_css('.addFocus.ipt-account.ng-pristine.ng-valid').send_keys(user)
        self.by_css('.addFocus.ng-pristine.ng-valid').send_keys(passwd)
        self.by_css('.btn-login.fontFamily').click()

    @parameterized.expand([
        ('', '', '请输入账号密码'),
        ('admin111@sohu.com'),
        ('', 'a123456789', '请输入账号密码')])

    def test_login(self,username,password,assert_text):
        self.dr.get(self.test_url)
        sleep(3)
        self.souhuLogin(username,password)
        self.assertEqual(self.getassertText(),assert_text)

if __name__ == '__main__':
    unittest.main(verbosity=2)
View Code

 

发送邮件

第一个示例,无附件

import smtplib #调用SMTP发件服务
from email.mime.text import MIMEText #导入做纯文本的邮件模板类
smtpsever = 'smtp.qq.com'
sender = '840633025@qq.com'
psw = 'fgwgbeghglxybbei'
receiver = '313891664@qq.com'
port = 465
body = '这是第一封测试邮件'  #邮件内容
msg = MIMEText(body,'html','utf-8')
msg['from'] = '840633025@qq.com'
msg['to'] = '313891664@qq.com'
msg['subject'] = '这是纯文本发送的邮件示例'  #邮件名称
smtp = smtplib.SMTP_SSL(smtpsever,port)  #调用发件服务
smtp.login(sender,psw)  #通过发送者邮箱账号和授权码登录邮箱
smtp.sendmail(sender,receiver,msg.as_string())  #发送邮件,信息以字符串方式保存
smtp.quit()
View Code

 

带附件的邮件发送

import smtplib  #调用SMTP发件服务
from email.mime.text import MIMEText  #导入做纯文本的邮件模板类
from email.mime.multipart import MIMEMultipart
smtpsever = 'smtp.qq.com'
sender = '840633025@qq.com'
psw = 'fgwgbeghglxybbei'
receiver = '313891664@qq.com'
port = 465
filepath = r"./sql.txt"
with open(filepath,'rb') as fp:
    mail_body = fp.read()
msg = MIMEMultipart()
msg['from'] = '840633025@qq.com'
msg['to'] = '313891664@qq.com'
msg['subject'] = '这是带附件的邮件'
body = MIMEText(mail_body,'html','utf-8')
msg.attach(body)
att = MIMEText(mail_body,'base64','utf-8')
att['Content-Type'] = 'application/octet-stream'
att['Content-Disposition'] = 'attachment;filename="test_report.html"'
msg.attach(att)
try:
    smtp = smtplib.SMTP_SSL()
    smtp.connect(smtpsever)
    smtp.login(sender,psw)
except:
    smtp = smtplib.SMTP_SSL(smtpsever,port)
    smtp.login(sender, psw)
smtp.sendmail(sender,receiver,msg.as_string())
smtp.quit()
View Code

 

自动化测试封装

 

posted @ 2020-03-07 19:19  hjj123  阅读(67)  评论(0)    收藏  举报