Robot Framework 初始化与清除

测试的 setup(环境创建)和 teardown (清除),是每个自动化测试框架都会涉及到的概念。简单的说, setup 是测试一个用例(或者套件)前要做的事情teardown 是测试后要做的事情。其实,任何测试,包括手工测试都会涉及到 setupteardown

比如,我们有一个 web 系统,测试登录功能的时候,需要先注册1个用户,用这个用户验证登录功能。那么对于测试登录功能的套件(或者用例)来说,前面先注册好一个用户的操作,就是 setup 。而是否要 teardown ,主要看这个用例执行后的结果是否会影响下面要执行的用例。比如,我们执行了上面用户登录的测试后,,如果要测试系统的统计功能,统计当前有多少个用户登录,其中的一个用例就是,当没有用户登录的时候,显示登录数量为0。这个时候就需要前面的用例执行完后,必须 teardown ,否则会影响后面用例的执行。由于人具有较高的智能判断能力,在人工执行用例的时候,会记忆或者判断出当前的系统的状态是否满足 测试某个用例的条件。所以测试用例书写的时候,往往并没有清除的写出执行前后需要做什么 setup、teardown。而自动化测试软件就不一样了,它必须明确每一个测试套件(用例)执行时的状态,否则一旦用例数量比较大的时候,就经常会出现由于执行前环境的不同而导致测试执行异常。有的时候不同的执行用例的顺序,会导致同样的测试用例和被测系统,这次执行成功,下次执行失败。

RF 中,每个测试套件目录、测试套件文件、测试用例都可以有自己的 setupteardown ,所有的 setupteardown 操作都是由一个关键字语句构成的。

测试用例的 setup、teardown

  • 写在测试用例的表的配置项中
*** Test Cases ***
测试1
    [Setup]  log to console  \n *** case st setup ***
    log to console  测试用例主体部分
    [Teardown]  log to console  \n *** case st teardown ***  

这里有一个测试用例 Test Cases测试1 ,它的配置项就是我们用方括号括起来的一个是 [Setup] 一个是 [Teardown]

这边有个例子:

*** Test Cases ***
测试1
    [Documentation]    测试初始化、清除
    [Setup]    log to console  \n *** 测试用例1 setup ****
    log to console   测试用例1主体部分
    [Teardown]    log to console   \n *** 测试用例 1 teardown ****

测试2
    log to console   测试用例2主体部分

测试3
    log to console   测试用例3主体部分

这边测试用例有测试1、测试2、测试3,三个测试用例,在测试1里面有方括号括起来的 [Setup]、[Teardown]。这个就代表测试用例1的 [Setup]和[Teardown] ,这边没有什么具体的内容,我的 [Setup][Teardown] 只是打了一些 log 我们执行一下看一下它的结果。

Robot Framework 初始化与清除_第1张图片
image.png

我们可以看到首先打印了测试1Setup 接下来是用例1的主体部分,然后是他的 Teardown 这是测试用例1打印的所有的 log ,在执行主体部分之前是 Setup 做的操作,主体部分执行完之后是 teardown 的工作,其它的两个测试用例测试用例23只有主体部分,因为他没有 [Setup][Teardown] 所以只执行主体部分,这个比较简单 [Setup][Teardown] 一般做一些初始化清除的有实质内容的工作,我们这里为了演示只是打印 log,我们看下 log 看看执行 log 上的内容,也会记录初始化与清除的工作的。

Robot Framework 初始化与清除_第2张图片
image.png

这个是测试用例的 [Setup][Teardown] 大家理解一下,接下来看下测试套件文件的

测试套件文件的Setup和Teardown

除了测试用例以外,测试套件也有初始化与清除,有的人会想测试用例中有不就行了吗,为什么测试套件里面也要有初始化与清除呢?大家考虑这样一种情况,因为我们有的情况其实针对一个测试套件里面所有的用例都需要做的一个操作,比如说我有一个用户登录的功能,里面有10个用例,这些用例的初始化都是要创建一个用户,举个例子:

Robot Framework 初始化与清除_第3张图片
image.png

