Web自动化测试05

本篇博客

unittest模块

1 unittest基本概念
2 unittest基本用法
3 unittest断言
4 unittest命令行接口
5 unittest与selenium

unittest模块

1 unittest基本概念

1) 什么是是unittest框架?

Unittest单元测试框架是专门用来进行测试的框架

2) 主要概念:

test fixture: 代表了用例执行前的准备工作和用例执行之后的清理工作。

test fixture

test case: 测试用例,这个相信大家都不陌生。是测试的最小单位,一般检查一组输入的响应(输出)是否符合预期。unittest模块提供了TestCase类来帮助我们创建测试用例;

test case

test suite: 经常被翻译成”测试套件”,也有人称为”测试套”,是测试用例或测试套件的集合,一般用来把需要一起执行的用例组合到一起;

test suite

test runner: 用来执行测试用例并输出测试结果的组件。可以是图形界面或命令行界面;

test runner

2 unittest基本用法 

unittest基本用法:

1.通过继承unittest.TestCase进行编写,继承unittest.TestCase的类会被框架识别为测试用例。

2.setUp和TearDown是用于事前和事后做相关处理动作的,就是前面说的Test Fixture,会在每个测试用例运行前后被框架自动调用

3.所有以test开头的方法会被框架自动识别为测试用例,并自动调用执行,不是以test开头的不会被调用

4.unittest.main()是最简单的测试执行方式

5.调用unittest.main()方法后,继承自unittest.TestCase类的类会被自动识别为测试用例并且被调用。

6.test suite: 经常被翻译成”测试套件”,(另一种测试调用方法)也有人称为”测试套”,是测试用例或测试套件的集合,一般用来把需要一起执行的用例组合到一起;

案例1:简单测试

1.unittest.main()运行时,框架自动寻找TestCase子类,并且运行
2.在TestCase类中,只把以test开头的方法当做测试用例,然后执行,是有顺序的,字母或者数字。

# 导入unittest模块
import unittest

# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):

    def test_001(self):
        print('001')

    def test_003(self):
        print('003')

    def test_002(self):
        print('002')


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

案例2:Test1,Test2都会被调用。因为都继承了TestCase

# 导入unittest模块
import unittest

# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):


    def test_001(self):
        print('001')

    def test_002(self):
        print('002')

    def test_003(self):
        print('003')

class Test2(unittest.TestCase):

    def test_001(self):
        print('201')

    def test_002(self):
        print('202')

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

案例3:

1 setUp()用于初始化一些参数,在测试用例执行前自动被调用

2 tearDown()用于清理,在测试用例执行后被调用

# 导入unittest模块
import unittest

# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):
    def setUp(self):
        print('hello')

    def tearDown(self):
        print('bye')

    def test_001(self):
        print('001')

    def test_002(self):
        print('002')

    def test_003(self):
        print('003')



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



# 1.unittest.main()运行时,框架自动寻找TestCase子类,并且运行
# 2.在TestCase类中,只把以test开头的方法当做测试用例,然后执行
# 3.setUp()用于初始化一些参数,在测试用例执行前自动被调用,tearDown()用于清理,在测试用例执行后被调用
# 4.setUp,tearDown。每个用例开始和结束调用相应的代码。

test suite: 经常被翻译成”测试套件”,也有人称为”测试套”,是测试用例或测试套件的集合,一般用来把需要一起执行的用例组合到一起;

下面是测试套件的用法:

1.创建测试套件

suit = unittest.TestSuite()

2. 定义一个测试用例列表,逐个添加

case_list= ['test_001','test_002','test_003']
    for case in case_list:
        suit.addTest(Test1(case))

3.运行测试用例,verbosity=2(固定)为每一个测试用例输出报告,run的参数是测试套件

unittest.TextTestRunner(verbosity=2).run(suit)

案例4:测试套件

# 导入unittest模块
import unittest

# 继承TestCase类,TestCase类是测试用例类
class Test1(unittest.TestCase):
    def setUp(self):
        print('hello')

    def tearDown(self):
        print('bye')

    def test_001(self):
        print('001')

    def test_002(self):
        print('002')

    def test_003(self):
        print('003')



if __name__ == '__main__':
    # 第一种调用:
    # unittest.main()

    # 第二种调用
    # 创建测试套件
    suit = unittest.TestSuite()
    # 定义一个测试用例列表
    case_list= ['test_001','test_002','test_003']
    for case in case_list:
        suit.addTest(Test1(case))

    # 运行测试用例,verbosity=2为每一个测试用例输出报告,run的参数是测试套件
    unittest.TextTestRunner(verbosity=2).run(suit)

3 unittest断言

