编写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. JackSon解析json字符串

    JackSon解析json字符串 原文:http://blog.csdn.net/java_huashan/article/details/9353903 概述 jackson解析json例子 准备工 ...

  2. 如意云路由刷PandoraBox

    目录 1 准备固件 2 使用uboot刷机 2.1 修改IP 2.2 开始刷写 3 ssh登录 4 刷回如意云 准备固件 http://downloads.openwrt.org.cn/Pandora ...

  3. JAVA面试-HIBERNATE与 MYBATIS的对比

    JAVA面试中问及HIBERNATE与 MYBATIS的对比,在这里做一下总结   我是一名java开发人员,hibernate以及mybatis都有过学习,在java面试中也被提及问道过,在项目实践 ...

  4. Windows 安装、重装MySQL时,报错:could not start the service mysql

    原因: 卸载mysql时并没有完全删除相关文件和服务,需要手动清除. 解决方法: 首先,在管理工具->服务里面将MySQL的服务给停止(有的是没有安装成功,有这个服务,但是已经停止了的). 然后 ...

  5. Spring Cloud体系介绍

    上图只是Spring Cloud体系的一部分,Spring Cloud共集成了19个子项目,里面都包含一个或者多个第三方的组件或者框架! Spring Cloud 工具框架 1.Spring Clou ...

  6. media wiki run on nginx

    1. 环境安装: nginx安装 nginx-1.5.7 php安装 PHP 5.4.10 (cli) (built: Jul 30 2014 16:45:08) mysql安装 Ver 14.14 ...

  7. (转)session、cookie与“记住我的登录状态”的功能的实现

    Cookie的机制 Cookie是浏览器(User Agent)访问一些网站后,这些网站存放在客户端的一组数据,用于使网站等跟踪用户,实现用户自定义功能. Cookie的Domain和Path属性标识 ...

  8. Excel随机生成数据

    CONCATENATE函数是一个文本连接函数,非常简单,和&的效果一样. CONCATENATE是一个文本连接函数 语法:CONCATENATE(text1,text2,text3...... ...

  9. 【翻译】Webpack 4 从0配置到生产模式

    查看原文 webpack 4 发布了! webpack 4 作为一个零配置的模块打包器 webpack 是强大的并且有许多独一无二的特点但是有一个痛点就是配置文件. 在中型到大型项目中为webpack ...

  10. Fragment之间传数据

    1.用bundle存Bundle bundle = new Bundle();bundle.putString("cid1", classList.get(i).getId()); ...