Compréhension approfondie du fonctionnement du plugin pytest-repeat

Comme mentionné dans l’article précédent, pytest_repeatcomment la fonction spécifique du plug-in est-elle réalisée ? Je pense qu'après avoir compris le plugin en détail, d'autres plugins tiers peuvent rapidement comprendre son mécanisme de fonctionnement interne. 

pytest_repeatComment implémenter des cas d'utilisation récurrents sans utiliser de plugins

Le moyen le plus stupide, bien sûr, est de courir plusieurs fois, mais ce n'est évidemment pas ce dont nous avons besoin. Dans l'article de revue des décorateurs , nous avons passé en revue les points de connaissances liés aux décorateurs, sachant que les décorateurs peuvent ajouter dynamiquement des fonctions ou modifier le comportement des fonctions sans modifier le code d'origine. Évidemment, on peut ici utiliser des décorateurs pour réaliser des fonctions répétées.

def repeat(nums: int = 2):
  
    def wrapper(func):
​
        @functools.wraps(func)
        def decorator(*args, **kwargs):
            for i in range(nums):
                func(*args, **kwargs)
​
        return decorator
​
    return wrapper

Ce code est facile à comprendre. Il définit un décorateur avec des paramètres personnalisés, indiquant le nombre de fois que la fonction à l'intérieur du décorateur est exécutée. De cette façon, l'utilisation du décorateur sur le cas d'utilisation @repeat()peut atteindre l'objectif d'exécuter le cas d'utilisation à plusieurs reprises. Mais le résultat statistique est toujours 1 cas d'utilisation. Les étudiants qui l'ont utilisé pytest_repeatsavent que ses résultats statistiques sont de multiples cas d'usage ? Comment faire cela, découvrez-le grâce au code source.

pytest_repeatComment réaliser une exécution répétée

Accès direct au code source

Interprétation du code source

def pytest_addoption(parser):
    parser.addoption(
        '--count',
        action='/pytest-dev/pytest-repeat/blob/v0.9.1/store',
        default=1,
        type=int,
        help='Number of times to repeat each test')
​
    parser.addoption(
        '--repeat-scope',
        action='/pytest-dev/pytest-repeat/blob/v0.9.1/store',
        default='function',
        type=str,
        choices=('function', 'class', 'module', 'session'),
        help='Scope for repeating tests')

Ce code définit deux options de ligne de commande :

  • --count: Utilisé pour spécifier le nombre de fois que chaque scénario de test doit être répété. action=storeIndique de stocker la valeur dans l'argument de ligne de commande.
  • --repeat-scope: utilisé pour spécifier la portée des cas de tests répétés, vous pouvez choisir function, ou . La valeur par défaut est . Indique de stocker la valeur dans l'argument de ligne de commande.classmodulesessionfunctionaction=store

Les deux options sont parser.addoptionajoutées à l'analyseur de ligne de commande de pytest via la méthode.

Lors de l'exécution de pytest et de la spécification --countdes paramètres --repeat-scope, pytest-repeatle plugin prendra ces paramètres et générera automatiquement plusieurs instances d'exécution répétées pour le scénario de test.

Par exemple, si vous exécutez la commande suivante :

pytest --count=2 --repeat-scope=function

pytest-repeatLe scénario de test sera automatiquement exécuté deux fois lors de l'exécution du scénario de test test_my_function.


action=storeest argparseun argument dans le module qui spécifie comment la valeur de l'option est gérée lors de l'analyse de la ligne de commande. Plus précisément, action=storecela signifie stocker la valeur de l'option dans un argument de ligne de commande.

Lorsque vous utilisez parser.addoptionla méthode pour ajouter des options à l'analyseur de ligne de commande, en spécifiant action=store, la valeur de l'option sera stockée dans le résultat analysé, qui peut être obtenu via l'attribut correspondant.

Par exemple, lors de l'exécution de la commande pytest, les valeurs des options --countet --repeat-scopespécifiées sont stockées dans les arguments de ligne de commande. Vous pouvez request.config.getoptionaccéder à ces valeurs stockées en utilisant la méthode, par exemple :

def test_example(request):
    count = request.config.getoption('--count') 
    # count = request.config.option.count 这样也能获取
    repeat_scope = request.config.getoption('--repeat-scope')
    # repeat_scope = request.config.option.repeat_scope
    # 使用获取到的值进行后续操作

Dans l'exemple de code ci-dessus, les valeurs de et request.config.getoptionsont obtenues à partir des paramètres de ligne de commande à l'aide de la méthode et sont stockées respectivement dans les variables et .--count--repeat-scopecountrepeat_scope

Résumé : action=storeest argparseun paramètre du module qui spécifie de stocker la valeur de l'option dans l'argument de ligne de commande. Dans pytest, request.config.getoptionles valeurs d'options stockées dans les arguments de ligne de commande peuvent être obtenues à l'aide de la méthode.