unittest断言:

断言是测试用例的核心。我们使用assertEqual()来判断预期结果,用assertTrue()和assertFalse来做是非判断。

案例:断言测试

import unittest

class Test(unittest.TestCase):
    def setUp(self):
        print('start')

    def tearDown(self):
        print('bye')

    def test_001(self):
        self.assertEqual('1','1')

    def test_002(self):
        self.assertEqual('1','0')

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

跑了2个测试用例,一个通过,一个失败。期待为1,结果为0。

显示代码错误的地方:

 

4 unittest命令行接口

unittest命令行接口:

unittest支持命令行接口,我们可以在命令行里指定运行具体的测试用例。

python -m unittest test.Tese1

5 unittest与selenium

unittest与selenium

前面我们简单学习了unittest的用法,接下来我们将unittest与selenium融合在一起进行web自动化测试

目录结构:

1. Commonlib目录存放通用模块(我们封装的selenium模块)

2. 创建Business目录 ,根据业务创建测试功能模块

3. 创建Testcase目录存放测试用例

1. Commonlib-Commonlib.py(后面会用到)

from selenium import webdriver
import time

class Commonshare(object):
    # 初始化方法
    def __init__(self):
        # 创建浏览器对象
        self.driver = webdriver.Firefox()
        # 设置隐式等待
        self.driver.implicitly_wait(5)
        # 设置浏览器的最大化
        self.driver.maximize_window()

    def open_url(self,url):
        # 请求指定站点
        self.driver.get(url)
        time.sleep(3)

    def locateElement(self, locate_type, value):
        # 判断定位方式并调用相关方法
        el = None
        if locate_type == 'id':
            el = self.driver.find_element_by_id(value)
        elif locate_type == 'name':
            el = self.driver.find_element_by_name(value)
        elif locate_type == 'class':
            el = self.driver.find_element_by_class_name(value)
        elif locate_type == 'text':
            el = self.driver.find_element_by_link_text(value)
        elif locate_type == 'xpath':
            el = self.driver.find_element_by_xpath(value)
        elif locate_type == 'css':
            el = self.driver.find_element_by_css_selector(value)
        # 如果el不为None,则返回
        if el is not None:
            return el

    # 指定对某一元素的点击操作
    def click(self, locate_type, value):
        # 调用定位方法进行元素定位
        el = self.locateElement(locate_type,value)
        # 执行点击操作
        el.click()
        time.sleep(1)

    # 对指定的元素进行数据输入
    def input_data(self,locate_type,value,data):
        # 调用定位方法进行元素定位
        el = self.locateElement(locate_type,value)
        # 执行输入操作
        el.send_keys(data)

    # 获取指定元素的文本内容
    def get_text(self, locate_type, value):
        # 调用定位方法进行元素定位
        el = self.locateElement(locate_type, value)
        return el.text

    # 获取指定元素的属性值
    def get_attr(self, locate_type, value, data):
        # 调用定位方法进行元素定位
        el = self.locateElement(locate_type, value)
        return el.get_attribute(data)



    # 收尾清理方法
    def __del__(self):
        time.sleep(3)
        self.driver.quit()

if __name__ == '__main__':
    pass

2. Business-Login.py(后面会用到)

 下面加了time.sleep()。因为后面案例2,3个测试用例,有2个都报错说没有定位到元素。因为网络太慢了,所以就加了延迟时间就可以了。

# 导入selenium封装类
import sys
sys.path.append("..")
from Commonlib.Commonlib import Commonshare
import time


class Login(Commonshare):
    def login(self,user,pwd):
        self.open_url('http://www.yhd.com/')
        self.click('class','hd_login_link')
        time.sleep(2)
        self.input_data('id','un',user)
        time.sleep(2)
        self.input_data('id','pwd',pwd)
        time.sleep(2)
        self.click('id','login_button')

if __name__ == '__main__':
    log = Login()
    log.login('hack_ai_buster','1qaz2wsx#EDC')

案例1:登陆1号店,简单调用。

Testcase-testcase.py

import sys
sys.path.append("..")
from Business.Login import Login
import unittest


