前情介紹:
在自動化測試框架中投剥,數(shù)據(jù)驅(qū)動的意思是指定的是測試用例或者說測試套件是由外部數(shù)據(jù)集合來驅(qū)動的框架。
數(shù)據(jù)集合(也可稱之為數(shù)據(jù)來源)可以是任何類型的數(shù)據(jù)文件比如xls坦康,xlsx浑度,csv等等字支,甚至可以是數(shù)據(jù)庫中的表雷厂⊥镌觯總之,是一個放數(shù)據(jù)的地方就對了罗侯。
核心思想就是數(shù)據(jù)和測試代碼分離器腋,及時當(dāng)測試數(shù)據(jù)發(fā)生大量變化的情況下測試代碼(或者說測試用例)可以保持不變。
最常見的例子是需要用多個不同的賬號和密碼來登陸某個郵箱钩杰,來驗證哪些是有效的值纫塌,哪些是錯誤的值,或者哪些值可以導(dǎo)致出錯等等讲弄。
數(shù)據(jù)驅(qū)動并不是和關(guān)鍵字驅(qū)動等水火不相容的一種驅(qū)動模式措左,我的理解是,兩者更像是互相協(xié)助的關(guān)系避除。甚至你把數(shù)據(jù)看成一種關(guān)鍵字也未嘗不可怎披。
練習(xí)環(huán)境配置
實例1(UI自動化-百度搜索)
實例2(有效登錄)
實例3(無效登錄)
實例4 (Appium)
實例5 (連接mysql數(shù)據(jù)庫)
實例6 (GET/POST請求)
實例7(接口API測試)
Appium Error總結(jié)
robotframework Error總結(jié)
測試需求:
為了更純粹一點(diǎn)的看到RF中的數(shù)據(jù)驅(qū)動的模式,這次采用了官方的Demo做一個講解瓶摆。
對 一個 簡單計算器的Calculator.py進(jìn)行測試凉逛,Calculator.py的代碼如下(寫的漂亮):
class Calculator(object):
BUTTONS = '1234567890+-*/C='
def __init__(self):
self._expression = ''
def push(self, button):
if button not in self.BUTTONS:
raise CalculationError("Invalid button '%s'." % button)
if button == '=':
self._expression = self._calculate(self._expression)
elif button == 'C':
self._expression = ''
elif button == '/':
self._expression += '//' # Integer division also in Python 3
else:
self._expression += button
return self._expression
def _calculate(self, expression):
try:
return str(eval(expression))
except SyntaxError:
raise CalculationError('Invalid expression.')
except ZeroDivisionError:
raise CalculationError('Division by zero.')
class CalculationError(Exception):
pass
測試設(shè)計:
數(shù)據(jù)驅(qū)動引入了一個非常有效的概念,即“模板”概念群井,在很多測試場景下状飞,測試人員輸入的操作是有一定重復(fù)性的,區(qū)別只在于輸入的數(shù)據(jù)书斜,還是以登陸為例诬辈,除了包含正常的測試用例,還需要有其他的異常用例覆蓋才能保證登陸接口的正確性荐吉”涸悖基于橫向構(gòu)造不同的測試數(shù)據(jù)輸入來判斷不同的測試結(jié)果,即為數(shù)據(jù)驅(qū)動样屠。行為可以封裝成模板穿撮。
先用一個CalculatorLibrary庫來進(jìn)行封裝需要做的測試步驟,對應(yīng)的驗證和錯誤處理
- push button
- push buttons
- result_should_be
- should_cause_error
再在RF中設(shè)計兩個模板來使用上面庫中的方法痪欲。
不同的輸入數(shù)據(jù)則在測試用例中體現(xiàn)悦穿。
測試實現(xiàn):
1 . 編寫CalculatorLibrary.py文件,代碼示例如下(最漂亮的還是寫注釋的地方勤揩,嘖嘖嘖):
from calculator import Calculator, CalculationError
class CalculatorLibrary(object):
"""Test library for testing *Calculator* business logic.
Interacts with the calculator directly using its ``push`` method.
"""
def __init__(self):
self._calc = Calculator()
self._result = ''
def push_button(self, button):
"""Pushes the specified ``button``.
The given value is passed to the calculator directly. Valid buttons
are everything that the calculator accepts.
Examples:
| Push Button | 1 |
| Push Button | C |
Use `Push Buttons` if you need to input longer expressions.
"""
self._result = self._calc.push(button)
def push_buttons(self, buttons):
"""Pushes the specified ``buttons``.
Uses `Push Button` to push all the buttons that must be given as
a single string. Possible spaces are ignored.
Example:
| Push Buttons | 1 + 2 = |
"""
for button in buttons.replace(' ', ''):
self.push_button(button)
def result_should_be(self, expected):
"""Verifies that the current result is ``expected``.
Example:
| Push Buttons | 1 + 2 = |
| Result Should Be | 3 |
"""
if self._result != expected:
raise AssertionError('%s != %s' % (self._result, expected))
def should_cause_error(self, expression):
"""Verifies that calculating the given ``expression`` causes an error.
The error message is returned and can be verified using, for example,
`Should Be Equal` or other keywords in `BuiltIn` library.
Examples:
| Should Cause Error | invalid | |
| ${error} = | Should Cause Error | 1 / 0 |
| Should Be Equal | ${error} | Division by zero. |
"""
try:
self.push_buttons(expression)
except CalculationError as err:
return str(err)
else:
raise AssertionError("'%s' should have caused an error."
% expression)
2 . RF中創(chuàng)建一個Data Driven的項目,測試用例和模板的名字的結(jié)構(gòu)如下:
在項目那一級導(dǎo)入CalculatorLibrary庫秘蛔,導(dǎo)入后CalculatorLibrary里的方法都可以被作為關(guān)鍵字使用陨亡。
- 將剛才的CalculatorLibrary.py文件放在和這個項目同一個目錄下傍衡。
- 點(diǎn)擊Library按鈕后輸入文件名即可導(dǎo)入。
3 . 最下方的兩個齒輪形狀的就是模板形式负蠕,可以通過New User Keyword的方式來創(chuàng)建(創(chuàng)建好一個項目后蛙埂,在項目名上右鍵則可創(chuàng)建User Keyword),對于計算器測試來說遮糖,也就兩種結(jié)果绣的,一種是輸入正常的值得到正常的結(jié)果,一種是輸入異常的值得到錯誤提示
Calculator - 正常的值的測試步驟
Calculator should fail-異常的值的測試步驟
4 .構(gòu)造測試用例來進(jìn)行測試欲账。
加減乘除屡江,輸入異常,輸入不允許的值(一串字符串赛不,空值惩嘉,除以0),比如:
最終代碼如下:
*** Settings ***
Documentation Example test cases using the data-driven testing approach.
...
... The _data-driven_ style works well when you need to repeat
... the same workflow multiple times.
...
... Tests use ``Calculate`` keyword created in this file, that in
... turn uses keywords in ``CalculatorLibrary.py``. An exception
... is the last test that has a custom _template keyword_.
...
... Notice that one of these tests fails on purpose to show how
... failures look like.
Test Template Calculate
Library CalculatorLibrary.py
*** Test Cases *** Expression Expected
Addition 12 + 2 + 2 16
2 + -3 -1
Subtraction 12 - 2 - 2 8
2 - -3 5
Multiplication 12 * 2 * 2 48
2 * -3 -6
Division 12 / 2 / 2 3
2 / -3 -1
Failing 1 + 1 3
Calculation error [Template] Calculation should fail
kekkonen Invalid button 'k'.
${EMPTY} Invalid expression.
1 / 0 Division by zero.
*** Keywords ***
Calculate
[Arguments] ${expression} ${expected}
Push buttons C${expression}=
Result should be ${expected}
Calculation should fail
[Arguments] ${expression} ${expected}
${error} = Should cause error C${expression}=
Should be equal ${expected} ${error} # Using `BuiltIn` keyword
CC先生說:RF的數(shù)據(jù)驅(qū)動看起來的確是非常簡潔的踢故,采用了封裝的思維文黎,將更多的操作都封裝到庫,模板中殿较,干凈利落的實現(xiàn)了測試數(shù)據(jù)和測試步驟的分離耸峭。大熱天的,看起來還真是清爽~~~