Question

Je cherche des suggestions pour améliorer le processus d'automatisation des tests fonctionnels d'un site Web. Voici ce que j'ai essayé dans le passé.

Je l'habitude d'avoir un projet de test en utilisant WATIN . Vous écrivez effectivement ce qui ressemble à des « tests unitaires » et utilisez WATIN pour automatiser un navigateur de cliquer autour de votre site etc.

Bien sûr, vous avez besoin d'un site pour exécuter. Donc, j'ai fait le test de copie en fait le code de mon projet Web dans un répertoire local et a commencé un serveur Web pointant vers ce répertoire avant que les exécuter des tests.

De cette façon, une personne nouvelle pourrait simplement obtenir le dernier de notre contrôle de code source et exécuter notre script de compilation, et de voir tous les tests exécutés. Ils pourraient également exécuter simplement tous les tests de l'IDE.

Le problème que je courais en était que j'ai passé beaucoup de temps à maintenir le code pour mettre en place l'environnement de test plus que les tests. Sans oublier qu'il a fallu beaucoup de temps à courir à cause de tout ce que la copie. De plus, je devais tester différents scénarios, y compris l'installation, ce qui signifie que je devais être en mesure de définir la base de données à différents états initiaux.

Je suis curieux de ce que vous avez fait pour automatiser les tests fonctionnels pour résoudre certains de ces problèmes et de garder toujours simple.

Plus de détails Puisque les gens ont demandé plus de détails, ici il est. Je suis en cours d'exécution ASP.NET à l'aide de Visual Studio et Cassini (intégré dans le serveur web). Mes tests unitaires exécutés dans MbUnit (mais ce n'est pas si important. Peut-être NUnit ou XUnit.NET). En règle générale, j'ai un cadre de test unitaire séparé exécuté tous mes tests Watin. Dans la phase de AssemblyLoad, je lance le serveur Web et copier tout mon code d'application Web localement.

Je suis intéressé par des solutions pour toute plate-forme, mais je peux avoir besoin de plus de descriptions sur ce que signifie chaque chose. :)

Était-ce utile?

La solution

Phil,

L'automatisation peut juste être difficile à maintenir, mais plus vous utilisez votre automatisation pour le déploiement, plus vous pouvez tirer parti pour la configuration de test (et vice versa).

Franchement, il est plus facile d'évoluer le code d'automatisation, l'affacturage et la refactorisation en unités spécifiques, petites de fonctionnalités lors de l'utilisation d'un outil de construction qui ne sont pas
juste conduite statiquement compilé, des unités pré-factorisées de fonctionnalité, comme cela est le cas avec NAnt et MSBuild. Ceci est l'une des raisons que beaucoup de gens qui étaient des utilisateurs relativement précoces de Toole comme NAnt se sont déplacés Rake. La liberté de traiter la construction code comme tout autre code - à évoluer cotinually son contenu et la forme - est plus grande avec Rake. Vous ne finissent pas avec le même stase dans des objets d'automatisation aussi facilement et aussi rapidement avec Râteau, et il est beaucoup plus facile de script dans Rake que NAnt ou MSBuild.

Alors, une partie de votre lutte est liée intrinsèquement dans les outils. Pour garder votre automatisation sensible et maintenu, il faut se méfier des obstacles que les outils de construction statiques comme imposent NAnt et MSBuild.

Je suggère que vous couplent pas votre environnement de test démarrage de cerclage de charge d'assemblage. C'est un couplage intérieur vers l'extérieur qui ne sert qu'à brève convenance. Il n'y a rien de mal (et, tout probablement droit) d'aller à la ligne de commande et l'exécution de la tâche de construction qui met en place l'environnement avant l'exécution des tests soit à partir de l'IDE ou de la ligne de commande, ou à partir d'une console interactive, comme le C # REPL de le projet Mono, ou de la CISR.

Configuration des données de test est tout simplement une douleur dans le cul parfois. Il doit être fait.

Vous allez avoir besoin d'une bibliothèque que vous pouvez appeler pour créer et nettoyer l'état de base de données. Vous pouvez faire ces appels à partir de votre code de test, mais je personnellement tendance à éviter de faire cela parce qu'il ya plus d'un bon usage des données d'essai ou code de contrôle de données échantillon.

