Test des applications de filetage

Dans ce chapitre, nous allons découvrir comment tester les applications de thread. Nous apprendrons également l'importance des tests.

Pourquoi tester?

Avant de plonger dans la discussion sur l'importance des tests, nous devons savoir ce que sont les tests. En termes généraux, les tests sont une technique permettant de déterminer si quelque chose fonctionne bien. D'un autre côté, en particulier si nous parlons de programmes informatiques ou de logiciels, le test est la technique d'accès à la fonctionnalité d'un logiciel.

Dans cette section, nous discuterons de l'importance des tests logiciels. Dans le développement de logiciels, il doit y avoir une double vérification avant la publication du logiciel au client. C'est pourquoi il est très important de tester le logiciel par une équipe de test expérimentée. Tenez compte des points suivants pour comprendre l'importance des tests logiciels -

Amélioration de la qualité des logiciels

Certes, aucune entreprise ne souhaite fournir des logiciels de mauvaise qualité et aucun client ne souhaite acheter de logiciels de mauvaise qualité. Les tests améliorent la qualité du logiciel en trouvant et en corrigeant les bogues.

Satisfaction des clients

La partie la plus importante de toute entreprise est la satisfaction de ses clients. En fournissant un logiciel sans bogue et de bonne qualité, les entreprises peuvent satisfaire leurs clients.

Réduisez l'impact des nouvelles fonctionnalités

Supposons que nous ayons créé un système logiciel de 10000 lignes et que nous ayons besoin d'ajouter une nouvelle fonctionnalité, l'équipe de développement aurait alors des inquiétudes quant à l'impact de cette nouvelle fonctionnalité sur l'ensemble du logiciel. Ici aussi, les tests jouent un rôle essentiel car si l'équipe de test a réalisé une bonne suite de tests, cela peut nous éviter d'éventuelles ruptures catastrophiques.

Expérience utilisateur

Une autre partie la plus importante de toute entreprise est l'expérience des utilisateurs de ce produit. Seuls les tests peuvent garantir que l'utilisateur final trouve qu'il est simple et facile d'utiliser le produit.

Réduire les dépenses

Les tests peuvent réduire le coût total du logiciel en trouvant et en corrigeant les bogues en phase de test de son développement plutôt qu'en les corrigeant après la livraison. S'il y avait un bogue majeur après la livraison du logiciel, cela augmenterait son coût tangible, par exemple en termes de dépenses et de coût intangible, par exemple en termes d'insatisfaction client, de réputation négative de l'entreprise, etc.

Que tester?

Il est toujours recommandé d'avoir une connaissance appropriée de ce qui doit être testé. Dans cette section, nous allons d'abord comprendre le principal motif du testeur lors du test d'un logiciel. La couverture de code, c'est-à-dire le nombre de lignes de code que notre suite de tests atteint, lors des tests, doit être évitée. C'est parce que, lors des tests, se concentrer uniquement sur le nombre de lignes de codes n'ajoute aucune valeur réelle à notre système. Il peut rester quelques bogues, qui se reflètent plus tard à un stade ultérieur, même après le déploiement.

Tenez compte des points importants suivants relatifs à ce qu'il faut tester -

  • Nous devons nous concentrer sur le test de la fonctionnalité du code plutôt que sur la couverture du code.

  • Nous devons d'abord tester les parties les plus importantes du code, puis passer aux parties les moins importantes du code. Cela fera certainement gagner du temps.

  • Le testeur doit avoir une multitude de tests différents qui peuvent pousser le logiciel à ses limites.

Approches pour tester les programmes logiciels simultanés

En raison de la capacité d'utiliser la véritable capacité de l'architecture multicœur, les systèmes logiciels simultanés remplacent les systèmes séquentiels. Ces derniers temps, des programmes système simultanés sont utilisés dans tout, des téléphones mobiles aux machines à laver, des voitures aux avions, etc. déjà un bogue, alors nous nous retrouverions avec plusieurs bogues.

Les techniques de test pour les programmes logiciels simultanés se concentrent largement sur la sélection de l'entrelacement qui expose des modèles potentiellement dangereux tels que les conditions de course, les blocages et la violation de l'atomicité. Voici deux approches pour tester des programmes logiciels simultanés -

Exploration systématique

Cette approche vise à explorer l'espace des entrelacements le plus largement possible. De telles approches peuvent adopter une technique de force brute et d'autres adoptent une technique de réduction d'ordre partiel ou une technique heuristique pour explorer l'espace des entrelacements.

Axé sur la propriété

