草庐IT

python - Pytest 在哪里存储预期数据

coder 2023-05-24 原文

测试函数我需要传递参数并查看输出是否与预期输出匹配。

当函数的响应只是一个可以在测试函数内部定义的小数组或单行字符串时,这很容易,但假设我测试的函数修改了一个可能很大的配置文件。或者,如果我明确定义它,结果数组是 4 行长。我在哪里存储它,以便我的测试保持干净且易于维护?

现在,如果那是字符串,我只需在 .py 测试附近放置一个文件,然后在测试中执行 open() :

def test_if_it_works():
    with open('expected_asnwer_from_some_function.txt') as res_file:
        expected_data = res_file.read()
    input_data = ... # Maybe loaded from a file as well
    assert expected_data == if_it_works(input_data)

我发现这种方法存在许多问题,例如保持此文件为最新的问题。它看起来也很糟糕。 我可以让事情变得更好,把它移到固定装置上:

@pytest.fixture
def expected_data()
    with open('expected_asnwer_from_some_function.txt') as res_file:
        expected_data = res_file.read()
    return expected_data

@pytest.fixture
def input_data()
    return '1,2,3,4'

def test_if_it_works(input_data, expected_data):
    assert expected_data == if_it_works(input_data)

这只是将问题转移到另一个地方,通常我需要测试在空输入、单个项目或多个项目输入的情况下功能是否有效,因此我应该创建一个包含所有三个案例或多个 fixture 的大 fixture 。最后代码变得相当困惑。

如果一个函数需要一个复杂的字典作为输入,或者返回同样庞大的字典,测试代码就会变得丑陋:

 @pytest.fixture
 def input_data():
     # It's just an example
     return {['one_value': 3, 'one_value': 3, 'one_value': 3,
     'anotherky': 3, 'somedata': 'somestring'], 
      ['login': 3, 'ip_address': 32, 'value': 53, 
      'one_value': 3], ['one_vae': 3, 'password': 13, 'lue': 3]}

很难阅读使用此类固定装置的测试并使其保持最新状态。

更新

搜索了一段时间后,我发现一个库解决了部分问题,而不是大型配置文件,我有大型 HTML 响应。它是 betamax .

为了方便使用,我创建了一个 fixture :

from betamax import Betamax

@pytest.fixture
def session(request):
    session = requests.Session()
    recorder = Betamax(session)
    recorder.use_cassette(os.path.join(os.path.dirname(__file__), 'fixtures', request.function.__name__)
    recorder.start()
    request.addfinalizer(recorder.stop)
    return session

所以现在在我的测试中,我只使用 session fixture ,我发出的每个请求都会自动序列化到 fixtures/test_name.json 文件中,所以下次我执行测试而不是做一个真正的 HTTP 请求库从文件系统加载它:

def test_if_response_is_ok(session):
   r = session.get("http://google.com")

这非常方便,因为为了使这些装置保持最新状态,我只需要清理 fixtures 文件夹并重新运行我的测试。

最佳答案

我曾经遇到过类似的问题,我必须根据预期文件测试配置文件。我就是这样解决的:

  1. 在相同位置创建一个与您的测试模块同名的文件夹。将所有预期的文件放入该文件夹中。

    test_foo/
        expected_config_1.ini
        expected_config_2.ini
    test_foo.py
    
  2. 创建一个 fixture ,负责将该文件夹的内容移动到一个临时文件中。我确实使用了 tmpdir 固定装置。

    from __future__ import unicode_literals
    from distutils import dir_util
    from pytest import fixture
    import os
    
    
    @fixture
    def datadir(tmpdir, request):
        '''
        Fixture responsible for searching a folder with the same name of test
        module and, if available, moving all contents to a temporary directory so
        tests can use them freely.
        '''
        filename = request.module.__file__
        test_dir, _ = os.path.splitext(filename)
    
        if os.path.isdir(test_dir):
            dir_util.copy_tree(test_dir, bytes(tmpdir))
    
        return tmpdir
    

    重要提示:如果您使用的是 Python 3,请将 dir_util.copy_tree(test_dir, bytes(tmpdir)) 替换为 dir_util.copy_tree(test_dir, str( tmpdir)).

  3. 使用你的新 fixture 。

    def test_foo(datadir):
        expected_config_1 = datadir.join('expected_config_1.ini')
        expected_config_2 = datadir.join('expected_config_2.ini')
    

请记住:datadirtmpdir fixture 相同,此外还可以处理放置在名为 test 模块的文件夹中的预期文件。

关于python - Pytest 在哪里存储预期数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29627341/

有关python - Pytest 在哪里存储预期数据的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  4. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  5. ruby-on-rails - ruby 日期方程不返回预期的真值 - 2

    为什么以下不同?Time.now.end_of_day==Time.now.end_of_day-0.days#falseTime.now.end_of_day.to_s==Time.now.end_of_day-0.days.to_s#true 最佳答案 因为纳秒数不同:ruby-1.9.2-p180:014>(Time.now.end_of_day-0.days).nsec=>999999000ruby-1.9.2-p180:015>Time.now.end_of_day.nsec=>999999998

  6. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  7. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  10. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

随机推荐