APP下载

一种基于Python 语言自动化测试框架的实现

2024-07-24刘玮玮

电脑知识与技术 2024年17期

摘要:文章通过设计特定测试场景,编写测试用例数据,基于Python的Unittest框架,采用PO模式实现通用操作封装,使用ddt装饰器实现遍历测试数据并批量执行。所实现的自动化测试检验了人力资源管理系统中,以系统管理员身份登录时,添加政治类别操作可能出现的几种情况。该测试过程能够自动截图,并通过断言比较测试用例的正确性,同时将生成的测试报告发送到指定邮箱。

关键词:Python;Unittest框架;PO对象;ddt装饰器;自动化测试

中图分类号:TP311.53 文献标识码:A

文章编号:1009-3044(2024)17-0055-04 开放科学(资源服务)标识码(OSID) :

0 引言

作为保证软件质量的重要手段,软件测试在日新月异的软件开发中愈发重要。自动化测试是将以人为驱动的测试行为转化为机器执行的过程,即模拟手工测试步骤,通过执行以程序语言编制的测试脚本自动地测试软件,涵盖了所有测试阶段。自动化测试具有跨平台兼容性,且与进程无关。广义的自动化测试强调整个测试过程都由计算机系统完成,范围更广;狭义的自动化测试主要指通过某个自动化工具自动执行特定测试任务,处理范围较小。

自动化测试适用于回归测试,因为重复单一的数据录入或击键等测试操作会造成不必要的时间和人力浪费。测试人员通常需要借助自动化测试工具对程序进行理解和对设计文档进行验证。采用自动化测试工具还有利于生成测试报告文档,保持版本的连贯性。自动化工具也能够确定测试用例的覆盖路径,确定测试用例集对程序逻辑流程和控制流程的覆盖。本文以系统管理员身份登录人资管理系统,验证添加政治面貌类别操作。

1 Unittest 框架

Unittest框架是Python自带的一种单元测试框架,具备编写用例、组织用例、执行用例、输出报告等自动化框架的条件。该框架可以实现批量执行用例,提供丰富的断言知识,还可以生成报告。Unittest框架的核心要素包括:TestCase(测试用例),TestSuite(测试套件),TextTestRunner(以文本形式运行测试用例),Tes⁃tLoader(批量执行测试用例-搜索指定文件夹内指定字母开头的模块),Fixture(固定装置(两个固定的函数,一个初始化时使用,一个结束时使用)) 。在使用Unittest框架创建测试用例时,首先要导入unittest包,新建的测试类需继承unittest.TestCase,并且测试方法必须以test字母开头[1]。

2 具体实现

2.1 测试环境搭建

安装Python、Selenium 插件、PyCharm 平台,配置相关环境变量后,还需要安装Chrome浏览器及对应Chrome驱动,并确保可以成功登录打开人资管理系统。打开PyCharm平台,创建一个项目,同时在创建项目时选择解释器为当前安装的Python[2]。

测试数据准备如图1所示。

项目路径如图2所示[3]。

2.2 封装基本操作

首先在指定名称文件夹下创建driver.py文件,封装打开谷歌浏览器操作,代码如下:

from selenium import webdriver

def browser():

driver=webdriver.Chrome()

#打开谷歌浏览器

return driver

在指定文件夹下创建function.py文件[4],封装截图方法inser_img(driver,filename),查找最新测试报告方法latest_report(report_dir),将测试报告发送到邮箱的方法send_mail(latest_report),以及读取csv文件方法。读取csv文件方法可以通过逐行逐列循环读取csv文件来批量执行测试用例,即通过数据驱动实现自动化测试某个功能,读取csv文件代码如下:

def get_csv_file(line):

# 文件路径需要自己修改成自己的文件路径

with open(r"盘符:\*\*\需被读取的文件名.csv",encoding=′utf-8-sig′) as file:

reader=csv.reader(file)

for index,row in enumerate(reader,1):

if index==line:

return row 以及创建myunit.py文件,封装启动测试集和结束测试集操作,代码如下:

import unittest

from driver.driver import *

class StartEnd(unittest.TestCase):

def setUp(self):

self.driver=browser()

self.driver.implicitly_wait(10)

self.driver.maximize_window()

def tearDown(self):

self.driver.quit()

2.3 定义基础类Python 文件

创建基础类BasePage.py,用于被所有页面对象类继承。其中,初始化方法用于打开被测系统页面,open方法用于打开指定url地址页面,find_element方法用于查找指定页面元素,相关代码如下:

from time import sleep

class Page():

def __init__(self, driver):

self.driver = driver

self. base_url = ′http://116.204.108.152: 30016/suthr/logon′

def _open(self, url):

url_ = self.base_url + url

print("Test page is %s" % url_)

self.driver.maximize_window()

self.driver.get(url_)

sleep(2)

assert self.driver.current_url == url_, ′Did not land on %s′ % url_

def open(self):

self._open(self.url)

def find_element(self, *loc):

return self.driver.find_element(*loc)

2.4 创建PageObject 对象

创建PO对象LoginPage.py文件,用于封装登录人资系统的操作;AddLeibiePage.py文件用于封装一系列操作,包括点击系统管理员链接→输入系统管理员用户名→输入系统管理员密码→点击登录按钮→点击类别维护菜单→点击政治面貌类别子菜单→点击创建类别按钮→填写政治类别名称框→填写描述框→点击保存按钮,以及读取弹窗文字信息和红底提示文字信息等。

以输入政治类别名称,点击保存为例,代码如下:

from selenium.webdriver.common.by import By

from Website. test_case. page_object. BasePage im⁃port *

from time import sleep

class LeibieAdd(Page):

...