这里有一个登陆用户的用户名和密码,用户名就是abc,密码就是123,有这样一个用户,这边用例是创建一个用户跟之前的用户abc密码123有关联关系,比如创建一个test suite1里面t1里面跟已存在的用户用户名是一样的abc密码不一样12,然后test case2用户名不一样密码是一样的,testcase3用户名ab和密码12都不一样。
如果有这样一个测试套件文件,这里面的测试用例它都需要存在一个用户名是abc密码是123用户,第一个用例是创建一个和用户名一样密码不一样的用户,第二是用户名不一样密码一样,第三用户名密码都不一样,那对于这种测试套件里面的测试用例他是不是共用一个初始化条件就是有一个用户名是abc密码是123的用户,如果我们只在每一个测试case里面去定义用户名密码,十个用例我要把用户名为abc密码123的用户创建十次,所以因为这个原因我们在test suite1的初始化里面就创建了这样一个abc的用户,我在下面case执行的时候就不需要在创建了,所以他们共用一套初始化的环境,我们不需要在每个初始化的用户里面都创建这样一个用户,我们只需要在进入测试套件整个测试套件文件执行之前创建一个用户,在所有的测试套件里面呢每个用例执行完了之后再把它删掉这样的话就可以了,有的人会想既然像之前这种情况,我直接在t1里面创建一个用户名为abc密码为123的用户,不删掉,给后面的2,3使用这样可以吗??这样是不可以的,因为如果前面创建失败或者测试用例失败, 那后面的就没有初始化条件测试就不对了,还有一种情况你怎么知道我每次执行会选择所有的用例呢?如果我先执行后面的测试用例最后在执行t1或者我根本就不执行t1会有什么问题呢,那我的初始化环境就没有了,所以这里给大家强调测试用例之间一定不要有相互依赖关系因为你每次选择测试用例都是不一样的比如有冒烟测试。顺序和数量都是不一样的所以不能把某个 case 作为其他 case 的依赖,所以我们不能这样做,这边就要用到测试套件文件的 setup、teardown 这是为什么需要他,知道了原因之后我们来看,测试套件文件的 setup、teardown

测试套件有两种类型的 SetupTeardown,一个是 Suite setup/Teardown,一个是 Test setup/Teardown。其中前者的(suite的)是进入这个 suite 执行用例前必须执行且只执行一次。而后者是,如果 suite 内的用例本身没有 setup/Teardown ,才执行缺省 setup/Teardown 。后者会被包含用例的 setup/Teardown 所取代。测试套件文件的 setup、teardown 是写在文件的 Settings 表中的。

我们先看第一个 Suite setup/Teardown 例子:

*** Settings ***
Suite Setup       log to console   \n --- Suite st2 Setup ---
Suite Teardown    log to console   \n --- Suite st2 Teardown ---

*** Test Cases ***
测试1
    [Setup]    log to console  \n *** case 测试1 setup ****
    log to console   测试用例主体部分 11
    [Teardown]    log to console   \n *** case 测试1 teardown ****

测试2
    log to console   测试用例主体部分22

测试3
    log to console   测试用例主体部分33

首先他是放在测试套件的 Settings 表里面,这个测试套件文件有三个测试用例第一个测试用例有自己的 setup Teardown ,第二个第三个没有,而这个 Suite setup/Teardown 执行顺序是进入测试套件之前先执行 Suite Setup ,所有的用例执行完了之后再执行 Suite Teardown 我们执行一下。

Robot Framework 初始化与清除_第4张图片
image.png

进入到测试 Suite 的之后就执行它的 Suite Setup,然后是测试用例主体的1、2、3部分,全部执行完了之后再执行 SuiteTeardown。大家看到没,他是包在测试用例的头和尾之间的。

下面看一下 Test Setup\Teardown

*** Settings ***
Suite Setup       log to console   \n --- Suite st Setup ---
Suite Teardown    log to console   \n --- Suite st Teardown ---
Test Setup       log to console   \n --- Test st Default Setup ---
Test Teardown    log to console   \n --- Test st Default Teardown ---

*** Test Cases ***
测试1
    [Setup]    log to console  \n *** case 1 setup ****
    log to console   测试用例主体部分11
    [Teardown]    log to console   \n *** case 1 teardown ****

测试2
    log to console   测试用例主体部分22

测试3
    log to console   测试用例主体部分33

我们除了刚才的 suite setup 之后我们又加了两个 Test SetupTest Teardown 仍然放在 Settings 表里面的,我们刚说了 Test setup/Teardown 如果用例本事没有 setup 和 Teardown 我们才用它的,我们看一下这个测试套件文件里面有三个用例,第一个用例有自己的 setup和Teardown 他还会用 Test SetupTest Setup Teardown 吗,如果他有的话它就会用自己的,测试用例23他们没有自己的测试套件初始化和清除那么他就会用 Test Setup\Teardown 作为它的 Defaultcasesetupteardown ,运行截图:

Robot Framework 初始化与清除_第5张图片
image.png

这个是测试套件文件的 setupTeardown 除了测试套件的文件还有测试套件的目录呢,测试套件可以是目录也可以是文件,测试套件的文件又可以包含子的套件目录也可以包含子的文件,比如我们有一些组合目录登录功能、注册功能都输入用户管理功能等等,就是这种一层层组合的,可以加很多目录出来,我们测试套件的目录它也可以有初始化和清除,有没有觉得奇怪啊,测试套件文件它对应一个文件初始化清除就放在文件的Settings 表里面,这个很容易理解,那么测试套件目录他是一个目录它的初始化清除对应的语句要放在那里呢?大家来看一下。

测试套件目录的 setup Teardown

我们 python 里面都有 package 都有对应的 __init__.py文件,那么 robot 里面测试套件
目录的 setupTeardown 它放在他目录的配置文件 __init__ 这个 Settings 表里面,他可以是 __init__.txt 或者 __init.robot__ 如果这个文件存在了他就对应这个目录的配置文件,我们把它放在这些文件的 settings 表里面。 这个和 python 是一样的,而且他们 settings 里面的 setupTeardown 和我们测试套件文件也非常类似。他也分两种类型的一种是 Suite ,一种是 Test 大家理解一下.

  • 两种类型
    • Suite setup/Teardown
      进入和退出这个suite执行用例前后必须执行且只分别执行一次

    • Test setup/teardown
      如果 suite 内的用例、或者子套件本身没有 setup/teardown ,才执行

Robot Framework 初始化与清除_第6张图片
image.png

我这里有个 suit1 有个 st1.robotst2.robot 如果想给 suit1 做一个初始化清除的文件,那么就需要创建一个 init.robot 大家看一下

Robot Framework 初始化与清除_第7张图片
image.png

__init__.robot里面打印的 log 都叫 Suite big Setup 以及 Test big Default两种类型(testsuite),这是测试套件suite1的初始化与清除,这里面有个 St1.robot

*** Settings ***
Suite Setup       log to console   \n --- Suite little Setup ---
Suite Teardown    log to console   \n --- Suite little Teardown ---
Test Setup       log to console   \n --- Test little Default Setup ---
Test Teardown    log to console   \n --- Test little Default Teardown ---


*** Test Cases ***
测试1
    [Setup]    log to console  \n *** 测试用例1 setup ****
    log to console   测试用例1 主体部分
    [Teardown]    log to console   \n *** 测试用例1 teardown ****

测试2
    log to console   测试用例2 主体部分

St1 里面又有自己的 Suite Setup/TeardownTest Setup/Teardownst1 又有测试用例1和测试用例2,测试用例1有自己的测试用例的 setupTeardown ,还有一个St2.robot


*** Test Cases ***
测试3
    [Setup]    log to console  \n *** 测试用例3 setup ****
    log to console   测试用例3主体部分
    [Teardown]    log to console   \n *** 测试用例3 teardown ****

测试4
    log to console   测试用例4主体部分

St2.robot 没有任何的 Suite Setup/Teardown 但是测试用例3有他自己的这个 setupTeardown用例4就什么都没有,我们执行下看看,它会打印出什么东西出来,执行之前我们要想一下怎么执行呢?这是一个套件套件怎么执行?直接用 robot 直接执行 suit1就可以了,整个 suit1 有两个测试用例的文件 st1st2 对应的测试用例一个是测试1测试2,另一个是测试3和测试4,那我看下他们执行的结果。运行结果有点长,截图一次截不了我就把结果复制了


E:\tmp\rf1>robot suite1
==============================================================================
Suite1
==============================================================================

--- Suite big Setup ---
Suite1.St1
==============================================================================

--- Suite little Setup ---
测试1
*** 测试用例1 setup ****
.测试用例1 主体部分
.
*** 测试用例1 teardown ****
测试1                                                                 | PASS |
------------------------------------------------------------------------------
测试2
--- Test little Default Setup ---
.测试用例2 主体部分
.
--- Test little Default Teardown ---
测试2                                                                 | PASS |
------------------------------------------------------------------------------

--- Suite little Teardown ---
Suite1.St1                                                            | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================
Suite1.St2
==============================================================================
测试3
*** 测试用例3 setup ****
.测试用例3主体部分
.
*** 测试用例3 teardown ****
测试3                                                                 | PASS |
------------------------------------------------------------------------------
测试4
--- Test big Default Setup ---
.测试用例4主体部分
.
--- Test big Default Teardown ---
测试4                                                                 | PASS |
------------------------------------------------------------------------------
Suite1.St2                                                            | PASS |
2 critical tests, 2 passed, 0 failed
2 tests total, 2 passed, 0 failed
==============================================================================

