Εισαγωγή στη δοκιμή μονάδων στο Python

Μόλις τελειώσατε να γράψετε ένα κομμάτι κώδικα και αναρωτιέστε τι να κάνετε. Θα υποβάλετε ένα αίτημα έλξης και θα ζητήσετε από τους συμπαίκτες σας να αναθεωρήσουν τον κωδικό; Ή θα δοκιμάσετε με μη αυτόματο τρόπο τον κωδικό;

Πρέπει να κάνετε και τα δύο αυτά πράγματα, αλλά με ένα επιπλέον βήμα: πρέπει να ελέγξετε μονάχα τον κωδικό σας για να βεβαιωθείτε ότι ο κώδικας λειτουργεί όπως προορίζεται.

Οι δοκιμές μονάδας μπορεί να περάσουν ή να αποτύχουν και αυτό τους καθιστά μια εξαιρετική τεχνική για τον έλεγχο του κωδικού σας. Σε αυτό το σεμινάριο, θα δείξω πώς να γράψω μονάδες τεστ στο Python και θα δείτε πόσο εύκολο είναι να τα κάνετε στο δικό σας έργο.

Ξεκινώντας

Ο καλύτερος τρόπος για να καταλάβετε τις δοκιμές είναι εάν το κάνετε πρακτικό. Για το σκοπό αυτό, σε ένα αρχείο με την ονομασία name_function.py, θα γράψω μια απλή συνάρτηση που θα περιλαμβάνει ένα όνομα και επώνυμο και θα επιστρέψει ένα πλήρες όνομα

#Generate a formatted full name def formatted_name(first_name, last_name): full_name = first_name + ' ' + last_name return full_name.title()

Η συνάρτηση formatted_name () παίρνει το πρώτο και το επώνυμο και τα συνδυάζει με ένα κενό μεταξύ για να σχηματίσει ένα πλήρες όνομα. Στη συνέχεια κεφαλαιοποιεί το πρώτο γράμμα κάθε λέξης. Για να βεβαιωθείτε ότι αυτός ο κώδικας λειτουργεί, πρέπει να γράψετε κάποιον κώδικα που χρησιμοποιεί αυτήν τη λειτουργία. Στο names.py θα γράψω έναν απλό κώδικα που επιτρέπει στους χρήστες να εισάγουν το όνομα και το επώνυμό τους:

from name_function import formatted_name print("Please enter the first and last names or enter x to E[x]it.") while True: first_name = input("Please enter the first name: ") if first_name == "x": print("Good bye.") break last_name = input("Please enter the last name: ") if last_name == "x": print("Good bye.") break result = formatted_name(first_name, last_name) print("Formatted name is: " + result + ".")

Αυτός ο κωδικός εισάγει formatted_name () από το name_function.py και κατά την εκτέλεση, επιτρέπει στον χρήστη να εισάγει μια σειρά ονομάτων και επώνυμων και εμφανίζει τα μορφοποιημένα πλήρη ονόματα.

Μονάδα δοκιμής και δοκιμές

Υπάρχει μια ενότητα στην τυπική βιβλιοθήκη της Python που ονομάζεται unittest και περιέχει εργαλεία για τη δοκιμή του κωδικού σας. Ο έλεγχος μονάδας ελέγχει εάν όλα τα συγκεκριμένα μέρη της συμπεριφοράς της λειτουργίας σας είναι σωστά, γεγονός που θα διευκολύνει την ενσωμάτωσή τους μαζί με άλλα μέρη.

Η δοκιμαστική θήκη είναι μια συλλογή δοκιμαστικών μονάδων που αποδεικνύουν από κοινού ότι μια λειτουργία λειτουργεί όπως προορίζεται, μέσα σε ένα πλήρες φάσμα καταστάσεων στις οποίες μπορεί να βρεθεί αυτή η λειτουργία και ότι αναμένεται να χειριστεί. Η δοκιμαστική περίπτωση θα πρέπει να λαμβάνει υπόψη όλα τα πιθανά είδη εισόδου που θα μπορούσε να λάβει μια συνάρτηση από τους χρήστες, και ως εκ τούτου θα πρέπει να περιλαμβάνει δοκιμές για να αντιπροσωπεύει καθεμία από αυτές τις καταστάσεις.

Περνώντας μια δοκιμή

Ακολουθεί ένα τυπικό σενάριο για τη συγγραφή δοκιμών:

