理解中的自动化测试框架由三部分组成:
测试用例集 –> 执行测试用例集 –> 可视化报告
这里写图片描述

之前受限于工作,一直很少了解UI自动化。最近学习了一种python + unnittest + HTMLTestRunner的自动化框架。
一些的工作还是以demo开始。
创建测试用例集:pytestDemo1.py

#!/usr/bin/env python
#-*- coding = utf-8 -*-

import unittest

class MydemoA(unittest.TestCase):
    def setUp(self):
        print("MydemoA setUp ... ")
        self.a = 1
    def test_demo_a1(self):
        self.a += 1
        self.assertEqual(self.a, 2, "a != 2")
        print("I am test_demo_a1 the value of a is {}".format(self.a))
    def test_demo_a2(self):
        self.a += 1
        self.assertEqual(self.a, 3, "a != 3")
        print("I am test_demo_a2 the value of a is {}".format(self.a))
    def test_demo_a3(self):
        self.a += 1
        self.assertEqual(self.a, 4, "a != 4")
        print("I am test_demo_a3 the value of a is {}".format(self.a))
    def tearDown(self):
        print("MydemoA tearDown ...")

if __name__ == "__main__":
    print("开始...")
    unittest.main()

解析测试用例集,再执行测试用例集,最后生成HTML可以化报告
callPytest.py

#!/usr/bin/env python
#-*- coding = utf-8 -*-

import os, time
import unittest
import HTMLTestRunner

def creatSuit():
    '''创建测试用例集,加载测试用例:TestCase'''
    test_units = unittest.TestSuite()
    discover = unittest.defaultTestLoader.discover(os.getcwd(), pattern = "pytest*.py")
    for test_suit in discover:
        for test_case in test_suit:
            test_units.addTests(test_case)
    return test_units

if __name__ == "__main__":
    # 获取当前时间,用于命名的html文件名字
    now = time.strftime("%Y-%m-%d_%H_%M_%S",time.localtime())
    file_name = ''.join([os.getcwd() + '\\' + now + "_result.html"])
    with open(file_name, "wb") as fp:
        runner = HTMLTestRunner.HTMLTestRunner(
                stream = fp,
                title = u"测试报告",
                description = u"用例执行情况:")

        # 运行测试用例集TestSuite(creatSuit返回值)
        runner.run(creatSuit())

生成html报告如下图:
这里写图片描述

吐槽哈:(1)报告太丑了(2)扩展性太差
一年前自己借鉴了HTMLTestRunner的报告,改了一个自动化接口的报告
https://blog.csdn.net/zhanghs11/article/details/79572764

调试发现setUp、tearDown和自己的理解有偏差,类里面的每个testcase都要执行。这样可以把一些共性或者需要初始化的数据,抽出来一起封装在setUp里面。

UI自动化框架

目录结构
这里写图片描述
dirver:驱动文件,chromedriver.exe
publicMethod:公共变量,断言方法、UI页面共用模块
result:报告
testcase: 测试用例集
callPytest:启动main文件

asserMethod.py

#-*- coding = utf-8 -*-
#from selenium import webdriver

def insertClassExist(my_browser, class_xpath):
    try:
        result = my_browser.find_elements_by_xpath(class_xpath)
    except:
        return False
    return True if result else False

publicParams.py

#-*- coding = utf-8 -*-

HOST = {
    'Test1' : 'https://test1.xxxxx.com',
    'Test2' : 'https://test2.xxxxx.com',
    'Test3' : 'https://test3.xxxxx.com',
    'Test4' : 'https://test4.xxxxx.com',
    'Test5' : 'https://test5.xxxxx.com',
    'Test6' : 'https://test6.xxxxx.com'
}

env = 'Test1'

# 不存在
nonexistent_user = '153xxxxxxxx'
nonexistent_password = '111111'

# 已注册未开户
reg_user = ''
reg_password = '123456'

