2016-11-26 39 views
1

使用pytest,我试图测试一个像分层场景的树。 允许使用文档的结构的例子:pytest树状数据嵌套参数化

Document --- Chapter --- Paragraph 
     1 n  1 n 

凡文档包含多个章节;一章包含多个段落。

当开始测试新文档时,需要运行一些设置代码;当新章节开始时,需要运行其他一些设置代码;段落也一样。

写成伪代码:

for doc in documents: 
    setup_doc(doc) 
    for chapter in doc.chapters: 
     setup_chapter(chapter) 
     for paragraph in chapter.paragraphs: 
      setup_paragraph(paragraph) 
      test_it(doc, chapter, paragraph) 
      teardown_paragraph(paragraph) 
     teardown_chapter(chapter) 
    teardown_doc(doc) 

如果我们有如下的数据:

Document Alpha 
    chapter A 
     Paragraph A1 
     Paragraph A2 
    chapter B 
     Paragraph B1 

我希望收集到的测试案例是:

test_it[Alpha, A, A1] 
test_it[Alpha, A, A2] 
test_it[Alpha, B, B1] 

我已经尝试了pytest_generate_tests,类场景,灯具和参数化测试函数的不同组合,但没有b能够实现这一点。

任何指针将不胜感激。

回答

0

Pytest fixutes应该是独立的。 所以要解决你的任务,你必须建立一个与所有功能组合(文档 - 章 - 段)的清单一个夹具。

你可以用简单的工具来做到这一点,该工具返回这样一个列表的一个元素,或者你可以在测试生成阶段生成这个列表,如下面的代码所示。

documents = { 
     'Alpha': { 
      'A': {'A1': {},'A2': {}}, 
      'B': {'B1': {}} 
     } 
    } 


def pytest_generate_tests(metafunc): 
    """Documents tree from documents""" 
    if 'document' in metafunc.fixturenames: 
     documents_plain = [] 
     for document in documents.keys(): 
      for chapter in documents[document].keys(): 
       for paragraph in documents[document][chapter].keys(): 
        documents_plain.append({'document': document, 'chapter': chapter, 'paragraph': paragraph}) 
     metafunc.parametrize(
      'document', 
      documents_plain, 
      scope='session') 


def test_it(document): 
    print('{}, {}, {}'.format(document['document'], document['chapter'], document['paragraph'])) 


py.test -s 

Alpha, B, B1 
Alpha, A, A1 
Alpha, A, A2 
0

如果像我一样,你想通过documentdocument,一些参数化的documentchapter还有一些一些测试,chapterparagraph我的方法(安德烈·索罗金的启发)如下。

conftest.py

import pytest 

documents = { 
    'Alpha': { 
     'A': {'A1': {},'A2': {}}, 
     'B': {'B1': {}} 
    } 
} 

def pytest_generate_tests(metafunc): 
    if 'document' in metafunc.fixturenames: 
     if 'chapter' in metafunc.fixturenames: 
      if 'paragraph' in metafunc.fixturenames: 
       metafunc.parametrize(
        ['document', 'chapter', 'paragraph'], 
        [(d, c, p) for d, cs in documents.items() 
           for c, ps in cs.items() 
           for p in ps.keys() 
        ]) 
      else: 
       metafunc.parametrize(
        ['document', 'chapter'], 
        [(d, c) for d, cs in documents.items() 
          for c in cs.keys() 
        ]) 
     else: 
      metafunc.parametrize(
        'document', documents.keys()) 

然后在test.py

def test_d(document): 
    print(document) 

def test_dc(document, chapter): 
    print(document, chapter) 

def test_dcp(document, chapter, paragraph): 
    print(document, chapter, paragraph) 

运行

>>> pytest test.py -s 
test.py Alpha 
.Alpha A 
.Alpha B 
.Alpha A A2 
.Alpha A A1 
.Alpha B B1 
.