Πρώτα πρέπει να δημιουργήσετε ένα δοκιμαστικό αρχείο. Στη συνέχεια, εισαγάγετε τη μονάδα unittest, ορίστε την τάξη δοκιμών που κληρονομεί από το unittest. TestCase και τέλος, γράψτε μια σειρά μεθόδων για να ελέγξετε όλες τις περιπτώσεις συμπεριφοράς της λειτουργίας σας.

Υπάρχει μια γραμμή προς γραμμή εξήγηση κάτω από τον ακόλουθο κώδικα:

import unittest from name_function import formatted_name class NamesTestCase(unittest.TestCase): def test_first_last_name(self): result = formatted_name("pete", "seeger") self.assertEqual(result, "Pete Seeger")

Αρχικά, πρέπει να εισαγάγετε ένα unittest και τη συνάρτηση που θέλετε να δοκιμάσετε, formatted_name (). Στη συνέχεια, δημιουργείτε μια τάξη, για παράδειγμα NamesTestCase, η οποία θα περιέχει δοκιμές για τη συνάρτηση formatted_name (). Αυτή η τάξη κληρονομείται από την τάξη unittest.TestCase.

Το NamesTestCase περιέχει μια μεμονωμένη μέθοδο που ελέγχει ένα μέρος του formatted_name (). Μπορείτε να καλέσετε αυτήν τη μέθοδο test_first_last_name ().

Να θυμάστε ότι κάθε μέθοδος που ξεκινά με το "test_" θα εκτελείται αυτόματα όταν εκτελείτε το test_name_function.py.

Μέσα στη δοκιμαστική μέθοδο test_first_last_name (), καλείτε τη συνάρτηση που θέλετε να δοκιμάσετε και αποθηκεύσετε μια τιμή επιστροφής. Σε αυτό το παράδειγμα θα καλέσουμε το formatted_name () με τα ορίσματα "pete" και "seeger" και θα αποθηκεύσουμε το αποτέλεσμα στην προκύπτουσα μεταβλητή.

Στην τελευταία γραμμή θα χρησιμοποιήσουμε τη μέθοδο assert. Η μέθοδος επιβεβαίωσης επαληθεύει ότι ένα αποτέλεσμα που λάβατε ταιριάζει με το αποτέλεσμα που αναμένεται να λάβετε. Και σε αυτήν την περίπτωση γνωρίζουμε ότι η συνάρτηση formatted_name () θα επιστρέψει το πλήρες όνομα με κεφαλαία γράμματα, οπότε περιμένουμε το αποτέλεσμα "Pete Seeger". Για να το ελέγξετε, χρησιμοποιείται η μέθοδος του unittest assertEqual ().

self.assertEqual(result, “Pete Seeger”)

Αυτή η γραμμή ουσιαστικά σημαίνει: Συγκρίνετε την τιμή στην προκύπτουσα μεταβλητή με το "Pete Seeger" και αν είναι ίσες, είναι εντάξει, αλλά αν δεν με ενημερώσετε.

Κατά την εκτέλεση του test_name_function.py αναμένεται να πάρετε εντάξει που σημαίνει ότι η δοκιμή έχει περάσει.

Ran 1 test in 0.001s OK

Αποτυχία δοκιμής

Για να σας δείξω πώς αποτυγχάνει η δοκιμή που πρόκειται να τροποποιήσω μια συνάρτηση formatted_name () συμπεριλαμβάνοντας ένα νέο όρισμα μεσαίου ονόματος.

Έτσι θα ξαναγράψω τη λειτουργία έτσι ώστε να μοιάζει με αυτό:

#Generate a formatted full name including a middle name def formatted_name(first_name, last_name, middle_name): full_name = first_name + ' ' + middle_name + ' ' + last_name return full_name.title()

Αυτή η έκδοση του formatted_name () θα λειτουργήσει για άτομα με μεσαία ονόματα, αλλά όταν το δοκιμάσετε θα δείτε ότι η λειτουργία έχει διακοπεί για άτομα που δεν έχουν μεσαίο όνομα.

Έτσι, όταν εκτελείτε το test_name_function.py, θα έχετε την έξοδο που μοιάζει με αυτό:

Error Traceback (most recent call last): File “test_name_function.py”, line 7, in test_first_last_name result = formatted_name(“pete”, “seeger”) TypeError: formatted_name() missing 1 required positional argument: ‘middle_name’ Ran 1 test in 0.002s FAILED (errors=1)

