使用“数据驱动测试”之前

栏目: 编程工具 · 发布时间: 6年前

内容简介:什么是数据驱动测试?从它的定义来看,就是数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。说的直白些,就是参数化的应用。
编辑推荐:
本文来自cnblogs,文章简单明了的给大家介绍了什么是数据驱动测试,然后借助单元测试框架怎么做自动化测试。

什么是数据驱动测试?

从它的定义来看,就是数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变。说的直白些,就是参数化的应用。

使用“数据驱动测试”之前

“他们”认为数据驱动什么样子?

这里以csv文件为例,大多文章也是选用的csv/excel文件。

参数、断言、结果都有了,大概就这样子吧?

接下来需要将数据读取出来。

# coding=utf-8

import csv

import codecs

# 读取本地 CSV 文件

data = csv.reader(codecs.open('user_info.csv', 'r', 'utf_8_sig'))

# 用户存放用户数据

users = []

# 循环输出每一行信息

for line in islice(data, 1, None):

users.append(line)

# 打印

print(users)

得到结果:

 [['', '123', '请输入帐号', ''],
 ['user', '', '请输入密码', ''],
 ['error', 'error', '帐号或密码错误',''],
 ['admin', 'admin123', 'admin你好', ''],
 ['guest', 'guest123', 'guest你好', '']]

这里得到一个测试数据的二维数组。

那么接下来要用这些数据做自动化测试了?被测试功能如下:

使用“数据驱动测试”之前

测试代码如下:

# 测试登陆功能

from selenium import webdriver

driver = webdriver.Chrome()

for user in users:

driver.get("http://127.0.0.1:8000/")

driver.find_element_by_id ("inputUsername").send_keys (user[0])

driver.find_element_by_id ("inputPassword").send_keys (user[1])

driver.find_element_by_id ("Login").click()

sleep(2)

tips = driver.find_element_by_id("tips").text

print(tips)

print(user[2])

try:

assert tips == user[2]

except AssertionError as msg:

print(msg)

user[3] = "Faile"

else:

user[3] = "Pass"

driver.quit()

# 打印结果

print(users)

运行之后的测试结果:

 [['', '123', '请输入帐号', 'Pass'],
 ['user', '', '请输入密码', 'Pass'],
 ['error', 'error', '帐号或密码错误','Pass'],
 ['admin', 'admin123', 'admin你好', 'Faile'],
 ['guest', 'guest123', 'guest你好', 'Faile']]

看,结果已经写到最后一列了。

最后,我们还需要将测试结果写回到csv文件中。

# 读取本地 CSV 文件