Je conduis tous les échantillons de contrôle de données de HTTP. J'écris des contrôleurs avec des actions spécifiquement pour contrôler les données d'échantillon et question par rapport à ces actions obtient par Sélénium. Je les utilise pour créer et nettoyer les données. Je peux composer ces actions arrive à créer des scénarios communs de données de configuration, et je peux transmettre des valeurs spécifiques pour les données en tant que paramètres de demande (ou des paramètres de formulaire si besoin est).

Je garde ces contrôleurs dans un domaine que j'appelle habituellement « test_support ».

Mon automatisation pour le déploiement du site ne déploie pas la zone de test_support ou de ses routes et de la cartographie. Dans le cadre de mon automatisation de vérification de déploiement, je fais en sorte que le code test_support n'est pas dans l'application de production.

Je l'utilise aussi le code test_support pour automatiser le contrôle de tout l'environnement - remplacement des services avec des faux, en éteignant les sous-systèmes pour simuler des défaillances et des basculements, activer ou désactiver l'authentification et le contrôle d'accès pour les tests fonctionnels qui ne porte pas sur ces aspects, etc.

Il y a une grande valeur secondaire pour contrôler les données de votre application web d'échantillons ou de données de test à partir du Web: lorsque demoing l'application, ou lorsque vous faites des tests d'exploration, vous pouvez créer des scénarios de données que vous avez juste besoin en émettant quelques-uns obtient contre les attaques connues (ou devinables) URL dans la zone de test_support. Vraiment faire un effort discipliné pour coller aux routes reposant et l'orientation des ressources ici va vraiment payer.

Il y a beaucoup plus à cette automatisation fonctionnelle (y compris le test, le déploiement, demoing, etc.) afin que les mieux conçus ces ressources sont, plus le temps que vous aurez les maintenir sur le long couloir, et plus les possibilités que vous » ll trouver les moyens de tirer parti, mais unforseen bénéfiques.

Par exemple, l'écriture de code modèle de domaine sur le modèle sémantique de vos pages Web aidera à créer un code de test beaucoup plus compréhensible et diminuer la friabilité. Si vous le faites bien, vous pouvez utiliser ces mêmes modèles avec une variété de pilotes différents afin que vouspeuvent les exploiter dans les tests de stress et des tests de charge ainsi que des tests fonctionnels ainsi que de les utiliser à partir de la ligne de commande comme outils d'exploration. Soit dit en passant, ce genre de chose est plus facile à faire quand vous n'êtes pas lié à des types de pilotes que vous êtes lorsque vous utilisez une langue statique. Il y a une raison pour laquelle de nombreux grands penseurs de tests et ceux qui font travailler en Ruby, et pourquoi Watir est écrit en Ruby. La réutilisation, la composition et l'expressivité est beaucoup plus facile à réaliser dans Ruby que le code C # test. Mais c'est une autre histoire.

Nous allons rattraper quelque temps et parler plus sur les 90% restants de ce genre de choses:)

Autres conseils

Nous avons utilisé plasma sur un projet. Il émule un serveur Web en cours - point juste à la racine de votre projet d'application Web.

Il était étonnamment stable - pas copier des fichiers ou un démarrage sur le serveur de processus

.

Voici comment un test utilisant le plasma nous cherche ...

    [Test]
    public void Can_log_in() {
        AspNetResponse response = WebApp.ProcessRequest("/Login.aspx");
        AspNetForm form = response.GetForm();

        form["UserName"] = User.UserName;

        form["Password"] = User.Password;

        AspNetResponse loggedIn = WebApp.ProcessRequest(Button.Click(form, "LoginUser"));


        Assert.IsTrue(loggedIn.IsRedirect());

        AspNetResponse homePage = WebApp.ProcessRequest(loggedIn.GetRedirectUrl());

        Assert.AreEqual(homePage.Status, 200);
    }

Toutes les classes "AspNetResponse" et "AspNetForm" sont inclus avec le plasma.

Nous utilisons actuellement un processus automatisé de construction pour notre asp.net demande mvc.

Nous utilisons les outils suivants:

  • TeamCity
  • SVN
  • nUnit
  • Sélénium