Στην έξοδο θα δείτε πληροφορίες που θα σας πουν όλα όσα πρέπει να ξέρετε πού αποτύχει η δοκιμή:

  • Το πρώτο στοιχείο στην έξοδο είναι το Σφάλμα που σας λέει ότι τουλάχιστον μία δοκιμή σε περίπτωση δοκιμής είχε ως αποτέλεσμα σφάλμα.
  • Στη συνέχεια θα δείτε το αρχείο και τη μέθοδο με την οποία προέκυψε το σφάλμα.
  • Μετά από αυτό θα δείτε τη γραμμή στην οποία παρουσιάστηκε το σφάλμα.
  • Και τι είδους λάθος είναι, σε αυτήν την περίπτωση λείπει 1 όρισμα "middle_name".
  • Θα δείτε επίσης τον αριθμό των δοκιμών εκτέλεσης, τον χρόνο που απαιτείται για την ολοκλήρωση των δοκιμών και ένα μήνυμα κειμένου που αντιπροσωπεύει την κατάσταση των δοκιμών με αριθμό σφαλμάτων που προέκυψαν.

Τι να κάνετε όταν η δοκιμή έχει αποτύχει

Μια δοκιμή επιτυχίας σημαίνει ότι η λειτουργία συμπεριφέρεται σύμφωνα με αυτό που αναμένεται από αυτήν. Ωστόσο, μια αποτυχημένη δοκιμή σημαίνει ότι υπάρχει μεγαλύτερη διασκέδαση μπροστά σας.

Έχω δει μερικούς προγραμματιστές που προτιμούν να αλλάξουν το τεστ αντί να βελτιώσουν τον κώδικα - αλλά όχι σε αυτό. Αφιερώστε λίγο περισσότερο χρόνο για να επιλύσετε το πρόβλημα, καθώς θα σας βοηθήσει να κατανοήσετε καλύτερα τον κώδικα και να εξοικονομήσετε χρόνο μακροπρόθεσμα.

In this example, our function formatted_name() first required two  parameters, and now as it is rewritten it requires one extra: a middle name. Adding a middle name to our function broke the desired behavior of  it. Since the idea is not to make changes to the tests, the best solution is to make middle name optional.

After we do this the idea is to make the tests pass when the first and last name are used, for example “Pete Seeger”, as well as when first, last and middle names are used, for example “Raymond Red Reddington”. So  let’s modify the code of formatted_name() once again:

#Generate a formatted full name including a middle name def formatted_name(first_name, last_name,): if len(middle_name) > 0: full_name = first_name + ' ' + middle_name + ' ' + last_name else: full_name = first_name + ' ' + last_name return full_name.title()

Now the function should work for names with and without the middle name.

And to make sure it still works with “Pete Seeger” run the test again:

Ran 1 test in 0.001s OK
Και αυτό ήθελα να σας δείξω: Είναι πάντα καλύτερο να κάνετε αλλαγές στον κώδικά σας ώστε να ταιριάζουν με τις δοκιμές σας παρά με άλλα. Τώρα ήρθε η ώρα να προσθέσετε μια νέα δοκιμή για ονόματα που έχουν μεσαίο όνομα.

Προσθήκη νέων δοκιμών

Γράψτε μια νέα μέθοδο στην κλάση NamesTestCase που θα δοκιμάσει τα μεσαία ονόματα:

import unittest from name_function import formatted_name class NamesTestCase(unittest.TestCase): def test_first_last_name(self): result = formatted_name("pete", "seeger") self.assertEqual(result, "Pete Seeger") def test_first_last_middle_name(self): result = formatted_name("raymond", "reddington", "red") self.assertEqual(result, "Raymond Red Reddington")

Αφού εκτελέσετε τη δοκιμή, και οι δύο δοκιμές πρέπει να περάσουν:

Ran 2 tests in 0.001s OK
Σουτιέν!

Μπράβο!

Έχετε γράψει τις δοκιμές σας για να ελέγξετε αν η συνάρτηση λειτουργεί χρησιμοποιώντας ονόματα με ή χωρίς μεσαίο όνομα. Μείνετε συντονισμένοι για το μέρος 2 όπου θα μιλήσω περισσότερα για τις δοκιμές στο Python.

Ευχαριστούμε που το διαβάσατε! Δείτε περισσότερα άρθρα όπως αυτό στο προφίλ μου στο FreeCodeCamp: //www.freecodecamp.org/news/author/goran/ και άλλα διασκεδαστικά πράγματα που δημιουργώ στη σελίδα μου στο GitHub: //github.com/GoranAviani