当前位置: 首页 > 工具软件 > Avocado > 使用案例 >

Avocado使用手册(2) --编写脚本部分 (For Big Cloud Enterprise Linux 7.2)

陈博容
2023-12-01

1. 基本的列子

很简单的sleeptest,除了睡一会,啥都不做。

import time

from avocado import Test

class SleepTest(Test):

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

这是您可以为Avocado编写的最简单的测试,同时仍然可以利用其API功能。

1.1什么是avocado

从《Avocado使用手册(1) --环境安装部分》中的示例中可以看出,Avocado测试是一种从test继承自的类开始的方法avocado.Test。

1.2 多个测试和命名约定

您可以在一个类中进行多个测试。

要做到这一点,只是给这样开始的方法的名称test,比如说 test_foo,test_bar等等。我们建议您遵循此命名样式,如PEP8函数名称部分中所定义。

对于类名,您可以选择任何您喜欢的名称,但我们也建议它遵循CamelCase约定,也称为CapWords,在类名称下的PEP 8文档中定义。

1.3 便利的属性

请注意,测试类为您提供了许多便利属性:

  • 一个随时可用的测试日志机制,可通过以下方式访问self.log。它允许您记录调试,信息,错误和警告消息。
  • 可通过以下方式访问的参数传递系统(和提取系统)self.params。这与Varianter有关,您可以在Testary参数中找到更多信息。
  • 还有更多(见avocado.core.test.Test

为了最大限度地减少意外冲突,我们将公共冲突定义为属性,因此如果您看到像double 这样的东西,则不会覆盖这些冲突。AttributeError: can’t set attribute

2. 测试状态

Avocado支持最常见的退出状态:

  • PASS - 测试通过,没有未经处理的例外情况
  • WARN- 一种变体PASS可以跟踪最终不会影响测试结果的值得注意的事件。输出中可能存在一个示例 。它与测试结果无关,除非测试失败,否则意味着该功能可能按预期工作,但有一些条件可能很好审查。(某些结果插件不支持此功能并报告 )soft lockupdmesgPASS
  • SKIP-试验的先决条件并不满足,测试的身体未执行(也没有了它setUp()和tearDown)。
  • CANCEL- 在测试setUp()方法或测试方法期间某处取消了测试tearDown()。该setUp()和tearDown 方法执行。
  • FAIL - 测试未达到预期结果。失败指向测试对象中的(可能的)错误,而不是测试本身。当测试(和它的)执行中断时, 报告ERRORa而不是a FAIL。“
  • ERROR - 这可能(可能)指向测试本身的一个错误,而不是在被测试的主题中。它通常是由未捕获的异常引起的,并且需要彻底探索此类失败并且应该导致测试修改以避免此失败或使用self.fail以及描述测试中的主题如何无法执行它的任务。
  • INTERRUPTED- 此结果无法由测试编写者设置,只有在达到超时或用户CTRL+C在执行此测试时命中时才可以设置 。
  • 其他 - 还有其他一些内部测试状态,但你不应该面对它们。

2.1 测试方法

设置状态的最简单的方法是直接从测试使用self.fail, self.error或self.cancel。

要记住警告,只需写入self.log.warning 记录器即可。这不会中断测试执行,但会记住条件,如果没有失败,则会将测试报告为WARN。

2.2 将错误转化为失败

Python代码上的错误通常以抛出异常的形式发出信号。当Avocado运行测试时,任何未处理的异常都将被视为测试ERROR,而不是作为测试FAIL。

尽管如此,依赖库通常会引发自定义(或内置)异常。这些异常通常会导致 ERROR但如果您确定这是测试对象的奇怪行为,您应该捕获异常并解释self.fail方法中的失败:

try:
    process.run("stress_my_feature")
except process.CmdError as details:
    self.fail("The stress comamnd failed: %s" % details)

如果您的测试复合多次执行并且您无法在其他情况下获得此异常然后预期失败,则可以使用fail_on装饰器简化代码 :

@avocado.fail_on(process.CmdError)
def test(self):
    process.run("first cmd")
    process.run("second cmd")
    process.run("third cmd")

再一次,让您的测试保持最新并区分 FAIL并ERROR在审查测试结果时节省大量时间。

3. 保存测试生成自定义数据

每个测试实例都提供了一个所谓的whiteboard。它可以通过访问self.whiteboard。这个白板只是一个字符串,在测试完成后会自动保存到测试结果中(在执行过程中没有同步,所以当机器或python崩溃时可能不存在,并且应该使用直接io来outputdir获取关键数据) 。如果您选择将二进制数据保存到白板,则您有责任首先对其进行编码(base64是显而易见的选择)。

在之前演示的基础上sleeptest,假设您要保存睡眠长度以供其他一些脚本或数据分析工具使用:

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

白板可以并且应该由可用的测试结果插件生成的文件公开。该results.json文件已包含每个测试的白板。此外,为方便起见,我们会将白板内容的原始副本保存在与文件 whiteboard位于同一级别的results.json文件中(可能您希望直接使用基准测试结果与自定义脚本分析该特定内容)基准结果)。