lbmc = (By.ID, ′dictValue′) # 定位类别名称输入框

Baocun_loc = (By.XPATH, ′//*[@id="ajax-modal"]/div[3]/button[1]′) # 定位保存按钮hongdi_loc = (By.ID,′dictValue-error′) # 定位消息提示文字信息

...

def type_lbmc(self, lbname):

self.find_element(*self.lbmc).clear()

self.find_element(*self.lbmc).send_keys(lbname)

# 输入类别名称

def type_Baocun(self):

self.find_element(*self.Baocun_loc).click()

#点击保存按钮

def type_hongdi(self):

return self.find_element(*self.hongdi_loc).get_attri⁃bute("innerHTML")

# 读取红底文字信息

...

def test_zzlb_add(driver, lbname):

...

sleep(1)

add_page.type_lbmc(lbname)

sleep(1)

add_page.type_Baocun()

需要注意的是,各类动态增加方法时一定要加self参数,并且PO类与调用PO类的封装方法缩进要一致,表示同级的关系。如果缩进不一致,在后续测试类调用封装方法时会报“方法没有定义”的错误。

2.5 创建测试类

使用unittest框架创建测试类test_addzz.py,测试类中每一个以test开头的方法就是一条测试用例。同时,使用ddt装饰器实现遍历测试数据,每遍历出一条数据,就往测试类中添加一个以test开头的方法setattr (类,方法名,方法)[5]。

该测试类通过调用function.py中的读取csv文件方法get_csv_file(line)以及调用test_user_login(driver,username,password)方法,分别测试了csv文件中的3条测试数据,对应添加政治类别中的输入政治类别名称为空、重复和过长的操作。测试类能够实现测试界面的截屏,并且能够断言对比测试用例是否正确。关键代码如下:

import unittest

from Website. test_case. model import function,myunit

from Website.test_case.page_object.AddLeibiePage import *

from Website.test_case.page_object.LoginPage im⁃port *

from Website. test_case. page_object. AddPage im⁃port *

import time

import ddt

@ddt.ddt

class AddzzTest(myunit.StartEnd):

# @unittest.skip(′skip this case′)

def test01_add_null(self):

′′′操作成功′′′

print("test case is start run...")

test_date = function.get_csv_file(2)

#创建参数接收测试数据

test_user_login(self.driver,′ceshi01′,′123456′)

#登录

test_zzlb_add(self.driver,test_date[0])

#输入测试数据

time.sleep(3)

function. inser_img(self. driver, "test01_add_null.png")

# 截屏

po = LeibieAdd(self.driver)

# 设置参数接收数据

self.assertIn(test_date[1], po.type_hongdi())

# 断言对比测试用例是否正确

print("test case is successful test end!")

...

if __name__ == ′__main__′:

unittest.main()

2.6 生成测试报告并发送指定邮箱

为能够生成测试报告并发送指定邮箱,须创建run_test.py文件,相关代码如下:

import unittest

from Website.test_case.model.function import *

from HTMLTestRunner import HTMLTestRunner

import time

report_dir=′./test_report′

test_dir=′./test_case′

print("start run test case")

discover=unittest. defaultTestLoader. discover(test_dir,pattern="test_addzz.py")

now=time.strftime("%Y-%m-%d %H_%M_%S")

report_name=report_dir+′/′+now+′result.html′

print("start write report..")

with open(report_name,′wb′) as f:

runner=HTMLTestRunner(stream=f,title="Test Re⁃port" ,description="localhost login test")

runner.run(discover)

f.close()

print("find latest report")

latest_report=latest_report(report_dir)

print("send email report..")

send_mail(latest_report)

print("Test end")

3 测试结果

3.1 PyCharm 界面结果显示

从测试工作台可以看到,3个测试用例均通过,分别测试了添加政治类别名称为空、添加政治类别名称重复和添加政治类别名称过长这3种情况。测试结果均与预期相同,能够弹出相应的错误提示弹窗,测试通过,并成功发送测试报告邮件。界面如图3、图4 所示。

3.2 测试报告邮件

正确收到测试报告邮件,邮件显示测试内容和测试结果。界面如图5所示。

4 总结

本文通过设计特定测试场景,编写测试用例数据,实现了自动化测试,检验了人资管理系统中以系统管理员身份登录时,添加政治类别操作可能出现的几种情况。自动化测试能够自动截图、断言对比测试用例的正确性,并将生成的测试报告发送到指定邮箱。

整体使用Python+Unittest+PO框架实现自动化测试。基于Unittest框架,使用PO对象实现通用操作封装,提高了测试脚本的可重用性;使用ddt装饰器实现遍历测试数据并批量执行[6];同时实现了测试过程的自动截图,能够断言对比测试用例的正确性,并将生成的测试报告发送到指定邮箱。可以看出,使用Py⁃thon+Unittest+PO 框架实现自动化测试,能够实现自动化测试流程的一体化,提高测试效率。

参考文献:

[1] 王春明.基于Unittest的Python测试系统[J].数字通信世界,2023(3):66-69.

[2] 李亚伟,牛士会.基于Python通过unittest进行自动化测试[J].价值工程,2023,42(14):163-165.

[3] 蒋程燕,孟令琴.基于Python语言的自动化测试应用实例[J].工业控制计算机,2021,34(10):109-110,113.

[4] 王娜.基于python的接口自动化测试框架设计[J].电脑知识与技术,2020,16(12):246-248.

[5] 方巍,吴伶琳.基于Python的Web自动化测试的实践[J].现代计算机,2020(34):91-94.

[6] 单攀攀.一种基于Selenium与Unittest的Web自动化测试框架[J].信息技术与网络安全,2021,40(9):77-80.

【通联编辑:谢媛媛】