J'écris un ensemble d'outils pour tester le comportement d'un serveur HTTP personnalisé: qu'il s'agisse de définir les codes de réponse appropriés, les champs d'en-tête, etc. J'utilise pytest pour écrire tests.py.test: Comment générer des tests à partir d'appareils
L'objectif est de faire des demandes à plusieurs ressources, puis d'évaluer la réponse dans plusieurs tests: chaque test doit tester un seul aspect de la réponse HTTP. Cependant, toutes les réponses ne sont pas testées avec chaque test et vice-versa. Pour éviter d'envoyer la même requête HTTP plusieurs fois et de réutiliser les messages de réponses HTTP, je pense à utiliser les fixtures de pytest, et pour exécuter les mêmes tests sur différentes réponses HTTP, je voudrais utiliser les capacités de test de pytest. demandes d'importation à l'importation pytest
def pytest_generate_tests(metafunc):
funcarglist = metafunc.cls.params[metafunc.function.__name__]
argnames = sorted(funcarglist[0])
metafunc.parametrize(argnames, [[funcargs[name] for name in argnames]
for funcargs in funcarglist])
class TestHTTP(object):
@pytest.fixture(scope="class")
def get_root(self, request):
return requests.get("http://test.com")
@pytest.fixture(scope="class")
def get_missing(self, request):
return requests.get("http://test.com/not-there")
def test_status_code(self, response, code):
assert response.status_code == code
def test_header_value(self, response, field, value):
assert response.headers[field] == value
params = {
'test_status_code': [dict(response=get_root, code=200),
dict(response=get_missing, code=404), ],
'test_header_value': [dict(response=get_root, field="content-type", value="text/html"),
dict(response=get_missing, field="content-type", value="text/html"), ],
}
Le problème semble être dans la définition des params: dict(response=get_root, code=200)
et définitions similaires ne se rendent pas compte, je voudrais lier sur l'appareil et sur la référence de fonction réelle.
Lorsque l'exécution des tests, je reçois ce genre d'erreurs:
________________________________________________ TestHTTP.test_header_value [type de contenu response0-text/html] _________________________________________________
self = <ev-question.TestHTTP object at 0x7fec8ce33d30>, response = <function TestHTTP.get_root at 0x7fec8ce8aa60>, field = 'content-type', value = 'text/html'
def test_header_value(self, response, field, value):
> assert response.headers[field] == value
E AttributeError: 'function' object has no attribute 'headers'
test_server.py:32: AttributeError
Comment puis-je convaincre le pytest de prendre la valeur de l'appareil au lieu de la fonction?
Merci, Nils. Cependant, ce code exécutera tous les tests sur tous les appareils, ce qui n'est pas ce que je désire. Je voudrais spécifier quels tests et quels appareils doivent être combinés. Pour l'argument, imaginez que vous ne voulez pas vérifier le code de retour sur une demande normale, seulement sur celui qui devrait retourner 404. En outre, je veux que chaque test ne vérifie qu'un aspect de la réponse, c'est-à-dire exécuter une seule assertion. Donc, si un en-tête est manquant, je devrais obtenir une erreur pour cet en-tête seulement, alors que pour les autres, les tests devraient passer. – David
Je viens de me rendre compte, je pourrais sauter vérifier avec 'key in response' pour voir si l'objet' response' a une 'key', et si oui, je peux' pytest.skip() 'it. – David
Pourquoi ne pas tester la valeur de retour de chaque demande? Le traitement moins spécial de certaines conditions, moins vous êtes susceptible de faire des erreurs. –