【问题标题】:How to parametrize a parametrized function in pytest?如何在pytest中参数化参数化函数?
【发布时间】:2023-02-21 00:32:30
【问题描述】:

我有以下 pytest 函数,其中 GAMES_AVAILABLE 是我希望我的代码测试的不同游戏的动态列表。

@pytest.mark.parametrize("game_ref", GAMES_AVAILABLE)
def test_all_games(game_ref):
    game_components = build_game_components(game_ref)
    available_players = determine_available_players(game_components)
    teams = create_player_teams(game_components['game'].number_of_players,available_players)
    for players in teams:
        if 'viz' in game_components:
            arena = Arena(players, game_components['game'], game_components['viz'])
        else:
            arena = Arena(players, game_components['game'])
        arena.playGames(2)
    return teams

输出如下

Testing started at 4:20 p.m. ...
Connected to pydev debugger (build 223.8617.48)
Launching pytest with arguments /home/tue/PycharmProjects/Hive_nn/tests/test_all_games.py --no-header --no-summary -q in /home/tue/PycharmProjects/Hive_nn/tests

============================= test session starts ==============================
collecting ... collected 3 items

test_all_games.py::test_all_games[game_ref0] 
test_all_games.py::test_all_games[game_ref1] 
test_all_games.py::test_all_games[game_ref2] 

======================== 3 passed, 3 warnings in 7.56s =========================

Process finished with exit code 0

就目前而言,我的代码以游戏可以玩的所有可能配置来玩每个游戏,这是动态完成的,具体取决于为特定游戏实现的功能。

现在我的代码为每场比赛生成一个测试,但是我希望它在每场比赛中为每个团队生成一个测试然后运行:

    if 'viz' in game_components:
        arena = Arena(players, game_components['game'], game_components['viz'])
    else:
        arena = Arena(players, game_components['game'])
    arena.playGames(2)

在这些新的子测试中。

但我不确定该怎么做?

此外,我对单元测试还很陌生,所以如果我的代码中有些东西看起来很奇怪或愚蠢,那可能是这样,我将不胜感激任何关于改进之处的反馈:)

【问题讨论】:

    标签: python unit-testing pytest


    【解决方案1】:

    只需动态生成参数列表:

    def team_games():
      for game_ref in GAMES_AVAILABLE:
        game_components = build_game_components(game_ref)
        available_players = determine_available_players(game_components)
        teams = create_player_teams(game_components['game'].number_of_players,available_players)
        for players in teams:
          # this can be simplified via get method if game_components is just a dict
          viz = game_components['viz'] if 'viz' in game_components else None
          yield players, game_components['game'], viz
          
    @pytest.mark.parametrize("players,game,viz", team_games())
    def test_all_games(players, game, viz):
      if viz:
        arena = Arena(players, game, viz)
      else:
        arena = Arena(players, game)
      arena.playGames(2)
    

    您甚至可以将完整的竞技场作为参数列表。为此,请修改team_games 函数,使其生成的不是元组,而是 Arena-s 对象。

    【讨论】:

    • 注意:此方法的一个缺点是生成有些静态并且在导入时完成,因此可能难以使用运行时信息或依赖于配置文件或命令行参数的信息进行配置。然而 pytest 也有一个 pytest_generate_tests 钩子,虽然不那么性感和方便,但更加灵活。
    猜你喜欢
    • 1970-01-01
    • 2023-02-19
    • 2016-12-25
    • 2023-03-03
    • 1970-01-01
    • 2016-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多