python进阶课测试进阶课

HTMLTestRunner高级技巧

2019-07-13  本文已影响1人  Xyxtank

一、更易读的测试报告

为了让测试报告更容易理解,更直观,需要对报告进行更多的细节描述,这就需要注释。而在python中,注释有两种,一种是comment,另一种是doc string。前者是普通的注释,后者用于函数、类和方法的描述。

HTMLTestRunner可以读取doc string类型的注释,所以要构建易读的测试报告,就用doc string 即可,方法就是在函数下方添加描述信息,如下所示:

这里以打开百度搜索为例,此处并没有做详细的注释信息,此时报告展示的信息如图:

import unittest
from selenium import webdriver
from HTMLTestRunner import HTMLTestRunner

class TestBaiduSearch(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get('http://www.baidu.com')
        self.driver.implicitly_wait(10)

    def test_baidu_search(self):
        self.driver.find_element_by_id('kw').clear()
        self.driver.find_element_by_id('kw').send_keys('测试')
        self.driver.find_element_by_id('su').click()

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

if __name__ == '__main__':
    testunit = unittest.TestSuite() #初始化测试用例集合对象,构建测试套件
    testunit.addTest(TestBaiduSearch("test_baidu_search")) #把测试用例加入到测试用力集合中去,将用例加入到检测套件中
    filename = './' +  'result.html'#重构文件名
    fp = open(filename,'wb')#定义测试报告存放路径
    runner = HTMLTestRunner(stream=fp)#定义测试报告
    runner.run(testunit)
    fp.close()

当对代码做更多的信息注释后,测试报告明显更人性化,更直观、易读。

注意对比,前后两张图,可以很直观的看出两者区别,并且此时修改的代码也很少,只是做了一些注释信息,如下:

import unittest
from selenium import webdriver
from HTMLTestRunner import HTMLTestRunner

class TestBaiduSearch(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get('http://www.baidu.com')
        self.driver.implicitly_wait(10)

    def test_baidu_search(self):
        '''测试百度搜索关键字''' #修改点
        self.driver.find_element_by_id('kw').clear()
        self.driver.find_element_by_id('kw').send_keys('测试')
        self.driver.find_element_by_id('su').click()

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

if __name__ == '__main__':
    testunit = unittest.TestSuite()  # 初始化测试用例集合对象,构建测试套件
    testunit.addTest(TestBaiduSearch("test_baidu_search"))  # 把测试用例加入到测试用力集合中去,将用例加入到检测套件中
    filename = './' + 'result.html'  # 重构文件名
    fp = open(filename, 'wb')  # 定义测试报告存放路径
    runner = HTMLTestRunner(stream=fp, title='百度搜索测试报告', description='用例执行情况')  # 定义测试报告
    runner.run(testunit)
    fp.close()

总结,修改了两处:

def test_baidu_search(self):
        '''测试百度搜索关键字''' #修改点
        self.driver.find_element_by_id('kw').clear()

另外,测试报告标题及测试用例提示描述:

runner = HTMLTestRunner(stream=fp, title='百度搜索测试报告', description='用例执行情况') 

二、自动生成不同的测试报告名称

每次测试用例执行完毕后,总是要手动修改测试报告名称,不修改名称的话会生成同样的测试报告,而且会把之前的测试报告覆盖,这非常不便于管理测试报告。因为测试报告相当于档案一样需要随时查阅,而且检查不同阶段的报告,才能看出测试工作的具体成效或成功,所以我们需要保存测试报告,并且报告的名称要有一定的规范。于是,我们用时间函数让测试报告自动更改名称。

1、time模块的具体使用

import time

print(time.time())#当前时间戳
print(time.ctime())#当前时间的字符串形式
print(time.localtime())#当前时间的strunc_time形式
print(time.strftime('%Y-%m-%d %H:%M:%S'))#获取当前时间,并且格式化为字符串

结果:

1562900671.1328707
Fri Jul 12 11:04:31 2019
time.struct_time(tm_year=2019, tm_mon=7, tm_mday=12, tm_hour=11, tm_min=4, tm_sec=31, tm_wday=4, tm_yday=193, tm_isdst=0)
2019-07-12 11:04:31

通过实例可以很明显的看出不同时间格式下的显示方式,而平时用的比较多的是最后一种,也就是获取当前时间,并且格式化为字符串。

2、根据时间生成测试报告名称

import time
import unittest
from selenium import webdriver
from HTMLTestRunner import HTMLTestRunner

class TestBaiduSearch(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get('http://www.baidu.com')
        self.driver.implicitly_wait(10)

    def test_baidu_search(self):
        '''测试百度搜索关键字'''
        self.driver.find_element_by_id('kw').clear()
        self.driver.find_element_by_id('kw').send_keys('测试')
        self.driver.find_element_by_id('su').click()

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

if __name__ == '__main__':
    testunit = unittest.TestSuite()  # 初始化测试用例集合对象,构建测试套件
    testunit.addTest(TestBaiduSearch("test_baidu_search"))  # 把测试用例加入到测试用力集合中去,将用例加入到检测套件中
    now = time.strftime('%Y-%m-%d %H_%M_%S')#获取当前时间,并且格式化为字符串
    filename = './' + now + 'result.html'  # 重构文件名
    fp = open(filename, 'wb')  # 定义测试报告存放路径
    runner = HTMLTestRunner(stream=fp, title='百度搜索测试报告', description='用例执行情况')  # 定义测试报告
    runner.run(testunit)
    fp.close()

注意: 用了不同的格式生成测试报告名称,这个可以根据个人实际情况而定。一般人们比较习惯时间用冒号":"进行分割,但是文件名称并不支持冒号“:”。

now = time.strftime('%Y-%m-%d %H_%M_%S')中%H_%M_%S的_不能换为冒号“:”,因为文件名不能出现冒号“:”。

三、项目集成测试报告

一般情况下,项目文件目录需要遵循一定的规范,比如测试用例脚本在一个文件中,测试报告在另外一个文件中,而且文件名的命名也需要有一定的标准,这样更符合管理,也方便测试程序的执行。总而言之:

这里创建两个文件夹分别保存测试用例脚本(test_case)和测试报告(test_report),另外,再创建一个执行测试脚本的文件(runtest.py),统一查找并执行需要测试的脚本。

runtest.py脚本中的代码如下:

import time
import unittest
import os
from HTMLTestRunner import HTMLTestRunner

def discover():
    '''获取需要执行的测试用例脚本'''
    suite = unittest.defaultTestLoader.discover(
        start_dir=os.path.join(
            os.path.dirname(__name__),
            'test_case'),  # 这个是待执行用例的目录
        pattern='test_txt_mail.py',  # 这个是匹配脚本名称的规则
        top_level_dir=None  # 这个是顶层目录的名称,一般默认等于None就行了
    )
    return suite

def get_time():
    '''返回当前时间格式化信息'''
    now = time.strftime('%Y-%m-%d %H_%M_%S')  # 获取当前时间,并且格式化为字符串
    return now

def go_runner():
    '''定义测试报告,执行测试用例脚本'''
    filename = os.path.join(
        os.path.dirname(__name__),
        'test_report',
        get_time() + 'result.html')
    fp = open(filename, 'wb')
    runner = HTMLTestRunner(stream=fp,
                            title='自动化测试报告',
                            description='测试用例执行详情')
    runner.run(discover())
    fp.close()

if __name__ == '__main__':
    go_runner()

test_txt_mail.py脚本中的代码如下:

import unittest
import os
from selenium import webdriver
import time

def testdata(index):
    '''测试数据'''
    with open(os.path.join(os.path.dirname(__file__), 'TestData.txt'), 'r') as fp:
        data = fp.readlines()
        new_data = data[index].strip().split(',')
    return new_data

class MyMailLogin(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()
        self.driver.get('https://mail.sina.com.cn/')
        self.driver.implicitly_wait(30)

    def mail_login(self, username, password):
        '''登录邮箱'''
        self.driver.find_element_by_id('freename').clear()
        self.driver.find_element_by_id('freename').send_keys(username)
        self.driver.find_element_by_id('freepassword').clear()
        self.driver.find_element_by_id('freepassword').send_keys(password)
        self.driver.find_element_by_link_text('登录').click()

    def error_info(self):
        '''定位提取登录错误提示信息'''
        freeError = self.driver.find_element_by_xpath(
            '//div[@class="freeError"]//span').text
        return freeError

    def test_username_null(self):
        '''测试登录邮箱:用户名为空'''
        self.mail_login(testdata(0)[0], testdata(0)[1])
        self.assertEqual(self.error_info(), testdata(0)[2])

    def test_username_and_password_null(self):
        '''测试登录邮箱:用户名及密码为空'''
        self.mail_login(testdata(1)[0], testdata(1)[1])
        self.assertEqual(self.error_info(), testdata(1)[2])

    def test_username_error(self):
        '''测试登录邮箱:用户名错误'''
        self.mail_login(testdata(2)[0], testdata(2)[1])
        self.assertEqual(self.error_info(), testdata(2)[2])

    def test_password_error(self):
        '''测试登录邮箱:密码错误'''
        self.mail_login(testdata(3)[0], testdata(3)[1])
        time.sleep(3)
        self.assertEqual(self.error_info(), testdata(3)[2])

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

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

测试报告如下:

注意:执行的脚本文件和数据均来自之前的文章,并且代码也有少许区别,跳转链接:https://www.jianshu.com/p/66e952c3e88b

上一篇下一篇

猜你喜欢

热点阅读