# 已开户
open_username = '153xxxxxxxx'
open_password = '123456'

uiBaseMethod.py

#-*- coding = utf-8 -*-

import os
from publicMethod.publicParams import *
from selenium import webdriver

# chrmoe初始化
def chromeInit():
    ''' '''
    # 设定模拟器型号为Nexus5
    mobile_emulation = {'deviceName': 'Nexus 5'}
    options = webdriver.ChromeOptions()
    # 指定chrome进入无界面模式  调试时可以注释此行及下面
    #options.add_argument('--headless')
    # 禁止使用gpu 避免一些奇怪的问题
    options.add_argument('--disable-gpu')
    # 将模拟器型号参数加入option
    options.add_experimental_option('mobileEmulation', mobile_emulation)

    chrome_path = ''.join([os.getcwd(), '\dirver\chromedriver.exe'])
    # 实例化浏览器对象
    my_browser = webdriver.Chrome(executable_path = chrome_path, chrome_options = options)
    my_browser.implicitly_wait(1)  # 设置隐式时间等待
    # 初始化清缓存
    my_browser.get_cookies()
    my_browser.delete_all_cookies()
    return my_browser

def login(my_browser, user_name, password):
    my_browser.get(HOST[env] + "/public-vue/common/index.html#/login")
    my_browser.find_element_by_xpath("//input[@type='text' and @class='ipt']").clear()
    my_browser.find_element_by_xpath("//input[@type='text' and @class='ipt']").send_keys(user_name)
    my_browser.find_element_by_xpath("//input[@type='password']").clear()
    my_browser.find_element_by_xpath("//input[@type='password']").send_keys(password)
    my_browser.find_element_by_xpath("//*[@class = 'ssui-btn ssui-btn-primary ssui-btn-primary_main']").click()
    my_browser.implicitly_wait(10)  # 设置隐式时间等待

if __name__ == "__main__":
    chromeInit()

pytestLogin.py

# -*- coding: utf-8 -*-
import unittest,time
from selenium import webdriver
from publicMethod.uiBaseMethod import *
from publicMethod.publicParams import *
from publicMethod.assertMethod import *

class LoginCase(unittest.TestCase):
    def setUp(self):
        self.my_browser = chromeInit()

    def test_user_login(self):
        self.user_name = open_username
        self.password = open_password
        login(self.my_browser, self.user_name, self.password)
        assert_result = insertClassExist(self.my_browser, "//div[@class='tabbar__label']")
        self.assertTrue(assert_result, '登录后跳转到理财投资也正常~')

    def tearDown(self):
        time.sleep(10)
        self.my_browser.quit()

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

callPytest.py

#!/usr/bin/env python
#-*- coding = utf-8 -*-

import os, time, sys
import unittest
import HTMLTestRunner

def creatSuit():
    '''创建测试用例集,加载测试用例:TestCase'''
    test_units = unittest.TestSuite()
    discover = unittest.defaultTestLoader.discover(os.getcwd() + '//testcase', pattern = "pytest*.py")
    for test_suit in discover:
        for test_case in test_suit:
            test_units.addTests(test_case)
    return test_units

if __name__ == "__main__":
    # 获取当前时间,用于命名的html文件名字
    now = time.strftime("%Y-%m-%d_%H_%M_%S",time.localtime())
    # 根目录
    root_path = os.getcwd()
    file_name = ''.join([root_path + '\\result\\' + now + "_result.html"])
    with open(file_name, "wb") as fp:
        runner = HTMLTestRunner.HTMLTestRunner(
                stream = fp,
                title = u"测试报告",
                description = u"用例执行情况:")

        # 运行测试用例集TestSuite(creatSuit返回值)
        runner.run(creatSuit())

测试报告
这里写图片描述

细节部分总结的还不够,具体的参见:unittest源码剖析
https://blog.csdn.net/zhanghs11/article/details/80158889

Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