Les approches basées sur les propriétés reposent sur l'observation que les erreurs de concurrence sont plus susceptibles de se produire sous des entrelacements qui exposent des propriétés spécifiques telles que des modèles d'accès à la mémoire suspects. Différentes approches axées sur les propriétés ciblent différentes erreurs telles que les conditions de concurrence, les blocages et la violation de l'atomicité, qui dépendent en outre de l'une ou d'autres propriétés spécifiques.

Stratégies de test

La stratégie de test est également appelée approche de test. La stratégie définit la manière dont les tests seraient effectués. L'approche de test a deux techniques -

Proactif

Une approche dans laquelle le processus de conception de test est lancé le plus tôt possible afin de trouver et de corriger les défauts avant la création de la construction.

Réactif

Une approche dans laquelle les tests ne commencent qu'à la fin du processus de développement.

Avant d'appliquer une stratégie ou une approche de test sur un programme python, nous devons avoir une idée de base sur le type d'erreurs qu'un programme logiciel peut avoir. Les erreurs sont les suivantes -

Erreurs de syntaxe

Pendant le développement du programme, il peut y avoir de nombreuses petites erreurs. Les erreurs sont principalement dues à des fautes de frappe. Par exemple, deux points manquants ou une mauvaise orthographe d'un mot-clé, etc. Ces erreurs sont dues à une erreur de syntaxe du programme et non de logique. Par conséquent, ces erreurs sont appelées erreurs syntaxiques.

Erreurs sémantiques

Les erreurs sémantiques sont également appelées erreurs logiques. S'il y a une erreur logique ou sémantique dans le programme logiciel, l'instruction sera compilée et exécutée correctement mais elle ne donnera pas la sortie souhaitée car la logique n'est pas correcte.

Test unitaire

C'est l'une des stratégies de test les plus utilisées pour tester les programmes python. Cette stratégie est utilisée pour tester les unités ou les composants du code. Par unités ou composants, nous entendons des classes ou des fonctions du code. Les tests unitaires simplifient les tests de grands systèmes de programmation en testant de «petites» unités. Avec l'aide du concept ci-dessus, les tests unitaires peuvent être définis comme une méthode dans laquelle des unités individuelles de code source sont testées pour déterminer si elles renvoient la sortie souhaitée.

Dans nos sections suivantes, nous découvrirons les différents modules Python pour les tests unitaires.

module unittest

Le tout premier module pour les tests unitaires est le module unittest. Il est inspiré de JUnit et inclus par défaut dans Python3.6. Il prend en charge l'automatisation des tests, le partage du code de configuration et d'arrêt pour les tests, l'agrégation des tests en collections et l'indépendance des tests par rapport au cadre de reporting.

Voici quelques concepts importants pris en charge par le module unittest

Fixation de texte

Il est utilisé pour configurer un test afin qu'il puisse être exécuté avant de démarrer le test et démonté après la fin du test. Cela peut impliquer la création d'une base de données temporaire, de répertoires, etc. nécessaires avant de démarrer le test.

Cas de test