def pytest_configure(config):
    config.addinivalue_line(
        'markers',
        'repeat(n): run the given test function `n` times.')

Cette fonction est appelée pendant la phase de configuration de pytest config.addinivalue_line()pour ajouter des indicateurs personnalisés 'repeat(n)'à la liste des indicateurs de pytest en appelant . 'repeat(n)'Les indicateurs peuvent être utilisés pour spécifier le nombre de fois qu'une fonction de test doit être répétée.


@pytest.fixture
def __pytest_repeat_step_number(request):
    marker = request.node.get_closest_marker("repeat")
    count = marker and marker.args[0] or request.config.option.count
    if count > 1:
        try:
            return request.param
        except AttributeError:
            if issubclass(request.cls, TestCase):
                warnings.warn(
                    "Repeating unittest class tests not supported")
            else:
                raise UnexpectedError(
                    "This call couldn't work with pytest-repeat. "
                    "Please consider raising an issue with your usage.")

Cette fonction d'appareil est utilisée pour obtenir le numéro de l'étape de répétition actuelle. Il vérifie d'abord si la fonction de test est 'repeat'décorée d'une balise et obtient le nombre de répétitions de la balise. S'ils ne sont pas signalés, les arguments des arguments de ligne de commande sont utilisés --countpar défaut.


@pytest.hookimpl(trylast=True)
def pytest_generate_tests(metafunc):
    count = metafunc.config.option.count
    m = metafunc.definition.get_closest_marker('repeat')
    if m is not None:
        count = int(m.args[0])
    if count > 1:
        metafunc.fixturenames.append("__pytest_repeat_step_number")
​
        def make_progress_id(i, n=count):
            return '{0}-{1}'.format(i + 1, n)
​
        scope = metafunc.config.option.repeat_scope
        metafunc.parametrize(
            '__pytest_repeat_step_number',
            range(count),
            indirect=True,
            ids=make_progress_id,
            scope=scope
        )

Cette pytest_generate_testsfonction hook sera appelée une fois que toutes les fonctions de test auront été collectées par pytest, et elle est définie trylast=Truepour garantir qu'elle est exécutée une fois l'exécution des autres fonctions hook terminée.

  1. Tout d’abord, le code obtient metafunc.config.option.countla valeur , qui représente le nombre de fois que le scénario de test est répété.
  2. Ensuite, le code appelle metafunc.definition.get_closest_marker('repeat')pour savoir si le scénario de test comporte un repeatmarqueur marqué comme .
  3. S'il existe repeatun marqueur de , obtenez le nombre d'exécutions répétées du marqueur et affectez-le à countla variable.
  4. Ensuite, le code metafunc.fixturenames.append("__pytest_repeat_step_number")ajoute un __pytest_repeat_step_numbernom d'appareil à metafuncla liste des appareils en ajoutant un appareil nommé .
  5. Ensuite, une fonction d'assistance est définie make_progress_idpour générer des identifiants de progression pour les cas de test.
  6. En fonction de metafunc.config.option.repeat_scopela valeur de , l'exécution répétée est étendue.
  7. Enfin, metafunc.parametrizeles cas de test sont générés dynamiquement en appelant . Il prend range(count)en paramètre le nombre de pas à générer pour répéter, et indirect=Truedéfinit qu'il sera appelé indirectement lorsque le projecteur est chargé. Dans le même temps, la fonction et la portée de génération d'identifiant de progression précédemment définies sont utilisées pour définir d'autres options de paramétrage.

On voit que cela se réalise finalement grâce au paramétrage, c'est pourquoi les exécutions répétées peuvent être considérées comme de multiples cas d'utilisation.

enfin

Je crois que tu as encore beaucoup de questions après m'avoir regardé, fixturequ'est-ce que c'est ? markQu'est-ce que c'est? Quels sont les paramètres request? Qu'est-ce que la fonction crochet ? parametrizeQu'est-ce que le paramétrage ? Ces questions peuvent être conservées pour l'instant. Dans ce contenu, nous avons principalement parlé de pytest_repeatla logique spécifique de mise en œuvre, puis avons conduit à de nombreux points de connaissance. Ne vous inquiétez pas, nous les éliminerons un par un plus tard.

Enfin : le didacticiel vidéo complet sur les tests de logiciels ci-dessous a été trié et téléchargé, et les amis qui en ont besoin peuvent l'obtenir par eux-mêmes [Garanti 100 % gratuit]

Documentation sur les entretiens de test de logiciels

Nous devons étudier pour trouver un emploi bien rémunéré. Les questions d'entretien suivantes sont les derniers documents d'entretien de sociétés Internet de premier plan telles que Ali, Tencent et Byte, et certains patrons de Byte ont donné des réponses faisant autorité. Terminez cet ensemble croire que chacun peut trouver un emploi satisfaisant.

Je suppose que tu aimes

Origine blog.csdn.net/wx17343624830/article/details/132668577
conseillé
Classement