Nous utilisons un script MSBuild qui fonctionne sur un agent de construction qui peut être une quantité de machines. Le script msbuild obtient la dernière version de code à partir svn et le construit.

En cas de succès, il déploie ensuite les objets à une machine / dossier donné et crée le site virtuel dans IIS.

Nous utilisons ensuite les tâches contrib MSBuild pour exécuter des scripts SQL pour installer les données de base de données et de charge, vous pouvez aussi faire une restauration.

Le succès que nous débutons les essais nunit. La configuration de test permet de vérifier que le sélénium est en cours d'exécution, puis conduit les tests de sélénium beaucoup de la même manière que le fait Watin. Sélénium a un bon enregistreur pour les tests qui peuvent être exportés vers c #.

La bonne chose à propos Sélénium est que vous pouvez conduire FF, Chorme et IE plutôt que d'être limité à IE qui était le cas avec Watin la dernière fois que je l'ai regardé. Vous pouvez également utiliser Sélénium pour faire des tests de charge avec la grille Sélénium donc vous pouvez réutiliser les mêmes tests.

En cas de succès msbuild balises alors la construction dans svn. TeamCity a un travail qui fonctionne la nuit qui va déployer la dernière étiquette à un environnement de mise en scène prêt pour les utilisateurs professionnels pour vérifier l'état de projet, le lendemain matin.

Dans une vie antérieure, nous avions Nant et des scripts MSBuild pour gérer entièrement l'environnement (installation java, le sélénium, etc.) mais cela prend beaucoup de temps pour en req avant nous supposons que chaque agent de construction a ces installés. Avec le temps, nous allons inclure ces tâches.

Pourquoi avez-vous besoin de copier le code? Fossé Cassini et laisser Visual Studio créer un répertoire virtuel pour vous. Bien sûr, les développeurs ne doivent pas oublier de construire avant d'exécuter des tests web si l'application Web a changé. Nous avons constaté que ce n'est pas un gros problème, surtout si vous exécutez des tests Web dans CI.

Data est un grand défi. Pour autant que je peux voir, vous devez choisir entre des alternatives imparfaits. Voici comment nous traitons. Tout d'abord, je dois préciser que nous travaillons avec un grand héritage complexe app WebForms. Aussi je dois mentionner que le code de domaine n'est pas bien adapté pour la création de données de test à partir du projet de test.

Cela nous a laissé deux choix. Nous pourrions: (a) des scripts de configuration des données d'exécution sous la construction, ou (b) créer toutes les données via des tests Web en utilisant le site Web réelle. Le problème avec l'option (a) est que les tests deviennent couplés avec des scripts à un niveau de minute. Il fait que ma tête bourdonnait de penser à la synchronisation de code de test web avec T-SQL. Nous sommes donc allés avec (b).

L'un des avantages de (b) est que votre configuration valide également le comportement des applications. Le problème est ... temps .

tests doivent être indépendants Idéalement, sans couplage temporel (peut fonctionner dans un ordre quelconque) et ne partage pas un contexte (par exemple, des données de test communes). La façon courante de gérer cela est de mettre en place et le démontage des données avec tous les tests. Après une bonne réflexion, nous avons décidé de briser cette règle.

Nous utilisons Gallio (MbUnit 3), qui offre quelques fonctionnalités intéressantes qui soutiennent notre stratégie. Tout d'abord, il vous permet de spécifier l'ordre d'exécution au niveau du montage et de test. Nous avons quatre appareils « de configuration », qui sont commandés -4, -3, -2, -1. Celles-ci passent dans l'ordre spécifié et avant tous les appareils « de configuration non », qui par défaut ont un ordre de 0

Notre projet de test Web dépend du script de compilation pour une seule chose: un nom d'utilisateur / mot de passe unique bien connu. Ceci est un couplage je peux vivre avec. Comme les tests de configuration fonctionnent ils construisent un objet « contexte de données » qui détient des identifiants de données (sociétés, utilisateurs, fournisseurs, clients, etc.) qui est ensuite utilisé (mais jamais changé) tout au long d'autres tous les appareils. (Par des identifiants, je ne veux pas nécessairement les clés. Dans la plupart des cas, notre interface utilisateur Web n'expose pas des clés uniques. Nous devons naviguer dans l'application en utilisant des noms ou d'autres procurations pour les vrais identifiants. Voir plus bas.)

Gallio vous permet également de spécifier qu'un test ou un appareil dépend d'un autre test ou appareil. Lorsqu'un précédent échoue, la personne à charge est sautée. Cela réduit le mal du couplage temporel en empêchant « les défaillances en cascade » qui peut récolter beaucoup de confusion.

Création de données de test de base une fois, au lieu d'avant chaque test, accélère les choses beaucoup. Cependant, les tests de configuration peuvent encore prendre 10 minutes pour courir. Quand je travaille sur de nouveaux tests que je veux courir et les répéter fréquemment. Entrez un autre frais caractéristique Gallio: Ambiance. L'ambiance est un wrapper autour DB4 qui fournit un moyen très simple de persister des objets. Nous l'utilisons pour persister automatiquement le contexte de données. Ainsi, les tests de configuration ne doivent être exécutés une fois entre les reconstructions de la base de données. Après cela, vous pouvez exécuter tout ou partie d'autres appareils à plusieurs reprises.

Alors, que sur le nettoyage des données de test? Ne nous devons commencer à partir d'un état connu? Ceci est une règle que nous avons trouvé opportun de rompre. Une stratégie qui fonctionne pour nous est d'utiliser des valeurs à long aléatoires pour des choses comme nom de l'entreprise, le nom d'utilisateur, etc. Nous avons trouvé qu'il est pas très difficile de garder un essai dans un « espace de données » logique telle qu'elle ne cogne pas dans d'autres données. Certes, je crains le jour que je passe des heures à pourchasser un test ne fantôme pour constater que c'est une collision de données. Il est un compromis qui fonctionne pour nous actuellement.

Nous utilisons Watin. J'aime assez ça. Une autre clé du succès est quelque chose Scott Bellware fait allusion. Comme nous créons des tests que nous construisons un modèle abstrait de notre interface utilisateur. Ainsi, au lieu de ceci:

browser.TextField("ctl0_tab2_newNote").TypeText("foo");

wiVerrez cela dans nos tests:

User.NotesTab.NewNote.TypeText("foo");

Cette approche offre trois avantages. Tout d'abord, nous répétons jamais une chaîne magique. Cela réduit considérablement friabilité. En second lieu, les tests sont beaucoup plus faciles à lire et à comprendre. Enfin, nous cachons la plupart du cadre Watin derrière nos propres abstractions. Dans le second exemple, seul TypeText est une méthode Watin. Ce sera plus facile de changer les changements du cadre.

Hope this helps.

Il était difficile, mais pas impossible, de construire une phase de test d'intégration dans le processus de construction en utilisant Maven. Ce qui est arrivé était essentiellement ceci:

  • Ignorer tous les tests JUnit dans un répertoire spécifique à moins que les feux de phase de test d'intégration.
  • Ajouter un profil Maven pour exécuter les tests d'intégration.
  • Pour la phase de pré-test d'intégration -

  • Démarrer Jetty exécutant l'application de frapper une base de données de test.

  • Démarrez le serveur de sélénium
  • Exécuter les tests d'intégration de sélénium en phase de test d'intégration
  • Arrêter le serveur de sélénium
  • Arrêter le sélénium

La difficulté de cette étape se couchait vraiment jetée - nous ne pouvions pas à lancer juste d'une guerre, nous avons donc fait d'avoir jetée Déballez la guerre, puis exécutez le serveur - mais il fonctionne bien, et est automatisé -. tout ce que vous devez faire est de taper mvn -PintegrationTest (qui était le nom de notre profil de test d'intégration) et en dehors a

Voulez-vous dire automatiquement après le test à partir de construction terminé? Vous pouvez écrire des scripts automatisés pour copier les fichiers de construction à un IIS de travail alors que la construction a respecté avec succès. Et puis démarrez le BVT automatisé par appel MSTest.exe ou d'autres méthodes.

Vous pouvez obtenir un essai avec AutoItX ou un langage de fonction, tel que Python, Ruby.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top