Για να δοκιμάσετε ένα σύστημα, απομονώστε τα δευτερεύοντα εφέ

Η εξάλειψη των παρενεργειών είναι ένας από τους καλύτερους τρόπους για τη δημιουργία δοκιμαστικού κώδικα

Η εικόνα ενός αγώνα πυγμαχίας μεταξύ δύο αρσενικών μαχητών. Τα πρόσωπά τους είναι έξω από το πλαίσιο. Ο μαχητής στα αριστερά έχει αποστείλει έναν αριστερό γάντζο στον μαχητή στα δεξιά. Ο μαχητής στα δεξιά φέρει ένα κόκκινο κοντό με ένα μικρό σύμβολο της Σοβιετικής Ένωσης.

Το Nock είναι μια διάσημη βιβλιοθήκη γραμμένη σε JavaScript που είναι χρήσιμη για την απόκρυψη αιτημάτων δικτύου. Επιστρέφει μια στατική απόκριση για τις δοκιμές ώστε να μπορούν να εκτελούνται ακόμα και αν δεν υπάρχει διαθέσιμος διακομιστής HTTP.

Ωστόσο, είναι επίσης μια μυρωδιά.

Η προκύπτουσα σύζευξη μεταξύ της πηγής δεδομένων και του συστήματος κάτω από το τεστ είναι ένα κόστος που μπορεί να επηρεάσει τον επαναπροσδιορισμό κώδικα και τη συντηρησιμότητα.

Εδώ γιατί.

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

Ένα διάγραμμα που εμφανίζει ένα μπλοκ στα αριστερά με τη λεζάντα

Ο κώδικας έχει αξιοπρεπή κάλυψη. Ωστόσο, υπάρχουν ορισμένα προβλήματα με αυτό.

Εάν κάνετε αλλαγές στον τύπο περιεχομένου της απάντησης, πρέπει να αλλάξετε τις δοκιμές, ακόμη και αν η συμπεριφορά του κώδικα παραμένει η ίδια:

Το ίδιο ισχύει και αν κάνετε αλλαγές στη διεύθυνση URL, τις κεφαλίδες ή τις παραμέτρους που ο Nock σβήνει. Πρέπει να αλλάξετε τις δοκιμές ακόμη και αν η συμπεριφορά του συστήματος παραμένει η ίδια:

Η λειτουργία "Δημιουργία λίστας αναρτήσεων" είναι η Σύστημα Under Test (SUT). Τα δεδομένα από την κλήση HTTP είναι η Πηγή Δεδομένων.

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

Ένα διάγραμμα που δείχνει ένα μπλοκ στα αριστερά με τη λεζάντα

Για περιβάλλον δοκιμής, μπορείτε να κάνετε την ένεση μιας "πηγής δεδομένων εντός μνήμης". Για την παραγωγή, μπορείτε να χρησιμοποιήσετε την "Πηγή δεδομένων διακομιστή HTTP".

Η "γενική διεπαφή" στο προηγούμενο JSFiddle είναι η μέθοδος "find posts title". Ανεξάρτητα από το πώς κατασκευάζετε τη διεπαφή, έχετε τον έλεγχο όλων των καλούντων. Επομένως, οι αλλαγές είναι απλές. Ο Martin Fowler καλεί μια "μη δημοσιευμένη διεπαφή".

Από την άλλη πλευρά, αν ο διακομιστής σπάσει τη σύμβαση του Δημοσιευμένου Διεπαφή, πείτε ότι το χαρακτηριστικό κλάσης αλλάζει από post-title στο άρθρο-title, πρέπει μόνο να αλλάξετε την εφαρμογή Source Data. Δεν χρειάζεται να κάνετε αλλαγές παντού.

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

Με το νέο σχέδιο, έχετε αποσυνδέσει την Πηγή Δεδομένων από το Σύστημα Under Test. Ως εκ τούτου, μπορείτε να καταργήσετε το Nock.

Ο νέος σχεδιασμός μειώνει επίσης την εργασία που απαιτείται για να προσθέσετε έναν νέο κανόνα στο σύστημα χωρίς αντιγραφή / επικόλληση:

Παρόλα αυτά, η "Πηγή δεδομένων διακομιστή HTTP" έχει κάποια μη δοκιμασμένη λογική μέσα στην ιδιωτική λειτουργία "τίτλος ερωτημάτων από το html".

Για να το δοκιμάσετε, μπορείτε να επαναλάβετε το ίδιο μοτίβο. Πιέστε τις παρενέργειες και κάντε το μηχανισμό "get request" pluggable στην "Πηγή δεδομένων διακομιστή HTTP". Με αυτόν τον τρόπο, μπορείτε να δοκιμάσετε τον κώδικα χωρίς να χρειάζεται ο Nock:

Δεδομένου ότι έχετε ήδη δοκιμές για να επιβεβαιώσετε ότι ο "κατάλογος των τίτλων των θέσεων" λειτουργεί με μια "Πηγή δεδομένων στην μνήμη", μπορείτε να αποφασίσετε να δοκιμάσετε την προέλευση δεδομένων μεμονωμένα για να βεβαιωθείτε ότι επιστρέφει το σωστό αποτέλεσμα:

Έχετε ωθήσει πλήρως την παρενέργεια από τη λογική. Σε αυτή την περίπτωση, η πραγματική λειτουργία "λάβετε αίτημα" είναι η παρενέργεια. Τώρα μπορείτε να χρησιμοποιήσετε το Nock για να το καλύψετε.

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

Το Nock είναι χρήσιμο να αποσυνδέει τη σύνδεση στο στρώμα HTTP και να παρέχει μια στατική απόκριση. Ωστόσο, χρησιμοποιήστε το με φειδώ. Για κάθε δοκιμή που στροβιλίζετε, αυξάνετε τη σημαντική συζεύξη και το κόστος αλλαγής.

Εάν δεν χρησιμοποιείται με φειδώ, ο Nock μπορεί να δημιουργήσει μια κόλαση.

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

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

Απομονώστε τις παρενέργειες και περιορίστε τη χρήση εργαλείων όπως το Nock στα όρια της εφαρμογής.

Αυτό θα σας δώσει αρκετή εμπιστοσύνη για να κάνετε αλλαγές και να μην σπάσετε τα πράγματα.

Συμμετοχή στον αγώνα, ώθηση των παρενεργειών, και στη συνέχεια ... Ξεκλειδώστε.

Ευχαριστώ για την ανάγνωση. Αν έχετε κάποια σχόλια, επικοινωνήστε μαζί μου στο Twitter, το Facebook ή το Github.

Χάρη στον Eduardo Slompo και τον Guilherme J. Tramontina για τη διορατική τους ανατροφοδότηση σε αυτή τη θέση.