编写Avocado测试

编写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日志记录器,可以在多个测试方法和在多个测试模块一起使用。 在给出的示例中,测试名称用于给出额外的上下文。


原文地址:https://www.cnblogs.com/weikunzz/p/6857972.html