如果需要附加多个输出文件,也可以使用self.outputdir指向该 $RESULTS/test-results/$TEST_ID/data位置的文件, 并保留用于任意测试结果数据。

4.访问测试数据文件

某些测试可能依赖于测试文件本身外部的数据文件。Avocado提供了一个测试API,可以很容易地访问这些文件:get_data()

对于Avocado测试(即INSTRUMENTED测试),get_data()允许从最多三个源访问测试数据文件:

  • 文件级数据目录:以测试文件命名的目录,但以.data。结尾。对于测试文件/home/user/test.py,文件级数据目录是/home/user/test.py.data/
  • 测试级数据目录:以测试文件和特定测试名称命名的目录。当同一文件的不同测试部分需要不同的数据文件(具有相同或不同名称)时,这些功能非常有用。考虑前面的例子/home/user/test.py,假设它包含两个测试,MyTest.test_foo并且MyTest.test_bar测试级数据目录将分别/home/user/test.py.data/MyTest.test_foo/home/user/test.py.data/MyTest.test_bar/
  • 变量级数据目录:如果在测试执行期间使用变体,则在查找测试数据文件时也将考虑以变体命名的目录。对于测试文件/home/user/test.pytest MyTest.test_foo,使用variant debug-ffff,数据目录路径将是/home/user/test.py.data/MyTest.test_foo/debug-ffff/

–log-test-data-directories
运行测试时,您可以使用这个命令行选项记录将用于特定测试和执行条件的测试数据目录(例如有或没有变体)。在测试日志中查找“测试数据目录”。

注意

以前存在的API avocado.core.test.Test.datadir,用于仅允许基于测试文件位置访问数据目录。此API已被删除。如果由于某种原因,您仍然需要仅基于测试文件位置访问数据目录,则可以使用 。get_data(filename=’’, source=‘file’, must_exist=False)
访问测试参数

5.访问测试参数

每个测试都有一组参数,可以通过以下方式访问 :self.params.get($name, $path=None, $default=None)

  • name - 参数名称(键)
  • path - 查找此参数的位置(未指定时使用mux-path
  • default - 找不到param时返回的内容
    这条路有点棘手。鳄梨使用树来表示参数。在简单的场景中,您不必担心,您将在默认路径中找到所有值,但最终您可能需要签出测试参数以了解详细信息。

假设您的测试收到以下参数(您将在下一节中学习如何执行它们):

$ avocado variants -m examples/tests/sleeptenmin.py.data/sleeptenmin.yaml --variants 2
...
Variant 1:    /run/sleeptenmin/builtin, /run/variants/one_cycle
    /run/sleeptenmin/builtin:sleep_method => builtin
    /run/variants/one_cycle:sleep_cycles  => 1
    /run/variants/one_cycle:sleep_length  => 600
...

在测试中你可以通过以下方式访问这些参数:

self.params.get("sleep_method")    # returns "builtin"
self.params.get("sleep_cycles", '*', 10)    # returns 1
self.params.get("sleep_length", "/*/variants/*"  # returns 600

注意

在可能发生冲突的复杂场景中,该路径很重要,因为当存在多个具有相同键匹配值的值时,鳄梨会引发异常。如上所述,您可以通过使用特定路径或通过定义允许指定解析层次结构的自定义mux-path来避免这些路径。更多细节可以在测试参数中找到。

清理测试环境

要在测试之前/之后执行设置操作,您可以使用setUptearDown方法。tearDown即使在setUp失败时也始终执行该方法,因此不要忘记在早期初始化变量setUp。

测试输出检查和输出记录模式

–output-check-record
如果使用此选项,Avocado会将测试生成的内容存储在标准(POSIX)流中,即STDOUT和 STDERR。根据所选的选项,您最终可能会记录不同的文件(我们称之为“参考文件”):

  • stdout将生成一个以stdout.expected测试过程标准输出流(文件描述符1)中的内容命名的文件
  • stderr将生成一个以stderr.expected测试过程标准错误流(文件描述符2)中的内容命名的文件
  • both将生成一个名为stdout.expected的文件和一个名为的文件stderr.expected
  • combined:将生成一个名为的单个文件output.expected,其中包含来自测试过程标准输出和错误流(文件描述符1和2)的内容
  • none 将明确禁用所有测试生成输出的记录和具有该内容的生成参考文件

参考文件将记录在第一个(最具体的)测试数据目录(访问测试数据文件)中。我们以测试为例synctest.py。在重新查看Avocado源代码时,您可以找到以下参考文件:

examples/tests/synctest.py.data/stderr.expected
examples/tests/synctest.py.data/stdout.expected

从这两个文件中,只有stdout.expected有一些内容:

$ cat examples/tests/synctest.py.data/stdout.expected
PAR : waiting
PASS : sync interrupted

avocado run output_record.sh --output-check-record all

函数调用总结

  • self.fail
  • self.error
  • self.cancel
  • self.log
  • self.params
  • self.outputdir
  • self.whiteboard
  • avocado run plant.py --store-logging-stream progress
  • $ tail -f ~/avocado/job-results/latest/progress.INFO
 类似资料: