2010-12-31 6 views
1

Je voudrais faire des tests de haut niveau de mon application mochiweb, comme il est possible de faire en Python avec WebTest, dans Django avec le client de test et dans Ruby on Rails avec des tests fonctionnels ou d'intégration. Je ne suis pas trop difficile sur la façon de le faire. Fondamentalement, je voudrais juste envoyer ou simuler des requêtes HTTP et faire des assertions sur le résultat.Comment tester une application mochiweb?

J'ai refaçonné mon code afin que mon gestionnaire de requêtes n'appelle pas lui-même Req:respond(), mais renvoie un numéro de ligne {Code, Headers, Body}. Cela me permet de construire des demandes fictives avec mochiweb_request:new(), les transmettre à mon répartiteur de demande et faire des affirmations sur le résultat en utilisant EUnit:

make_request(Method, Path) -> 
    Request = mochiweb_request:new(nil, Method, Path, {1, 1}, 
     mochiweb_headers:make([{"Accept", "text/html"}])), 
    Response = myapp:dispatch(Request), 
    Response. 


signin_test() -> 
    {Code, _, _} = make_request('GET', "/signin"), 
    ?assertEqual(Code, 200), 
    ok. 

Maintenant, mon problème est de savoir comment tester les requêtes POST. Je n'ai rien trouvé dans mochiweb qui me permettrait de faire ça. De la lecture du code mochiweb, il semble que lorsque Req:parse_post() est appelée, il déclenche une lecture sur un socket. J'ai trouvé un code de test intéressant dans src/mochiweb.erl. Apparemment, cela implique la construction de messages HTTP, en les écrivant sur une socket et en lisant la réponse. J'ai essayé de le faire dans mon propre code de test mais je n'ai pas réussi à arriver après quelques heures. Je commence à me demander si je vais dans la bonne direction. Peut-être que j'ai besoin de découpler encore plus mes fonctionnalités de la plomberie HTTP, c'est à dire. n'appelle pas Req:parse_post() à partir de mes gestionnaires de requêtes. Une autre solution que je pense serait d'utiliser une bibliothèque de tests de sites Web tiers, pas nécessaire écrite en Erlang. Peut-être quelque chose en Ruby ou Python ou même peut-être Selenium.

Alors, quelle solution recommanderiez-vous pour faire des tests fonctionnels ou d'intégration d'une application mochiweb?

Répondre

0

J'utilise le serveur de test commun et pour tester, j'utilise ibrowse. Voici un exemple:

post_cap_query_no_caps(_Config) -> 
A="<?xml version=\"1.0\" encoding=\"utf-8\"?><query><capabilities/></query>", 
{ok, "200", _C, Body}=ibrowse:send_req("http://localhost:8000/devices", XML_CONTENT_TYPE, post, A), 
"<devices/>" == Body. 
+0

Merci d'avoir signalé ibrowse. Avez-vous réussi à le faire fonctionner avec eunit? Démarrez-vous/arrêtez-vous le serveur et configurez-vous un environnement de test en utilisant les installations d'eunit? –

1

Nous découplons principalement nos tests de la plomberie HTTP. Habituellement, la bonne chose à faire dans un environnement fonctionnel de toute façon.

Il existe un code eunit dans src/mochiweb_multipart.erl qui est probablement plus pertinent pour votre cas d'utilisation particulier. Pourquoi ne pas simplement utiliser un client http pour faire les appels?

+0

Je ne comprends pas ce que vous entendez par "découpler nos tests de la plomberie HTTP". Quand j'ai dit "découpler encore plus mes fonctionnalités de la plomberie HTTP", je voulais dire que mes contrôleurs ne par exemple pas appeler Req: parse_post() mais seraient fournis avec des données POST analysées comme une structure de données Erlang par une fonction plus haut dans la pile d'appels. Cette fonction traitant de "plomberie HTTP" ne serait pas testée. Seuls les gestionnaires de requêtes seraient testés en leur transmettant des structures de données Erlang contenant des données POST. Est-ce ce que vous faites aussi? –

+0

J'ai jeté un oeil au code eunit src/mochiweb_multipart.erl et je pense que je comprends à peu près ce qu'il fait. Dans ce code, vous définissez vous-même un ServerFun afin de tester les fonctionnalités de mochiweb. Dans mon cas, je voudrais tester la fonctionnalité du serveur existant, donc je suppose que je devrais fournir une des fonctions de mon application comme l'option de boucle que mochiweb_socket_server: start() prend? Serait-ce la fonction de boucle définie dans l'application squelette mochiweb? (J'ai essayé et cela n'a pas fonctionné, mais il est tout à fait possible que j'ai eu un problème ailleurs dans mon code). –

+0

Oui, désolé de ne pas être plus précis. Avoir des tests découplés de la plomberie HTTP implique que la fonctionnalité elle-même est découplée de la plomberie HTTP. –

0

J'utilise ibrowse pour tester mon serveur webmachine, y compris les données POSTing au besoin.

Questions connexes