编写Avocado测试

现在我们开始使用python编写Avocado测试,测试继承于avocado.Test.

基本例子

创建一个时间测试,sleeptest,测试非常简单,只是sleep一会:

import time
from avocado import Test class SleepTest(Test): def test(self):
sleep_length = self.params.get('sleep_length', default=1)
self.log.debug("Sleep for %.2f seconds", sleep_length)
time sleep(sleep_length)

这是为avocado编写的一个简单示例,可以使用其他power API编写。

从上面的例子可以看出,avocado测试从avocado.Test继承的test方法入手。

多个测试和命名约定

可以在一个类中存在多个测试。

要想做多个测试,只需要在命名方法前加test,例如test_foo,test_bar等。建议遵守这个命名风格,就像PEP8 Function Names.

对于class名称,可以任意命名,当最好还是遵从CamelCase命名,参考PEP8 中Class Names

方便属性

测试类提供了一定数量的方便属性:

  • 为测试添加测试log,可以使用self.log.可以定义log debug,info,error和warning信息。
  • 参数解析系统,可以访问self.parms使用。可以在后面的Test variants - Mux文章查看更多信息。

保存生成的数据

每个测试都提供一个所谓的whiteboard,可以通过self.whiteboard访问。Witeboard是一个可以自动保存到测试结果(可以支持的output格式)字符串。你同样可以选择保存二进制数据到whiteboard,但你需要先进行编码转换(base64).

基于上面的sleeptest,假设想保存sleep_length用于其他脚本或数据分析工具:

def test(self):
sleep_length = self.params.get('sleep_length', default=1)
self.log.debug("Sleeping for %.2f second", sleep_length)
time.sleep(sleep_length)
slef.writeboard = "%.2f" % sleep_length

whiteboard可以并应当接收由可用的测试结果插件生成的文件。Result.json文件已经为每个测试包含了whiteboard.此外,会用一个命名为whiteboard的文件保存和results.json相同级别的信息(也许你想使用与你定制的脚本配套的结果处理工具,该文件会保存白板内容的原始副本)。

访问测试参数

每个测试都有一组可以通过self.params.get($name, $path=None, $default=None)访问的参数.Avocado会从Multiplex 配置文件中发现所有参数并填充到self.params.比如上面的例子,sleeptest的multiplex文件:

sleeptest:
type: "builtin"
length: !Mux
short:
sleep_length: 0.5
medium:
sleep_length: 1
long:
sleep_length: 5

当我们用avocado run $test --mux-yaml $file.yaml运行这个例子,3个variants会执行并且内容会插入/run的命名空间。每个variant包含变量的“type"和"sleep_length"。要获取有效值,需要名称(”sleep_length)和path。需要选择路径 ,在这个例子:/run/sleeptest/length/或sleeptest/,取决于如何设置。

默认的参数是可选的,但是要处理好这部分。可能有人运行你的测试时选择不同的参数或没有参数,它仍然能够很好的运行。

所以关于如何访问"sleep_length"的完整示例:

self.params.get("sleep_length", "/*/sleeptest/*", 1)

还有一种更简单的方式。它用于定义解析顺序,简单的查询可以简单的指定路径:

self.params.get("sleep_length", None, 1)
self.params.get("sleep_length", '*', 1)
self.params.get("sleep_length", default=1)

应该避免参数冲突(不同的匹配值应该指定不同的路径)。如果不能这样(例如使用复合yaml文件)可以通过 --mux-path进行默认路径的修改。它将对参数和操作通过路径进行一个接一个的切片。当第一个切片匹配后会返回,不再尝试其他切片。虽然相对查询只匹配来自--mux-path的切片。

有很多方式使用paths分离存在冲突的params或只是使查询更清晰。通常tests中使用"*"就足够了,namespacing不是必须的,但是有助于高级用法更清晰简单。

关于路径的考虑基本是从用户角度。更多信息参考The variants-Mux

使用multplex文件

Avocado可以使用multplex文件提供params和生成generation来运行sleeptest:

$ avocado run sleeptest.py --mux-yaml examples/tests/sleeptest.py.date/sleeptest.yaml
JOB ID : d565e8dec576d6040f894841f32a836c751f968f
JOB LOG : $HOME/avocado/job-results/job-2014-08-12T15.44-d565e8de/job.log
TESTS : 3
(1/3) sleeptest.py:SleepTest.test;1: PASS (0.50 s)
(2/3) sleeptest.py:SleepTest.test;2: PASS (1.00 s)
(3/3) sleeptest.py:SleepTest.test;3: PASS (5.00 s)
RESULTS : PASS 3 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0
TESTS TIME : 6.50 s
JOB HTML : $HOME/avocado/job-results/job-2014-08-12T15.44-d565e8de/html/results.html

The --mux-yaml accepts either only \(FILE_LOCATION or $INJECT_TO:\)FILE_LOCATION. As explained in Test variants - Mux without any path the content gets injected into /run in order to be in the default relative path location.
The \(INJECT_TO can be either relative path, then it’s injected into /run/\)INJECT_TO location, or absolute path (starting with '/'), then it’s injected directly into the specified path and it’s up to the test/framework developer
to get the value from this location (using path or adding the path to mux-path). To understand the difference execute those commands:

$ avocado multiplex -t -m examples/tests/sleeptest.py.data/sleeptest.yaml
$ avocado multiplex -t -m duration:examples/tests/sleeptest.py.data/sleeptest.yaml
$ avocado multiplex -t -m /my/location:examples/tests/sleeptest.pt.data/sleeptest.yaml

注意,因为multiplex文件为sleeptest指定了所有参数,所以不能将ID留空:

$ scripts/avocado run --mux-yaml examples/tests/sleeptest/sleeptest.yaml
Empty test ID. A test path or alias must be provided

可以使用同一个multiplex文件启动多个测试:

$avocado run sleeptest.py synctest.py --mux-yaml examples/tests/sleeptest.py.data/sleeptest.yaml

JOB ID     : cd20fc8d1714da6d4791c19322374686da68c45c
JOB LOG : $HOME/avocado/job-results/job-2016-05-04T09.25-cd20fc8/job.log
TESTS : 8
(1/8) sleeptest.py:SleepTest.test;1: PASS (0.50 s)
(2/8) sleeptest.py:SleepTest.test;2: PASS (1.00 s)
(3/8) sleeptest.py:SleepTest.test;3: PASS (5.01 s)
(4/8) sleeptest.py:SleepTest.test;4: PASS (10.00 s)
(5/8) synctest.py:SyncTest.test;1: PASS (2.38 s)
(6/8) synctest.py:SyncTest.test;2: PASS (2.47 s)
(7/8) synctest.py:SyncTest.test;3: PASS (2.46 s)
(8/8) synctest.py:SyncTest.test;4: PASS (2.45 s)
RESULTS : PASS 8 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0
TESTS TIME : 26.26 s
JOB HTML : $HOME/avocado/job-results/job-2016-05-04T09.25-cd20fc8/html/results.html

高级日志功能

Avocado 在测试的同时提供高级日志功能。这些可以和标准python API库组合。

一个常见的例子是需要在更长或更复杂的测试中遵循具体的进展。 让我们看一个非常简单的测试示例,但在单个测试中有一个多个明确的阶段:

import logging
import time from avocado import Test progress_log = logging.getLogger("progress" class Plant(Test): def test_plant_organic(self):
rows = self.params.get("rows", default=3) #Preparing soil
for row in range(rows):
progress_log.info("%s: Preparing soil on row %s",
self.name, row) # Letting soil rest
progress_log.info("%s: letting soil rest before throwing seeds",
self.name) time.sleep(2) # Throwing seeds
for row in range(rows):
progress_log.info("%s: throwing seeds on row %s",
self.name, row) # Let them grow
progress_log.info("%s: waiting for Avocados to grow",
self.name)
time.sleep(5) # Harvest them
for row in range(rows):
progress_log.info("%s: harvesting organic avocados on row %s",
self.name, row)

这时,可以请求avocaod显示你的日志流,独占或则加入其他内建流:

$ avocado --show app, progress run plant.py

结果类似于:

JOB ID     : af786f86db530bff26cd6a92c36e99bedcdca95b
JOB LOG : /home/cleber/avocado/job-results/job-2016-03-18T10.29-af786f8/job.log
TESTS : 1
(1/1) plant.py:Plant.test_plant_organic: progress: 1-plant.py:Plant.test_plant_organic: preparing soil on row 0
progress: 1-plant.py:Plant.test_plant_organic: preparing soil on row 1
progress: 1-plant.py:Plant.test_plant_organic: preparing soil on row 2
progress: 1-plant.py:Plant.test_plant_organic: letting soil rest before throwing seeds
-progress: 1-plant.py:Plant.test_plant_organic: throwing seeds on row 0
progress: 1-plant.py:Plant.test_plant_organic: throwing seeds on row 1
progress: 1-plant.py:Plant.test_plant_organic: throwing seeds on row 2
progress: 1-plant.py:Plant.test_plant_organic: waiting for Avocados to grow
\progress: 1-plant.py:Plant.test_plant_organic: harvesting organic avocados on row 0
progress: 1-plant.py:Plant.test_plant_organic: harvesting organic avocados on row 1
progress: 1-plant.py:Plant.test_plant_organic: harvesting organic avocados on row 2
PASS (7.01 s)
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0
TESTS TIME : 7.01 s
JOB HTML : /home/cleber/avocado/job-results/job-2016-03-18T10.29-af786f8/html/results.html

自定义的progress流和app输出混合在一起,可能不太适合。如果想让progress流输入到一个独立文件,这样会清晰。

$ avocado run plant.py --store-loggin-stream progress

这样,除了所有其他日志文件通常生成,会有另一个名为日志文件progress.INFO在作业结果目录。 在测试运行期间,可以观察进度:

$ tail -f ~/avocado/job-results/latest/progress.INFO

10:36:59 INFO | 1-plant.py:Plant.test_plant_organic: preparing soil on row 0
10:36:59 INFO | 1-plant.py:Plant.test_plant_organic: preparing soil on row 1
10:36:59 INFO | 1-plant.py:Plant.test_plant_organic: preparing soil on row 2
10:36:59 INFO | 1-plant.py:Plant.test_plant_organic: letting soil rest before throwing seeds
10:37:01 INFO | 1-plant.py:Plant.test_plant_organic: throwing seeds on row 0
10:37:01 INFO | 1-plant.py:Plant.test_plant_organic: throwing seeds on row 1
10:37:01 INFO | 1-plant.py:Plant.test_plant_organic: throwing seeds on row 2
10:37:01 INFO | 1-plant.py:Plant.test_plant_organic: waiting for Avocados to grow
10:37:06 INFO | 1-plant.py:Plant.test_plant_organic: harvesting organic avocados on row 0
10:37:06 INFO | 1-plant.py:Plant.test_plant_organic: harvesting organic avocados on row 1
10:37:06 INFO | 1-plant.py:Plant.test_plant_organic: harvesting organic avocados on row 2

同一个progress日志记录器,可以在多个测试方法和在多个测试模块一起使用。 在给出的示例中,测试名称用于给出额外的上下文。

编写Avocado测试的更多相关文章

  1. 新书《编写可测试的JavaScript代码 》出版,感谢支持

    本书介绍 JavaScript专业开发人员必须具备的一个技能是能够编写可测试的代码.不管是创建新应用程序,还是重写遗留代码,本书都将向你展示如何为客户端和服务器编写和维护可测试的JavaScript代 ...

  2. 编写可测试的JavaScript代码

    <编写可测试的JavaScript代码>基本信息作者: [美] Mark Ethan Trostler 托斯勒 著 译者: 徐涛出版社:人民邮电出版社ISBN:9787115373373上 ...

  3. 使用FsCheck编写Property-based测试

    使用FsCheck编写Property-based的测试 在编写基于Property-based的单元测试一文中,我们介绍了什么是Property-based测试.同时我们也总结了Property-b ...

  4. springboot快速入门02--Controller编写和测试

    02springboot快速入门--Controller编写和测试 1.新建一个HelloController import org.springframework.boot.SpringApplic ...

  5. Shell脚本的编写及测试

                                                      Shell脚本的编写及测试 1.1问题 本例要求两个简单的Shell脚本程序,任务目标如下: 编写一 ...

  6. 098 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 02 编写并测试Subject类

    098 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 02 编写并测试Subject类 本文知识点:编写并测试Subject类 说明: ...

  7. 099 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 03 编写并测试Student类

    099 01 Android 零基础入门 02 Java面向对象 03 综合案例(学生信息管理) 02 案例分析及实现 03 编写并测试Student类 本文知识点:编写并测试Subject类 说明: ...

  8. #使用C#winform编写渗透测试工具--子域名挖掘

    使用C#winform编写渗透测试工具--子域名挖掘 这篇文章主要介绍使用C#winform编写渗透测试工具--子域名挖掘.在渗透测试中,子域名的收集十分重要,通常一个网站的主站的防御能力特别强,而他 ...

  9. 使用C#winform编写渗透测试工具--暴力破解

    使用C#winform编写渗透测试工具--暴力破解 这篇文章主要介绍使用C#winform编写渗透测试工具--暴力破解.暴力破解是指通过利用大量猜测和穷举的方式来尝试获取用户口令的攻击方式.简单来说就 ...

随机推荐

  1. Nginx + Lua + 共享内存

    转自:http://blog.csdn.net/lxb_champagne/article/details/17099383 lua_package_path "/usr/local/sha ...

  2. GAN 生成mnist数据

    参考资料 GAN原理学习笔记 生成式对抗网络GAN汇总 GAN的理解与TensorFlow的实现 TensorFlow小试牛刀(2):GAN生成手写数字 参考代码之一 #coding=utf-8 #h ...

  3. 新型智能芯片nxp----嗯质朴

    公司omap 用到nxp的qx 操作系统   由飞利浦公司创立,已拥有五十年的悠久历史,主要提供工程师与设计人员各种半导体产品与软件,为移动通信.消费类电子.安全应用.非接触式付费与连线,以及车内娱乐 ...

  4. YII2与Thinkphp整合阿里云OSS

    前言: 如果上传的文件都和网站程序源代码放在一起:那是有相当多的弊端的: 1:静态文件会占用大量带宽: 2:服务器的成本略高: 常规的做法是把php源代码放到一台服务器上:图片等静态文件放在另一台服务 ...

  5. LoadRunner压力测试心得总结

    一.虚拟用户迭代一次的时间对整个压力场景的影响. 1.虚拟用户迭代一次的时间大于等于压力场景的上行周期. 此种情况,在压力场景的上行周期中,所有虚拟用户根据压力场景设置的策略全部依次运行.压力场景的上 ...

  6. 查看linux系统外网ip命令

    终端中输入 curl ipinfo.io 或者 curl ifconfig.me 即可通过IP地址检测网站提供的api获得取本机的外网IP,或者以 JSON 格式返回全部结果.

  7. ASP.NET MVC - The view must derive from WebViewPage, or WebViewPage<TModel>

    当通过一个空的站点构建ASP.NET MVC时经常会出现各种配置缺少的问题,最简单但的办法是吧VS自动生成的web.config文件拷贝到对应的目录下面 The view must derive fr ...

  8. iOS面试题--网络--如何处理多个网络请求的并发的情况

    如何处理多个网络请求的并发的情况 一.概念 1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配 ...

  9. Linux GCC编译使用动态、静态链接库 (转)

    原文出处:http://blog.csdn.net/a600423444/article/details/7206015 在windows下动态链接库是以.dll后缀的文件,二在Linux中,是以.s ...

  10. ios开发之 -- 单例类

    单例模式是一种软件设计模式,再它的核心结构中指包含一个被称为单例类的特殊类. 通过单例模式可以保证系统中一个类只有一个势力而且该势力易于外界访问,从而方便对势力个数的控制并节约系统资源.如果希望在系统 ...