Le cas de test vérifie si une réponse requise provient de l'ensemble spécifique d'entrées ou non. Le module unittest comprend une classe de base nommée TestCase qui peut être utilisée pour créer de nouveaux cas de test. Il comprend deux méthodes par défaut -

  • setUp()- une méthode de crochet pour installer le dispositif d'essai avant de l'exercer. Ceci est appelé avant d'appeler les méthodes de test implémentées.

  • tearDown( - une méthode hook pour déconstruire le fixture de classe après avoir exécuté tous les tests de la classe.

Suite de tests

Il s'agit d'un ensemble de suites de tests, de cas de test ou les deux.

Testeur

Il contrôle l'exécution des cas de test ou des combinaisons et fournit le résultat à l'utilisateur. Il peut utiliser une interface graphique ou une simple interface de texte pour fournir le résultat.

Example

Le programme Python suivant utilise le module unittest pour tester un module nommé Fibonacci. Le programme aide à calculer la série de Fibonacci d'un nombre. Dans cet exemple, nous avons créé une classe nommée Fibo_test, pour définir les cas de test en utilisant différentes méthodes. Ces méthodes sont héritées de unittest.TestCase. Nous utilisons deux méthodes par défaut - setUp () et tearDown (). Nous définissons également la méthode testfibocal. Le nom du test doit commencer par le test des lettres. Dans le dernier bloc, unittest.main () fournit une interface de ligne de commande au script de test.

import unittest
def fibonacci(n):
   a, b = 0, 1
   for i in range(n):
   a, b = b, a + b
   return a
class Fibo_Test(unittest.TestCase):
   def setUp(self):
   print("This is run before our tests would be executed")
   def tearDown(self):
   print("This is run after the completion of execution of our tests")

   def testfibocal(self):
   self.assertEqual(fib(0), 0)
   self.assertEqual(fib(1), 1)
   self.assertEqual(fib(5), 5)
   self.assertEqual(fib(10), 55)
   self.assertEqual(fib(20), 6765)

if __name__ == "__main__":
   unittest.main()

Lorsqu'il est exécuté à partir de la ligne de commande, le script ci-dessus produit une sortie qui ressemble à ceci -

Production

This runs before our tests would be executed.
This runs after the completion of execution of our tests.
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK

Maintenant, pour être plus clair, nous changeons notre code qui a aidé à définir le module Fibonacci.

Considérez le bloc de code suivant comme exemple -

def fibonacci(n):
   a, b = 0, 1
   for i in range(n):
   a, b = b, a + b
   return a

Quelques modifications au bloc de code sont apportées comme indiqué ci-dessous -

def fibonacci(n):
   a, b = 1, 1
   for i in range(n):
   a, b = b, a + b
   return a

Maintenant, après avoir exécuté le script avec le code modifié, nous obtiendrons la sortie suivante -

This runs before our tests would be executed.
This runs after the completion of execution of our tests.
F
======================================================================
FAIL: testCalculation (__main__.Fibo_Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "unitg.py", line 15, in testCalculation
self.assertEqual(fib(0), 0)
AssertionError: 1 != 0
----------------------------------------------------------------------
Ran 1 test in 0.007s

FAILED (failures = 1)

La sortie ci-dessus montre que le module n'a pas réussi à fournir la sortie souhaitée.

Module Docktest

Le module docktest aide également aux tests unitaires. Il est également livré pré-emballé avec python. Il est plus facile à utiliser que le module unittest. Le module unittest est plus adapté aux tests complexes. Pour utiliser le module doctest, nous devons l'importer. La docstring de la fonction correspondante doit avoir une session python interactive avec leurs sorties.

Si tout va bien dans notre code, il n'y aura pas de sortie du module docktest; sinon, il fournira la sortie.

Exemple

L'exemple Python suivant utilise le module docktest pour tester un module nommé Fibonacci, qui aide à calculer la série Fibonacci d'un nombre.

import doctest
def fibonacci(n):
   """
   Calculates the Fibonacci number

   >>> fibonacci(0)
   0
   >>> fibonacci(1)
   1
   >>> fibonacci(10)
   55
   >>> fibonacci(20)
   6765
   >>>

   """
   a, b = 1, 1
   for i in range(n):
   a, b = b, a + b
   return a
      if __name__ == "__main__":
   doctest.testmod()

Nous pouvons voir que la docstring de la fonction correspondante nommée fib avait une session python interactive avec les sorties. Si notre code est correct, il n'y aurait pas de sortie du module doctest. Mais pour voir comment cela fonctionne, nous pouvons l'exécuter avec l'option –v.

(base) D:\ProgramData>python dock_test.py -v
Trying:
   fibonacci(0)
Expecting:
   0
ok
Trying:
   fibonacci(1)
Expecting:
   1
ok
Trying:
   fibonacci(10)
Expecting:
   55
ok
Trying:
   fibonacci(20)
Expecting:
   6765
ok
1 items had no tests:
   __main__
1 items passed all tests:
4 tests in __main__.fibonacci
4 tests in 2 items.
4 passed and 0 failed.
Test passed.

Maintenant, nous allons changer le code qui a aidé à définir le module Fibonacci

Considérez le bloc de code suivant comme exemple -

def fibonacci(n):
   a, b = 0, 1
   for i in range(n):
   a, b = b, a + b
   return a

Le bloc de code suivant aide avec les changements -

def fibonacci(n):
   a, b = 1, 1
   for i in range(n):
   a, b = b, a + b
   return a

Après avoir exécuté le script même sans l'option –v, avec le code modifié, nous obtiendrons la sortie comme indiqué ci-dessous.

Production

(base) D:\ProgramData>python dock_test.py
**********************************************************************
File "unitg.py", line 6, in __main__.fibonacci
Failed example:
   fibonacci(0)
Expected:
   0
Got:
   1
**********************************************************************
File "unitg.py", line 10, in __main__.fibonacci
Failed example:
   fibonacci(10)
Expected:
   55
Got:
   89
**********************************************************************
File "unitg.py", line 12, in __main__.fibonacci
Failed example:
   fibonacci(20)
Expected:
   6765
Got:
   10946
**********************************************************************
1 items had failures:
   3 of 4 in __main__.fibonacci
***Test Failed*** 3 failures.

Nous pouvons voir dans la sortie ci-dessus que trois tests ont échoué.