Dois-je inclure des tests dans l'image Docker?


19

En ce qui concerne les tests, je peux penser à deux options:

  1. Mettez le test et l'application dans une seule image.
  2. N'incluez que le code d'application dans l'image. Créez un conteneur spécifique au test qui se construit après l'image principale et y ajoute des couches (code de test, dépendances, etc.).

Avec la première option, je peux tester le conteneur et l'expédier exactement comme testé. Un inconvénient évident est que du code inutile (et potentiellement des données de test) sera inclus dans l'image.

Avec la deuxième option, l'image qui est expédiée n'est pas tout à fait la même que celle qui est testée.

Les deux ressemblent à de mauvaises stratégies. Existe-t-il une troisième meilleure stratégie?


1
Vous vous êtes essentiellement répondu. Les deux sont une mauvaise idée. Vous embarquerez des processus exécutables déjà testés dans un conteneur dimensionné et personnalisé selon les besoins. Vous ne voulez pas de dépendances dev ni de code src. En production, c'est considéré comme un risque.
Laiv

1
Tester avant la conteneurisation signifie que l'environnement n'est pas testé, seul le code l'est. Vous n'aurez testé qu'une partie de ce que vous expédiez, pas tout.
lfk

Réponses:


10

Pour exécuter des tests au moment de la génération, la méthode préférée serait d'utiliser une génération en plusieurs étapes . Les Dockerfiles à plusieurs étapes vous permettent d'avoir une étape plus grande avec toutes les dépendances pour la construction et les tests, puis copiez les artefacts exacts que vous avez testés dans une autre étape pour une image d'exécution plus petite.

Vous souhaitez également des tests au niveau système de plusieurs conteneurs, en utilisant leurs interfaces externes au lieu de s'exécuter dans le conteneur. Étant donné que ces tests impliquent une coordination entre les services, nécessitent des dépendances différentes telles que l'accès à votre orchestration, ne sont pas aussi complets que les tests au moment de la construction et sont souvent écrits dans des langues complètement différentes de toute façon, ce n'est pas un problème de les exécuter à partir d'un Docker distinct conteneur dédié uniquement aux tests système.


1
C'est donc à peu près l'option 2 - j'exécute les tests dans un environnement / conteneur qui est très similaire à la production, mais pas tout à fait la même. Est-ce correct?
lfk

9

Il y a une troisième voie, comme vous l'avez dit vous-même. Je pense que vous mélangez le développement, les tests et le déploiement. Je propose que l'ensemble du SDLC soit considéré dans son ensemble, d'abord, pour comprendre ce que vous essayez d'atteindre. C'est un gros sujet, mais je ferai de mon mieux pour résumer.

TL; DR;

En bref, vous devez séparer:

  • votre code, de
  • la configuration de l'application, de
  • la configuration de l'environnement système.

Chacun doit être indépendant les uns des autres et convenablement:

  • version contrôlée
  • testé
  • déployable

Version plus longue

Tout d'abord, vous avez une application composée de code et (ensembles séparés de) configuration. Cela doit être testé, à la fois pour la construction et la fonction intentionnelle - c'est ce qu'on appelle l'intégration continue (CI). Il existe de nombreux fournisseurs de ce service en ligne et localement - par exemple CircleCI pour un fournisseur de cloud qui se connecte à votre référentiel et crée et teste chaque fois que vous vous engagez. Si votre référentiel est sur site et ne peut pas utiliser un fournisseur de cloud, quelque chose comme Jenkinsserait un équivalent. Si votre application est assez standard, il existe probablement une image Docker existante que le service CI peut utiliser. Si ce n'est pas le cas, vous devrez en créer un, ou un cluster, pour que votre code d'application et votre configuration puissent être déployés. Correctement configuré, vous disposerez d'une multitude de statistiques sur la qualité de votre code d'application.

Ensuite, une fois que vous êtes satisfait de la fonctionnalité et de l'exactitude de votre application, la base de code doit être correctement étiquetée pour une version spécifique. Cette version doit ensuite être déployée dans un environnement de test. Notez que le code sera le même que celui testé dans votre CI (peut-être, si vous l'avez fait correctement), mais votre configuration peut différer. Encore une fois, certains fournisseurs de CI peuvent proposer cette étape afin que vous puissiez tester votre déploiement d'une application packagée et d'une configuration discrète. Cette étape comprend généralement des tests fonctionnels de l'utilisateur (pour les nouvelles fonctionnalités), ainsi que des tests automatisés (pour les fonctionnalités connues). Si la version réussit cette étape, vous disposez d'une version candidate pour les tests d'intégration. Vous pouvez exécuter les tests d'automatisation à partir d'un autre conteneur Docker,certaines mesures qui indiquent que l'effort de test est de 1: 1 à l'effort de codage (bien que je ne sois pas sûr de cela moi-même).

Avant tout, l'étape suivante consiste à créer votre environnement (système) comme s'il s'agissait de production. Si vous utilisez Docker en production, c'est là que vous penserez au renforcement de la sécurité, à l'optimisation du réseau et du serveur, etc. Vos images Docker peuvent être basées sur celles que vous avez utilisées en développement (idéalement), mais il peut y avoir des changements pour la mise à l'échelle et la sécurité , comme j'ai dit. A présent, les tests fonctionnels de l'application devraient être terminés, vous êtes plus préoccupé par la sécurité et les performances. Selon les tests fonctionnels, vos tests ici peuvent être développés, déployés et exécutés à partir d'autres images Docker. Cette étape était horriblement coûteuse et rarement effectuée pour ce faire, vous aviez donc besoin d'un matériel dédié en place qui reproduise la production. Aujourd'hui, c'est complètement viable car vous pouvez vous lever et détruire tout l'environnement de presque n'importe quelle échelle à la demande.

Enfin, vous avez une version qui devrait être prête pour la production avec seulement un petit ensemble de deltas de configuration de celui de vos tests d'intégration (adresses IP, URI de base de données, mots de passe, etc.) Votre base de code a été testée au moins dans trois environnements différents à ce point et la majorité de la configuration du système au moins une fois.


Cela signifie-t-il que votre CI ne testera pas du tout vos Dockerfiles? Par exemple, si votre Dockerfile manquait une dépendance, les tests réussiraient-ils quand même?
lfk

1
Pas du tout. Testez d'abord le code, puis testez la configuration de l'application, puis testez le système. Ce que je dis, c'est que ce sont des activités discrètes. La grande chose à propos de la conteneurisation est que le rêve de développement dans un environnement identique à celui de Prod est très proche. Mais le durcissement rendrait le développement trop difficile.
avastmick

0

Je pense que vous mélangez différents types de tests. Fondamentalement, vous devez vous demander: quelle est l'unité testée ici?

Le scénario le plus courant lorsque vous travaillez en tant que développeur consiste à écrire des tests unitaires / d'intégration pour un morceau de code sur lequel vous travaillez, où ce morceau de code est l'unité testée. Vous exécutez ces tests localement et / ou dans CI.

Lorsque vous avez construit une nouvelle image docker, elle devient une nouvelle unité que vous pouvez tester. Quels types de choses aimeriez-vous tester pour cette image? Quelle est l'API qu'elle fournit? Comment testez-vous cela?

S'il s'agit d'une application Web, vous pouvez démarrer un conteneur basé sur l'image et effectuer certaines requêtes HTTP et vérifier que les réponses correspondent à vos attentes. Le problème que je pense que vous rencontrez est que vous êtes très habitué au cadre de test couplé au code d'application. C'est bien pendant le développement, mais maintenant vous voulez tester une image Docker et vous avez donc besoin d'un nouveau type de framework de test qui peut le faire et n'est pas lié au code de l'application.

Je pense donc que la 3ème option que vous recherchez est:

  • Exécutez vos tests unitaires / d'intégration avant de créer une image Docker.
  • Créez une image Docker contenant uniquement l'application que vous souhaitez distribuer.
  • Au lieu d'ajouter des couches supplémentaires au-dessus de cette image d'application, vous la testez telle quelle en l'exécutant avec certains paramètres donnés et confirmez vos résultats attendus.

Ainsi, les étapes CI / CD seraient:

Configuration de l'environnement de développement -> Exécuter des tests sur le code -> Créer l'image finale -> Exécuter des tests sur l'image -> Déployer l'image.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.