--- Suite big Teardown ---
Suite1                                                                | PASS |
4 critical tests, 4 passed, 0 failed
4 tests total, 4 passed, 0 failed
==============================================================================
Output:  E:\tmp\rf1\output.xml
Log:     E:\tmp\rf1\log.html
Report:  E:\tmp\rf1\report.html

E:\tmp\rf1>

suite1 有两个测试用例的文件 st1st2 对应的测试用例测试1,测试2,测试3,测试4,4个测试文件 ,看下执行的结果:首先进入 suite1的话他会先执行__init__里面的 Suite Setup log to console |n---Suite big Setup ---Suite Teardown log to console |n--- Suite big Teardown ---我们整个测试套件执行最外层开头和结尾就应该是|n---Suite big Setup ---|n--- Suite big Teardown ---

接下来进来之后会执行两个测试套件的文件,一个是 st1 一个是 st2 ,进入st1 的时候要执行测试用例1之前,他是不是有Suite Setup log to console |n ---Suite little Setup --- Suite Teardown log to console |n --- Suite little Teardown ---这个 Suite Setup/Teard 是不是要包在测试用例1和测试用例2外面,因为我前面的Setup是在最外层,这个里面的应该包在12外面,应该会有---Suite little Setup ------ Suite little Teardown ---包在测试1测试2之间
这个是包在用例12外面的

Robot Framework 初始化与清除_第8张图片
image.png

执行完这个 Setup 之后他才执行自己内部的 setupteardow 首先用例1又有自己的|n *** 测试用例1 setup ***|n *** 测试用例1 Teardown ***那么我们用例1在执行主体之前,大家看下主体部分的上和下分别有个测试用例1的|n *** 测试用例1 setup ***|n *** 测试用例1 Teardown ***

Robot Framework 初始化与清除_第9张图片
image.png

测试用例2没有 steupTeardown 那它是用

Robot Framework 初始化与清除_第10张图片
image.png

st1.robot 中的 Setup teardown 还是

Robot Framework 初始化与清除_第11张图片
image.png

__init__中的Setup teardown,应该用离它近的大家记住就近原则,所以测试2应该包在两边的是|n --- Test little Default Setup ---|n --- Test little Default Teardown ---

Robot Framework 初始化与清除_第12张图片
image.png

这是测试用例1和2//,接下来看一下 st2.robot 里面没有 SetupTeardown,但是测试3有自己的SetupTeardown所以3**的外面应该包着\n *** 测试用例3 setup ***\n *** 测试用例3 teardown ***

Robot Framework 初始化与清除_第13张图片
image.png

接着看用例4自己没有SetupTeardown他所在的st2文件也没有SetupTeardown,他就用到了最外层的|n--- Test big Default Setup ---|n--- Test big Default Teardown ---

Robot Framework 初始化与清除_第14张图片
image.png

我们把suite1里面的4个测试用例SetupTeardown.的顺序过了一遍,从过的顺序我们了解他们遵循的一个原则由内向外优先级递减,如果自己有的话就尽量用自己的,没有的话就往上找

总结:
我们__init_里面的Suite Setup Teardown他只执行一次Test Setup Teardown是根据需要的,如果他没有的话就会被多次复用,如果每个本身都有的话他可能一次都不会被用到,Test Setup Teardown每个用例如果没有自己Default (缺省)就会用Test Setup Teardown,如果没个用例都有就不会用到Test Setup Teardown被用的次数是不固定的。

刚才我们执行用例用的命令是:

robot suite1

执行了整个suite1如果我们只想执行其中的一个套件,比如我就想执行suite1st1.robot该怎么执行呢,这样写是不行的

robot suite1\st1.robot

虽然我运行也是执行了,

Robot Framework 初始化与清除_第15张图片
image.png

执行之后我们看下他的 log,最上层的log是 |n ---Suite little Setup ---开始的, |n ---Suite little Setup ---是在 st1Suite Setup但是他最上层的 __init__没有执行,因为我直接就进入到 st1去执行了,这种情况下比如说我最上层有一些初始化可能就走不到了,这样是不行的因为 robot关注的是路径的最后部分,这里如果想要执行应该这样写我们要执行那个 suite--suite比如 st1我们最终是 suite1里面的,就是

robot --suite st1 suite1

这样就执行到了:


Robot Framework 初始化与清除_第16张图片
image.png

这个参数是告诉robot目标参数是 suite1 里面挑了一个 st1,是这种目的

如果有多个套件要执行就是

`robot --suite st1 --suite st2 suite1

这样四个用例就都执行了。

--suite指定的就是执行的是那个子套件,如果我就只要执行测试用例1就这样写

robot --test 测试1 suite1

表示:robot suite1 里面的某一个测试用例

你可能感兴趣的:(Robot Framework 初始化与清除)