génération de py.tests de test en python

Question d'abord, puis une explication si vous êtes intéressé.

Dans le contexte de py.test, comment puis-je générer un grand nombre de fonctions de test à partir d'un petit ensemble de tests, les modèles de fonction?

quelque Chose comme:

models = [model1,model2,model3]
data_sets = [data1,data2,data3]

def generate_test_learn_parameter_function(model,data):
    def this_test(model,data):
        param = model.learn_parameters(data)
        assert((param - model.param) < 0.1 )
    return this_test

for model,data in zip(models,data_sets):
    # how can py.test can see the results of this function?
    generate_test_learn_parameter_function(model,data)

Explication:

je fais de mon mieux pour entrer dans le test de l'unité. Je code pour "science", en ce que je suis en train d'écrire un code que je pense être compliqué mathématiquement mais pas si mal du point de vue de la programmation, c'est-à-dire que j'ai peut-être cinq fonctions de test. Que je vienne de la "science" signifie que je suis assez nouveau aux tests de l'unité, mais ont été convaincu mes amis CS que c'est la chose à faire.

le code que j'écris prend une structure de modèle, quelques données, et apprend les paramètres du modèle. Donc, mon unité d'essai se compose d'un tas de structures de modèle et des ensembles de données pré-produites, puis un ensemble d'environ 5 tâches d'apprentissage machine à compléter sur chaque structure+données.

donc si je code à la main ceci je besoin d'un test par modèle par tâche. Chaque fois que je viens avec un nouveau modèle, j'ai besoin de copier et coller les 5 tâches, en changeant la structure de pickled+données que je pointe. Cela se sent comme une mauvaise pratique pour moi. Idéalement, ce que je voudrais est 5 fonctions de modèle qui définissent chacune de mes 5 tâches et puis juste cracher les fonctions de test pour une liste de structures que je spécifie.

googler m'amène soit à a) des usines ou B) des fermetures, deux choses qui me viennent à l'esprit et qui me suggèrent que il doit y avoir un moyen plus simple, car ce problème doit être affronté régulièrement par les programmeurs appropriés. Donc est-il?


EDIT: alors voici comment résoudre ce problème!

def pytest_generate_tests(metafunc):
    if "model" in metafunc.funcargnames:
        models = [model1,model2,model3]
        for model in models:
            metafunc.addcall(funcargs=dict(model=model))

def test_awesome(model):
    assert model == "awesome"

ceci appliquera le test test_awesome à chaque modèle de ma liste de modèles! Merci @dfichter!

(NOTE: qui affirment passe toujours, d'ailleurs)

16
demandé sur Mike Dewar 2011-02-07 19:40:30

2 réponses

bons instincts. py.test supporte exactement ce dont vous parlez avec son pytest_generate_tests() crochet. Ils l'expliquent ici.

15
répondu dfichter 2016-08-28 04:13:33

Vous pouvez aussi le faire à l'aide de paramétrées, luminaires. While hooks, est une API pour construire des plugins pour Py.test, paramétré fixtures est un moyen généralisé de faire un fixtures qui produit des valeurs multiples et génère des cas de test supplémentaires pour eux.

les Plugins sont conçus pour être des fonctionnalités à l'échelle du projet (ou du paquet), pas pour tester les fonctionnalités spécifiques au cas et les fixtures paramétrées sont exactement ce qu'il faut pour paramétrer une ressource pour tester affaire(s).

Donc votre solution pourrait être réécrit comme:

@pytest.fixture(params=[model1, model2, model3])
def model(request):
    return request.param

def test_awesome(model):
    assert model == "awesome"
5
répondu Gill Bates 2015-08-11 14:13:29