class Test(unittest.TestCase):
    def setUp(self):
        print('hello')

    def tearDown(self):
        print('bye')

    # 定义正确登陆的测试用例
    # def test_001(self):
    #     log = Login()
    #     # 用账号密码登录
    #     log.login('18001225175','zyc123')
    #     # 获取登录之后的用户名
    #     data = log.get_text('class','hd_login_name')
    #     # 断言,判断登录后的用户名是否和预期用户名相同
    #     self.assertEqual('1800*****75@phone',data)

    # 账号密码都不输入,直接登录
    def test_002(self):
        log = Login()
        # 用账号密码登录
        log.login('', '')
        # 获取登录之后的用户名
        data = log.get_text('id','error_tips')
        # 断言,判断登录后的用户名是否和预期用户名相同
        self.assertEqual('请输入账号和密码',data)

    # 只输入账号不输入密码,直接登录
    def test_003(self):
        log = Login()
        # 用账号密码登录
        log.login('sdfsdadfa', '')
        # 获取登录之后的用户名
        data = log.get_text('id', 'error_tips')
        # 断言,判断登录后的用户名是否和预期用户名相同
        self.assertEqual('请输入密码', data)

    # 只输入账号不输入密码,直接登录
    def test_004(self):
        log = Login()
        # 用账号密码登录
        log.login('sdfsdadfa', '')
        # 获取登录之后的用户名
        data = log.get_text('id', 'error_tips')
        # 断言,判断登录后的用户名是否和预期用户名相同
        self.assertEqual('请输入密码itcast', data)

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

 注意:为了让后面的案例能够轻松的完成测试。test_001(正确的账号和密码)我注销了,后面的案例都不用这个,因为正确的账号密码输入,会有动态的拖图验证。有的时候弄不好,结果就不对。而且,不在空白处点,会只运行案例一,然后会报一个找不到句柄的错。为了引起不要的麻烦,运行后面三个案例就行。

如果想要运行test_001的代码,(正确的账号和密码)可以加time时间延长:

  # 定义正确登陆的测试用例
    def test_001(self):
        log = Login()
        # 用账号密码登录
        time.sleep(2)
        log.login('18001225175','zyc123')

        # 获取登录之后的用户名
        time.sleep(10)
        data = log.get_text('class','hd_login_name')

        # 断言,判断登录后的用户名是否和预期用户名相同
        time.sleep(2)
        self.assertEqual('1800*****75@phone',data)

结果是:一个测试用例失败,三个测试用例通过。这是对的。

案例2:登陆1号店,测试套件调用。

Testcase-testsuit.py

import unittest
import sys
sys.path.append("..")
from Testcase.testcase import Test
# 导入HtmlTextRunner,用于生成html的测试报告
from Commonlib.HTMLTestRunner import HTMLTestRunner

class SuitTest(unittest.TestCase):
    def test_suit(self):
        case_list = ['test_002','test_003','test_004']
        # 创建测试套件
        mysuit = unittest.TestSuite()

        # 循环将测试用例放到测试套件中
        for case in case_list:
            mysuit.addTest(Test(case))

        # 创建测试运行器,设置为每一个测试用例生成测试报告,运行测试套件中的测试用例
        unittest.TextTestRunner(verbosity=2).run(mysuit)



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

下面为什么总的是4个?因为Testcase-testsuit.py本身也算一个测试用例,所以是4个。

下面为什么只有3个测试用例结果?因为unittest.TextTestRunner(verbosity=2).run(mysuit)运行的是mysuit,所以具体的就mysiut定义的3个。

 

案例3:登陆1号店。

Testcase-testsuit2.py

import unittest
import sys
sys.path.append("..")
from Testcase.testcase import Test
# 导入HtmlTextRunner,用于生成html的测试报告
from Commonlib.HTMLTestRunner import HTMLTestRunner

class SuitTest(unittest.TestCase):
    def test_suit(self):
        case_list = ['test_002','test_003','test_004']
        # 创建测试套件
        mysuit = unittest.TestSuite()

        # 循环将测试用例放到测试套件中
        for case in case_list:
            mysuit.addTest(Test(case))

        # 创建测试运行器,设置为每一个测试用例生成测试报告,运行测试套件中的测试用例
        # unittest.TextTestRunner(verbosity=2).run(mysuit)

        # 生成html测试报告
        with open('report.html','wb')as f:
            HTMLTestRunner(
                stream=f,           # 相当于f.write(报告)
                title='第一个测试报告',
                description='it黑马第一个测试报告',
                verbosity=2         # 为每个测试用例生成测试报告
            ).run(mysuit)


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

 

生成report.html测试报告。可以在目录双击打开,也可以在pycharm中点击右上的浏览器图标。

可以看到下面有3个测试用例,一个失败,两个通过。

可以看到失败的一个测试用例具体错误的地方:

期待:请输入密码itcast      结果:请输入密码    ( 因为是不符的,所以失败。)

 

附:Commonlib-HTMLTestRunner.py(有点长哦)

https://www.cnblogs.com/zhangyangcheng/diary/2020/03/19/12523394.html

 

原文地址:https://www.cnblogs.com/zhangyangcheng/p/12520218.html