csv_file = csv.writer(codecs.open('user_info.csv', 'w','utf_8_sig'),

# 写入标题

csv_file.writerow(['用户名','密码','断言','结果'])

# 循环写入数据

for user in users:

csv_file.writerow(user)

# 打印

print(users)

打开CSV文件,结果如下:

使用“数据驱动测试”之前

看结果一列,是不是已经有了结果。

那么,下来思考几个问题。

1、测试结果是否太过简单了,只有“Pass”和“Faile”,没有任何失败的日志,是否需要另起一列记录失败日志?

2、如何统计出总失败的用例数和成功的用例数?

3、如果想单独验证失败的两条用例应该怎么做?例如上图中的最后两条失败的用例。

4、上面的测试代码中,有多少是真正用在测试操作的,至少一半都在读写csv文件,是否需要做封装,想想怎么封装更简单?

5、在获取具体读取数据的时候,我们使用的是user[0]、user[1]、user[2],你真的容易分辨这些数据么?如果又加了一列数据呢?不改代码是不是就对不上号了。

6、这只是一组登录数据。我们知道不同的功能,所需要的数据是不一样的,比如搜索,只需要“搜索关键字”, 例如注册,需要“邮箱”、“密码”、“重复密码”、“昵称”等。我们一个系统有N多功能的好吧!

7、如第6条,这些测试数据要怎么放,放在一个csv文件还是多个文件?怎么统计测试结果?

所以,知道读取数据文件有多坑了吧!?谁说的方便维护?你一定没用这种方式写过真正的项目吧!一直处在跟着别人写demo阶段。如果你有更“高大上”的处理方式欢迎请告诉我,谢谢!

以下,我将介绍基于单元测试框架的数据驱动。

单纯读取数据文件来做自动化是有诸多问题的。那么我们借助单元测试框架来做自动化就爽多了,因为它解决了测试中的几问题。

如何定义一条测试用例,我们知道编程的世界里并没“用例”的概念。它只有目录、文件、类、方法、函数...,而单元测试框架告诉我们如何定义一条用例。

如何写断言,是的!当你做了一堆操作之后,如何判断这一系列操作是符合预期的,那么一定要拿实际结果与预期结果进行比较,而单元测试框架告诉我们如何写断言。

测试结果统计,当执行了一系列的用例之后,总共运行了多少条用例,成功了多少条,失败了多少条,失败的用例错误在哪里?单元测试框架会帮我们统计和展示。

被测功能还是上文的功能。

使用“数据驱动测试”之前

这里以unittest 单元测试框架为例。

import unittest

from selenium import webdriver

class LoginTest(unittest.TestCase):

@classmethod

def setUpClass(cls):

cls.driver = webdriver.Chrome()

cls.url = "http://127.0.0.1:8000/"

cls.driver.implicitly_wait(10)

@classmethod

def tearDownClass(cls):

cls.driver.quit()

def user_login (self, username, password):

driver = self.driver

driver.get(self.url)

driver.find_element_by_id ("inputUsername ").send_keys (username)

driver.find_element_by_id ("inputPassword ").send_keys (password)

driver.find_element_by_id ("Login ").click()

def atest_login_01(self):

self.user_login("", '123')

tips = self.driver.find_element_by_id ("tips").text

self.assertEqual(tips, '请输入帐号')

def atest_login_02(self):

self.user_login ("user", "")

tips = self.driver.find_element_by_id ("tips").text

self.assertEqual(tips, '请输入密码')

def atest_login_03(self):

self.user_login("error", "error")

tips = self.driver.find_element_by_id ("tips").text

self.assertEqual (tips, '帐号或密码错误')

def atest_login_04(self):

self.user_login ("admin", " admin123456")

sleep(2)

tips = self.driver.find_element_by_id ("user").text

self.assertEqual (tips, 'admin你好')

if __name__ == '__main__':

unittest.main()

看!测试代码是不是非常清晰。运行结果如下。

...F

=============================

FAIL: test_login_04 (__main__.LoginTest)

-------------------------------

Traceback (most recent call last):

File "test_login.py", line 43, in test_login_04

self.assertEqual(tips, 'admin你好')

AssertionError: 'admin' != 'admin你好'

- admin

+ admin你好

-----------------------------

Ran 4 tests in 12.977s

FAILED (failures=1)

结果告诉我们运行了4条测试,1条失败了,失败的原因是test_login_04用例断言预期结果为“admin你好”,实际结果为“admin”。

可是,这没有用到读取数据文件啊?不是,数据驱动啊? 我以为这么规范的编写测试用例,要啥自行车。

其实,我已经尽量的把登录操作做了封装,每条用例里面只关心登录的数据和结果的断言。谁告诉你“数据驱动”就必须要“读取数据文件”的?

我们继续引入unitest的参数化。

import unittest

from selenium import webdriver

from time import sleep

class LoginTest(unittest.TestCase):

@classmethod

def setUpClass(cls):

cls.driver = webdriver.Chrome()

cls.url = "http://127.0.0.1:8000/"

cls.driver.implicitly_wait(10)

@classmethod

def tearDownClass(cls):

cls.driver.quit()

def user_login(self, username, password):

driver = self.driver

driver.get(self.url)

driver.find_element_by_id ("inputUsername").send_keys (username)

driver.find_element_by_id ("inputPassword").send_keys (password)

driver.find_element_by_id ("Login").click()

@parameterized.expand([

("user_null", '', "123", "请输入帐号"),

("pawd_null", "user", '', "请输入密码"),

("login_error", "error", "error", "帐号或密码错误"),

("login_success", "admin", "admin123456", "admin你好"),

])

def test_login (self, name, username, password, assert_text):

self.user_login(username, password)

if name == "login_success":

sleep(2)

tips = self.driver.find_element_by_id ("user").text

self.assertEqual(tips, assert_text)

else:

tips = self.driver.find_element_by_id ("tips").text

self.assertEqual(tips, assert_text)

if __name__ == '__main__':

unittest.main(verbosity=2)

反正都是定义测试数据,这里提供了规范的元组给你用来定义数据,而且测试数据与测试方法上下呼应,维护起来也比读取文件方便多了,这次还要啥自行车?

测试结果:

test_login_0_user_null (__main__.LoginTest) ... ok

test_login_1_pawd_null (__main__.LoginTest) ... ok

test_login_2_login_error (__main__.LoginTest) ... ok

==============================

FAIL: test_login_3_login_success (__main__.LoginTest)

---------------------------------

Traceback (most recent call last):

File "C:\Python36\lib\site-packages\parameterized-0.6.1-py3.6.egg\parameterized\parameterized.py", line 392, in standalone_func

return func(*(a + p.args), **p.kwargs)

File "test_login.py", line 37, in test_login

self.assertEqual(tips, assert_text)

AssertionError: 'admin' != '请输入密码'

- admin

+ 请输入密码

------------------------------------

Ran 4 tests in 12.363s

FAILED (failures=1)

测试结果依然清晰明白。

这个话题,本来到此就结束了,我其实是很鄙视读取数据文件的操作的,因为真get不到它的“方便”之处,做自动化测试写代码就老老实实的写代码,就你测试用的这点数据,真没必要读取文件,数据库就更谈不上了。但是,那么多人都在分享读取数据文件的demo(实际规模化之后就不得而知了),我也看了不少资料,找到一些勉强能接受的方法。

当然,这又是另一篇文章了。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大演算

大演算

佩德羅.多明戈斯 / 張正苓,胡玉城 / 三采 / 2016-8-1 / 620

揭開大數據、人工智慧、機器學習的祕密, 打造人類文明史上最強大的科技——終極演算法! 有一個終極演算法,可以解開宇宙所有的祕密, 現在大家都在競爭,誰能最先解開它! .機器學習是什麼?大演算又是什麼? .大演算如何運作與發展,機器可以預測什麼? .我們可以信任機器學過的東西嗎? .商業、政治為什麼要擁抱機器學習? .不只商業與政治,醫學與科學界也亟需......一起来看看 《大演算》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具