js δοκιμή. Τεστ Γνώσεων JavaScript - Βασικά

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

Αυτή η διαδικασία θα πρέπει να περιλαμβάνει ένα σύνολο εργαλείων ελέγχου ποιότητας και απόδοσης για τον προγραμματιστή. Τέτοια εργαλεία μπορεί να είναι: δοκιμή μονάδας και ενσωμάτωσης, συνεχής ενσωμάτωση (Continuous Integration, CI), συλλογή και ανάλυση διαφόρων μετρήσεων (για παράδειγμα, πολύ μεγάλες μέθοδοι στο nDepend), έλεγχος συμμόρφωσης με τις απαιτήσεις των JsLint, FxCop κ.λπ.

Σε αυτό το άρθρο, θέλω να σας πω πώς να εκτελέσετε σωστά τον αυτόματο έλεγχο μονάδας και ενσωμάτωσης του προϊόντος σας σε JavaScript. Στην πραγματικότητα, η JavaScript δεν διαφέρει από αυτή την άποψη από την Java ή την C#.

Agile, TDD και BDD

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

Υπάρχουν επίσης τεχνικές προγραμματισμού που απαιτούν από εσάς να ξεκινήσετε τη λογική κωδικοποίησης γράφοντας ένα τεστ μονάδας: Ανάπτυξη βάσει δοκιμής (TDD) και Ανάπτυξη βάσει συμπεριφοράς (BDD). Συχνά χρησιμοποιούνται στη διαδικασία Agile. Ας εξετάσουμε τα χαρακτηριστικά τους με περισσότερες λεπτομέρειες.

Δοκιμαστική Ανάπτυξη

Η ανάπτυξη βάσει δοκιμής είναι μια επαναληπτική διαδικασία κωδικοποίησης που επαναλαμβάνει τα ακόλουθα τέσσερα βήματα:

Βήμα 1. Πριν προσθέσετε ένα νέο κομμάτι λογικής, δημιουργήστε ένα τεστ μονάδας για να ελέγξετε αυτήν τη λογική.

Βήμα 2. Εκτελέστε το τεστ και βεβαιωθείτε ότι είναι Δενπερνάει?

Βήμα 3. Γράψτε τον απλούστερο κώδικα που θα κάνει τη δοκιμή να περάσει.

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

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

Δοκιμές διπλών

Η διαίρεση των βοηθητικών αντικειμένων που χρησιμοποιούνται στη δοκιμή μονάδων σε κατηγορίες προέρχεται από το βιβλίο xUnit Test Patterns του Gerard Meszaros. Αυτές οι κατηγορίες ονομάζονται συλλογικά "test doubles" (test doubles). Οι Doublers είναι των παρακάτω τύπων:

  • απομίμηση;
  • Ανδρείκελο.

Στέλεχος τιμές εξόδουγια τα οποία ορίζονται εκ των προτέρων. Χρησιμοποιείται για τη μίμηση της διεπαφής ενός εξαρτημένου στοιχείου.

Κοροϊδεύωείναι ένα βοηθητικό αντικείμενο η ΣΥΜΠΕΡΙΦΟΡΑπου ορίζεται εκ των προτέρων. Χρησιμοποιείται για να μιμηθεί τη διεπαφή ενός εξαρτημένου στοιχείου και να ελέγξει εάν χρησιμοποιείται σωστά κατά τη διάρκεια της δοκιμής.

Κατάσκοποςείναι ένα βοηθητικό αντικείμενο για την επιθεώρηση που ονομάζεται μέθοδοι και παραμέτρους που τους μεταβιβάζονται κατά τη διάρκεια της δοκιμής.

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

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

Η διαφορά μεταξύ Stub και Mock είναι ο τρόπος με τον οποίο επαληθεύονται τα αποτελέσματα των δοκιμών. Στην περίπτωση του Stub, η κατάσταση του αντικειμένου ελέγχεται στο τέλος της δοκιμής. Στην περίπτωση του Mock, η δοκιμή ελέγχει ότι το αντικείμενο χρησιμοποιείται ακριβώς όπως περιγράφεται κατά την εγγραφή. Λεπτομέρειες μπορείτε να βρείτε στη σημείωση Mocks Aren "t Stubs του Martin Fowler, και θα δώσω εδώ μόνο ένα παράδειγμα.

Στέλεχος Κοροϊδεύω
"η δοκιμαστική σύνδεση πρέπει να ξεκινήσει τη ψηφοφορία": συνάρτηση () ( this.client.url = "/my/url"; sinon.stub(ajax, "poll").returns(()); this.client.connect(); sinon.assert.calledWith(ajax.poll, "/my/url"); ) "η δοκιμή σύνδεσης πρέπει να ξεκινήσει τη ψηφοφορία": συνάρτηση () ( this.client.url = "/my/url"; var mock = sinon.mock(ajax) mock.expects("poll") .withArgs("/my/url ").returns(()); this.client.connect(); mock.verify(); )

Ανάπτυξη με γνώμονα τη συμπεριφορά

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

Βήμα 1. Καθορισμός λειτουργικών απαιτήσεων για την εφαρμοσμένη ενότητα με τη μορφή δοκιμών.

Βήμα 2. Κωδικοποίηση ενότητας.

Βήμα 3. Έλεγχος ότι πληρούνται όλες οι επιθυμίες του πελάτη ή του επιχειρηματικού αναλυτή () ελέγχοντας τα αποτελέσματα των δοκιμών που εκτελούνται.

Όταν γράφετε δοκιμές σε στυλ BDD, είναι πολύ βολικό να χρησιμοποιείτε αντικείμενα Mock λόγω του γεγονότος ότι αντικατοπτρίζουν τέλεια τις λειτουργικές απαιτήσεις για το στοιχείο. Έτσι, οι δοκιμές στη διαδικασία BDD μπορούν να χρησιμεύσουν ως μια επίσημη αναπαράσταση της εργασίας ( ιστορία χρήστη) σε όρους Scrum, το οποίο σας επιτρέπει να εξοικονομήσετε χρόνο στη σύνταξη τεχνικών προδιαγραφών και τεκμηρίωσης για το τελικό προϊόν.

Τι πρέπει να είναι ένα πλαίσιο δοκιμής μονάδας JavaScript;

Μια πλήρης μονάδα JavaScript και ένα εργαλείο δοκιμής ενοποίησης πρέπει να αποτελείται από τα ακόλουθα στοιχεία:

  • Βιβλιοθήκη ισχυρισμών (ένα σύνολο μεθόδων για τον έλεγχο της κατάστασης του στοιχείου στο τέλος κάθε δοκιμής).
  • Mock βιβλιοθήκη (ένα εργαλείο για τη δημιουργία Mock αντικειμένων και άλλων «κατανόητων μελετών»).
  • Δοκιμαστικός δρομέας (όργανο αυτόματη εκκίνησηδοκιμές με υποστήριξη για τα περισσότερα προγράμματα περιήγησης, συμπεριλαμβανομένων των προγραμμάτων περιήγησης iOS και Android).
  • Μπλοκ σύνδεσης σε δημοφιλή συστήματα συνεχούς ολοκλήρωσης (Continuous Integration).

Στρατηγικές δοκιμών μονάδων JavaScript

Σήμερα, υπάρχουν τρεις στρατηγικές για τη δοκιμή μονάδων κώδικα JavaScript (για περισσότερες λεπτομέρειες, ανατρέξτε στο τρίτο κεφάλαιο του βιβλίου του Christian Johansen, Test-Driven JavaScript Development):

  • στο πρόγραμμα περιήγησηςδοκιμές?
  • ακέφαλοςδοκιμές?
  • Δοκιμές στην πορεία JsTestDriver.

Η δοκιμή εντός προγράμματος περιήγησης περιλαμβάνει την εκτέλεση όλων των δοκιμών ενότητας και ενσωμάτωσης από μια σελίδα HTML που ανοίγει μόνος του ο προγραμματιστής στα απαιτούμενα προγράμματα περιήγησης. Αυτή η προσέγγιση είναι απλή και διαισθητική. Ωστόσο, το μειονέκτημά του είναι ότι δεν προβλέπει τη δυνατότητα συμπερίληψης τέτοιων δοκιμών στο Continuous Integration. Επίσης, η μη αυτόματη εκκίνηση μιας σελίδας HTML σε δέκα ή περισσότερα προγράμματα περιήγησης και το συνεχές πάτημα του "F5" μπορεί να είναι κουραστική για έναν προγραμματιστή.

Η δοκιμή χωρίς κεφαλή σημαίνει ότι όλος ο κώδικας JavaScript ελέγχεται σε έναν εξομοιωτή, ο οποίος μπορεί να γραφτεί σε Java, Ruby, JavaScript, C++ κ.λπ. Ο πιο διάσημος εξομοιωτής με διαφορά είναι το PhantomJS, το οποίο είναι α webkit, ξεκίνησε από γραμμή εντολών. Μεταξύ των πλεονεκτημάτων του εξομοιωτή, μπορεί να σημειωθεί ότι μπορεί να χρησιμοποιηθεί εύκολα στη Συνεχή Ενοποίηση και επίσης ότι σας επιτρέπει να αυτοματοποιήσετε την εκκίνηση όλων των δοκιμών από τη γραμμή εντολών. Ωστόσο, αυτή η προσέγγιση έχει ένα σημαντικό μειονέκτημα - ο κώδικας δεν δοκιμάζεται σε πραγματικά προγράμματα περιήγησης, επομένως υπάρχει κίνδυνος να χαθούν σφάλματα του προγράμματος περιήγησης που δεν αναπαράγονται στον εξομοιωτή. Πριν από την εμφάνιση του JsTestDriver, μπορούσατε συχνά να δείτε τη δοκιμή In-Browser σε συνδυασμό με τη δοκιμή Headless, καθώς αλληλοσυμπληρώνονται τόσο καλά.

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

Το JavaScript δεν είναι πια κέικ!

Υποθέτω ότι δεν χρειάζεται να σας εξηγήσω ότι σήμερα η JavaScript δεν είναι απλώς μια γλώσσα για να εμπλουτίσετε τα πράγματα. εμφάνισηεφαρμογές. Αλλά θα εξηγήσω πάντως και θα κάνω μια μικρή εισαγωγή, γιατί μετά θα πληρωθώ περισσότερο περισσότερα λεφτά! 🙂 Έτσι, οι εποχές που χρησιμοποιούνταν η JavaScript για αστεία ή για δημιουργία μενού έχουν παρέλθει για πάντα. Τώρα είναι μια ανεξάρτητη γλώσσα που λειτουργεί εξίσου καλά τόσο στον πελάτη όσο και στον διακομιστή. Ο ρόλος της JavaScript έχει αυξηθεί σημαντικά, πράγμα που σημαίνει ότι όταν γράφετε κώδικα, δεν πρέπει να ντρέπεστε να χρησιμοποιείτε πρακτικές που έχουν αποδειχθεί σε άλλες γλώσσες προγραμματισμού.

Τι εννοώ με τον όρο πρακτικές και παραδείγματα; Φυσικά, το αρχιτεκτονικό πρότυπο MVC (ελεγκτής προβολής μοντέλου) και τα πρότυπα οργάνωσης κώδικα. Ακολουθώντας αυτά τα απλά κόλπα, θα μπορείτε να γράψετε καλύτερο κώδικα που όχι μόνο θα είναι εύκολο να διατηρηθεί, αλλά θα έχει και τη δυνατότητα να ελέγχεται αυτόματα.

Κανόνες για καλές δοκιμές

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

Το λάθος των περισσότερων δοκιμαστών

Δεν είναι μυστικό ότι ο πιο δημοφιλής τρόπος δοκιμών ήταν πάντα ένα απλό τεστ στα μάτια. Η ουσία του είναι απλή έως ατιμωτική - έγραψα μερικές χιλιάδες γραμμές κώδικα, έλυσα το πρόβλημα και ξεκίνησα τη δημιουργία μου. Έπαιξα, έκανα κλικ - όλα φαίνεται να λειτουργούν, μπορείτε να τα ανεβάσετε στον διακομιστή μάχης. Όλα είναι εξαιρετικά απλά και με τη δέουσα προσοχή του προγραμματιστή (ιδανικά, ένα άτομο με το ψευδώνυμο "δοκιμαστής"), μπορείτε να βασιστείτε στη σωστή λειτουργία της εφαρμογής.

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

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

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

Κάποτε μου ανέθεσαν να αναπτύξω ένα μικρό πρόγραμμα. Από πλευράς λειτουργικότητας, το έργο έμοιαζε με το πιο απλό CRM, το οποίο υλοποίησα στο συντομότερο δυνατό χρόνο. Έχοντας λάβει την οφειλόμενη αμοιβή, παρέδωσα όλες τις πηγές στον πελάτη και ξέχασα το έργο για οκτώ μήνες. Τότε άρχισαν τα πιο ενδιαφέροντα. Ο πελάτης αποφάσισε να επεκτείνει σοβαρά τη λειτουργικότητα του προγράμματος και με κάλεσε για βοήθεια. Φυσικά, το πήρα και άρχισα να σμιλεύω λειτουργία μετά από λειτουργία... Στην αρχή δεν ήταν δύσκολο, αλλά όταν ήρθε η συνολική ενσωμάτωση της λειτουργικότητας, ένα βουητό σμήνος από σφάλματα όρμησε προς την κατεύθυνση μου. Κομμάτια κώδικα άρχισαν να συγκρούονται και έπρεπε να αφιερώσω πολύ χρόνο στην επίλυση των συγκρούσεων. «Λοιπόν, πώς δεν είδατε ότι υπήρχε πρόβλημα με την αίτησή σας;» θα ρωτήσουν οι αναγνώστες. Θα απαντήσω: Το ξεκίνησα, αλλά λόγω του ότι η εφαρμογή μεγάλωσε, απλά δεν είχα τον χρόνο και τα νεύρα να δοκιμάσω μαζικά όλη τη λειτουργικότητα. Περιορίστηκα να δοκιμάζω μόνο μεμονωμένες λειτουργίες και πλήρωσα γενναιόδωρα για αυτό. Το ηθικό δίδαγμα της ιστορίας: «Σκεφτείτε τις δοκιμές ως αναπόσπαστο μέρος της ανάπτυξης».

Οι δοκιμές μονάδων είναι σαν μια ασημένια σφαίρα

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

Μετά την ολοκλήρωση της ανάπτυξης νέο χαρακτηριστικό(είναι δυνατή η εγγραφή δοκιμών πριν από την έναρξη της ανάπτυξης) ο προγραμματιστής γράφει έναν ειδικό κώδικα για να δοκιμάσει τον κώδικά του. Πρέπει να προσομοιώνει διαφορετικές καταστάσεις και να επιστρέφει τιμές. Για παράδειγμα, γράψαμε μια συνάρτηση για την περικοπή διαστημάτων (trim). Για να ελέγξουμε την απόδοσή του, πρέπει να προετοιμάσουμε αρκετές δοκιμές που θα μας επιτρέψουν να ισχυριστούμε ότι:

  • όταν περνάμε τη συμβολοσειρά "string" παίρνουμε "string" ως έξοδο.
  • όταν περνάμε τους όρους "γραμμή 9" στην έξοδο παίρνουμε "γραμμή 9".

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

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

Τεστ!= έξτρα κωδικός

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

Όταν δεν υπάρχει χρόνος για εξετάσεις

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


Όσο για τις αυστηρές προθεσμίες, συμφωνώ, αλλά είμαι έτοιμος να διαφωνήσω για το μέρος του επιπλέον κώδικα. Από τη μία πλευρά, ναι - οι δοκιμές απαιτούν πρόσθετο κώδικα, και ως εκ τούτου τον χρόνο να τον γράψετε. Από την άλλη, αυτός ο κωδικός παίζει το ρόλο των αερόσακων σε ένα αυτοκίνητο και σίγουρα θα αποδώσει όσο μεγαλώνει η εφαρμογή.
  • Το Cristian Johansen Test-Driven JavaScript Development (goo.gl/mE6Is) είναι ένα από τα λίγα βιβλία που εξετάζει το JavaScript από τη σκοπιά της δοκιμαστικής γραφής.
  • Ο John Resing, Beer Bibo JavaScript Ninja Secrets (goo.gl/xquDkJ) είναι ένα καλό βιβλίο που θα είναι χρήσιμο κυρίως για προγραμματιστές μεσαίων JS. Το βιβλίο συζητά λεπτομερώς τα ζητήματα της σύνταξης αποτελεσματικού κώδικα πολλαπλών προγραμμάτων περιήγησης, τις αποχρώσεις του χειρισμού συμβάντων και πολλά άλλα καλούδια.
  • David Flanagan JavaScript. Πλήρης οδηγός» (goo.gl/rZjjk) - Το βιβλίο έχει ανατυπωθεί έξι φορές και κάθε κυκλοφορία είναι μπεστ σέλερ. Πράγματι, αυτό είναι το πιο αναλυτικός οδηγόςσε JavaScript, την οποία κάθε προγραμματιστής JS πρέπει να διαβάσει τουλάχιστον μία φορά.
  • Δοκιμές μονάδων PhantomJS + JSCoverage + QUnit ή κονσόλας JS με υπολογισμό κάλυψης (goo.gl/FyQ38) - ο συγγραφέας του άρθρου δείχνει τη χρήση μιας δέσμης από τα παραπάνω πακέτα για τη συλλογή στατιστικών στοιχείων και τον υπολογισμό του ποσοστού κάλυψης κώδικα από δοκιμές.
  • Χρήσιμες περιπτώσεις χρήσης PhantomJS - Αυτή η σελίδα δείχνει μεγάλο αριθμό χρήσεων μάχης PhantomJS.

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

Δεν ελέγχεται όλος ο κώδικας

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

  • Δεν χρειάζεται να γράψετε μεγάλες συναρτήσεις. Κάθε συνάρτηση θα πρέπει να λύνει ένα πρόβλημα, όχι 100500 πιθανές καταστάσεις. Για παράδειγμα, δεν χρειάζεται να κλείσετε τον κωδικό για την αποστολή δεδομένων στον διακομιστή στη λειτουργία που είναι υπεύθυνη για την προετοιμασία τους.
  • Μια συνάρτηση με περισσότερες από δέκα γραμμές κώδικα είναι πιθανότατα κακή συνάρτηση.
  • Λογική και παρουσίαση δεν πρέπει ποτέ να πάνε μαζί.

QUnit - ένα κλασικό του είδους από τους δημιουργούς του jQuery

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


Κατεβάστε τελευταία έκδοση QUnit μπορείτε από τον επίσημο ιστότοπο. Η βιβλιοθήκη διατίθεται ως ένα μόνο αρχείο JS και CSS. Ας υποθέσουμε ότι έχετε καταλάβει πώς να φορτώσετε τα απαραίτητα εξαρτήματα και αν ναι, τότε ήρθε η ώρα να γράψετε μια δοκιμαστική δοκιμή. Ας μην πάμε μακριά και ας προσπαθήσουμε να δοκιμάσουμε τη συνάρτηση trim().

Για να δείξω τις δοκιμές, δημιούργησα ένα απλό έργο με την ακόλουθη δομή:

  • index.html - το κύριο αρχείο που θα εμφανίζει τα αποτελέσματα της δοκιμής.
  • qunit-1.12.0.js - Αρχείο βιβλιοθήκης QUnit;
  • example.js - ένα αρχείο που περιέχει τον κώδικα για δοκιμή (στην περίπτωσή μας, η περιγραφή της συνάρτησης trim()).
  • test.js - αρχείο με δοκιμές.
  • qunit-1.12.0.css - στυλ σχεδιασμού αναφοράς με δοκιμές.

Τα περιεχόμενα του αρχείου index.html και test.js εμφανίζονται στις λίστες 1 και 2. Η δεύτερη λίστα που μας ενδιαφέρει περισσότερο είναι η δήλωση της υπό δοκιμή συνάρτησης (trim()) και ο κωδικός δοκιμής για να επαληθεύσουμε ότι λειτουργεί . Σημειώστε ότι η ίδια η συνάρτηση trim() μπορεί να βρίσκεται οπουδήποτε, την έβαλα στη δεύτερη λίστα μόνο για να εξοικονομήσω χώρο στο αρχείο καταγραφής.
Τώρα ας δούμε τις ίδιες τις δοκιμές. Η βιβλιοθήκη QUnit.js μας προσφέρει μια σειρά από μεθόδους:

  • test() - περιτύλιγμα για περιγραφή δοκιμής.
  • ok() - ο ισχυρισμός σάς επιτρέπει να ελέγξετε την αλήθεια της πρώτης παραμέτρου. Στο παράδειγμά μας, το περνάω μια κλήση στη συνάρτηση trim() που ορίσαμε και τη συγκρίνω με την τιμή που περιμένω να λάβω. Εάν η συνθήκη είναι αληθής, το τεστ έχει περάσει.
  • equal() - η μέθοδος σας επιτρέπει να ελέγξετε την ισότητα της πρώτης και της δεύτερης παραμέτρου. Παρατηρήστε αμέσως ότι αυτή τη μέθοδοεκτελεί έναν μη αυστηρό έλεγχο, επομένως είναι κατάλληλο μόνο για βαθμωτές.
  • Η notEqual() είναι το αντίθετο της equal(). Εκτελείται εάν η πρώτη τιμή δεν είναι ίση με τη δεύτερη.
  • strictEqual() - παρόμοια με την equal() με μία διαφορά - χρησιμοποιεί αυστηρό έλεγχο (δηλαδή ελέγχει και τον τύπο δεδομένων).
  • notStrictEqual() - το αντίθετο του strictEqual();
  • deepEqual() - μέθοδος για αναδρομικές δηλώσεις, που χρησιμοποιείται για αρχέγονους, πίνακες, αντικείμενα.
  • notDeepEqual() - το αντίθετο του deepEqual();
  • Το raises() είναι ένας ισχυρισμός για τον έλεγχο συναρτήσεων επανάκλησης που δημιουργούν μια εξαίρεση.

Στη δεύτερη λίστα, έδειξα ξεκάθαρα πώς να εφαρμόσουμε αυτές τις μεθόδους στην πράξη. Εάν εκτελέσετε μια δοκιμαστική περίπτωση σε αυτή τη φόρμα, τότε όλες οι δοκιμές θα περάσουν επιτυχώς (δείτε το αντίστοιχο σχήμα). Για να δω τη διαφορά μεταξύ επιτυχίας και αποτυχίας τεστ, άλλαξα ελαφρώς τον κωδικό μιας δοκιμής. Πρόσθεσα εσκεμμένα ένα λανθασμένο αποτέλεσμα στη γραμμή με το τεστ χρησιμοποιώντας τη strictEqual() (δείτε το αντίστοιχο σχήμα).

Λίστα 1. Περιεχόμενα του αρχείου index.html Δοκιμή με QUnit



Με τη δοκιμή απλών συναρτήσεων φαίνεται κατανοητό. Σε κάθε περίπτωση, δεν έχω να προσθέσω κάτι άλλο. Στη συνέχεια, πρέπει να πάρετε τον πραγματικό κωδικό και να προσπαθήσετε να γράψετε δοκιμές μόνοι σας. Ας δούμε μια άλλη εργασία που αντιμετωπίζεται συχνά για προγραμματιστές JavaScript - τη δοκιμή ασύγχρονων συναρτήσεων. Μια εφαρμογή γεμάτη με κώδικα JavaScript αλληλεπιδρά κατά 99% με την πλευρά του διακομιστή χρησιμοποιώντας AJAX. Είναι επίσης αδύνατο να αφήσετε αυτόν τον κωδικό χωρίς δοκιμή, αλλά η σύνταξη δοκιμών θα είναι λίγο διαφορετική. Εξετάστε ένα παράδειγμα:

AsyncTest("myAsyncFunc()", συνάρτηση () ( setTimeout(function () ( ok(myAsyncFunc() == true, "Τα δεδομένα πέρασαν επιτυχώς"); start(); ), 500); ));

Η κύρια διαφορά μεταξύ αυτού του παραδείγματος και του προηγούμενου είναι ότι χρησιμοποιείται το asyncTest() αντί για το wrapper test(), δηλώνοντας έτσι ευθέως ότι ενδιαφέρομαι για ασύγχρονες δοκιμές. Στη συνέχεια, ξεκινάω ένα χρονικό όριο 500 χιλιοστών του δευτερολέπτου. Κατά τη διάρκεια αυτής της περιόδου, η συνάρτηση myAsyncFunc() θα πρέπει να μεταφέρει δεδομένα στον δοκιμαστικό διακομιστή και, εάν όλα είναι εντάξει, να επιστρέψει true. Εδώ έρχεται η πιο ενδιαφέρουσα στιγμή. Όταν καλείται η asyncTest(), το νήμα της εκτέλεσης διακόπτεται και όταν ολοκληρωθεί η δοκιμή, πρέπει να ξεκινήσει από μόνο του. Για τον έλεγχο της ροής της εκτέλεσης, το QUnit παρέχει τις μεθόδους start() και stop().


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

AsyncTest("myAsyncFunc()", συνάρτηση () ( expect(3); // Κάντε τρεις δοκιμές εδώ ok(myAsyncFunc(), "Κάνοντας τον κόσμο καλύτερο 1"); ok(myAsyncFunc(), "Κάνοντας τον κόσμο καλύτερο 2 ") ; ok(myAsyncFunc(), "Κάνοντας τον κόσμο ένα καλύτερο μέρος 3"); setTimeout(function () (start(); ), 3000); ));

Δοκιμή για προσαρμοσμένες ενέργειες

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

Καταχώριση 3. Συνάρτηση πληκτρολόγησης καταγραφής KeyLogger(target) ( if (!(αυτή η περίπτωση του KeyLogger)) (επιστροφή νέου KeyLogger(target); ) this.target = target; this.log = ; var self = this; this.target. off ("keydown").on("keydown", function(event) (self.log.push(event.keyCode); ));

Τώρα ας δοκιμάσουμε αυτή τη λειτουργία για δοκιμή. Πρώτα απ 'όλα, στο σώμα της δοκιμής, πρέπει να προσομοιώσουμε το πατημένο πλήκτρο. Ο ευκολότερος τρόπος για να το κάνετε αυτό είναι με τη βιβλιοθήκη jQuery, η οποία σας επιτρέπει να δημιουργήσετε ένα συμβάν σε μερικές γραμμές κώδικα (βλ. Λίστα 4).

Καταχώριση 4. Κωδικός δοκιμής για τη δοκιμή KeyLogger ("Δοκιμή εγγραφής κλειδιού", συνάρτηση () ( var event, $doc = $(document), keys = KeyLogger($doc); event = $.Event("keydown"); event .keyCode = 9; $doc.trigger(event); equal(keys.log.length, 1, "Key loged"); equal(keys.log, 9, "Key πατήθηκε με τον κωδικό 9 καταγεγραμμένο"); ));

Στην αρχή της καταχώρισης με το τεστ, ετοιμάζω ένα συμβάν για να μιμηθεί ένα πάτημα πλήκτρων - "keydown". Θα μας ενδιαφέρει να πατήσουμε το πλήκτρο Tab (κωδικός 9). Στη συνέχεια, χρησιμοποιώντας τη μέθοδο trigger(), στέλνω το προετοιμασμένο συμβάν, μετά το οποίο μπορώ να ξεκινήσω τη δοκιμή. Αρχικά, ελέγχουμε τη μεγάλη εικόνα - εάν πατήθηκε ένα πλήκτρο και μετά τον κωδικό του.

DOM υπό το πρόσχημα των δοκιμών

Εφόσον το Qunit.js σάς επιτρέπει να δοκιμάζετε προσαρμοσμένες ενέργειες, η σύνταξη δοκιμών για το DOM δεν θα πρέπει επίσης να αποτελεί πρόβλημα. Αυτό είναι αλήθεια και το παρακάτω παράδειγμα θα επιβεβαιώσει τα λόγια μου. Δεν θα το σχολιάσω, απλά ρίξτε μια ματιά στον κώδικα και όλα θα ξεκαθαρίσουν:

Test("Προσθήκη νέου στοιχείου div", συνάρτηση () ( var $fixture = $("#qunit-fixture"); $fixture.append("

Αυτό είναι το νέο div
"); equal($("div", $fixture).length, 1, "New div προστέθηκε με επιτυχία!"); ));

PhantomJS - εκτέλεση δοκιμών από την κονσόλα


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

Το έργο PhantomJS λύνει αυτό το πρόβλημα αρκετά κομψά. Αυτό δεν είναι απλώς ένα άλλο πλαίσιο για τη σύνταξη δοκιμών μονάδας, αλλά μια πλήρης έκδοση κονσόλας του κινητήρα WebKit. Για να το θέσω απλά, αυτή η εφαρμογή μιμείται ένα πρόγραμμα περιήγησης. Με τη βοήθεια του PhantomJS, δεν είναι μόνο η αυτοματοποίηση της επαλήθευσης της εκτέλεσης της δοκιμής, αλλά και η επίλυση πολλών εργασιών που αργά ή γρήγορα προκύπτουν ενώπιον ενός προγραμματιστή: λήψη των αποτελεσμάτων της απόδοσης σελίδων σε ένα αρχείο (PNG, JPG), λειτουργίες παρακολούθησης δικτύου (ταχύτητα φόρτωσης, συνολική απόδοση κ.λπ.), εξομοίωση ενεργειών χρήστη και ούτω καθεξής. Σας συνιστώ να μην είστε τεμπέλης και να διαβάσετε την επίσημη τεκμηρίωση για αυτό το έργο, σίγουρα θα βρείτε κάτι ενδιαφέρον για τον εαυτό σας.

Το PhantomJS μπορεί να μεταγλωττιστεί για διαφορετικές πλατφόρμες (*nix, OS X, Windows). Εάν αναπτύσσετε τα πάντα κάτω από τα Windows, τότε δεν υπάρχουν προβλήματα - συγχωνεύστε τα δυαδικά και προχωρήστε. Ενδέχεται να προκύψουν μικρές δυσκολίες με την εκκίνηση εάν έχετε εγκαταστήσει δύο προσαρμογείς βίντεο, ένας εκ των οποίων είναι NVIDIA. Σε αυτήν την περίπτωση, θα πρέπει να χρησιμοποιήσετε το hack που περιγράφεται στην πλαϊνή γραμμή.


Ας προσπαθήσουμε να εξοικειωθούμε με το PhantomJS στην πράξη. Για να εκτελέσουμε τις δοκιμές που προετοιμάστηκαν στην τελευταία ενότητα μέσω του PhantomJS και να λάβουμε τα αποτελέσματα της εκτέλεσης στην κονσόλα, χρειαζόμαστε ένα ειδικό σενάριο φόρτωσης - run-qunit.js . Ανοίξτε την κονσόλα (δουλεύω σε Windows, άρα χρησιμοποιώ cmd) και πληκτρολογήστε την εντολή στη μορφή

phantom.exe<путь к run-qunit.js> <путь к странице с тестами>

Στην περίπτωσή μου, η εντολή εκκίνησης αποδείχθηκε ως εξής:

E:\soft\phantomjs>phantomjs.exe E:\temp\testjsforx\qunit\run-qunit.js αρχείο:///E: /temp/testjsforx/qunit/index.html

Το αποτέλεσμα της εκτέλεσής του:

Οι δοκιμές ολοκληρώθηκαν σε 2592 χιλιοστά του δευτερολέπτου. 9 ισχυρισμοί από 9 πέρασαν, 0 απέτυχαν.

Όλα τα τεστ πέρασαν

Είναι σίγουρα απαραίτητο να καλύψετε τον κώδικα με δοκιμές και δεν έχει σημασία ποια κλίμακα δημιουργείτε την εφαρμογή. Για άλλη μια φορά, σας υπενθυμίζω: ακόμη και τα πιο μικρά προγράμματα μετατρέπονται σε αδέξια τέρατα που πρέπει να υποστηριχθούν και να ολοκληρωθούν με λειτουργικότητα. Ο καλά δοκιμασμένος κώδικας είναι το κλειδί για την επιτυχία και την ποιότητα. Ναι, δεν είναι εύκολο να ξεκινήσετε αμέσως να γράφετε κώδικα κατάλληλο για αυτοματοποιημένες δοκιμές, αλλά πιστέψτε με, όλο αυτό το μαρτύριο θα αποδώσει περισσότερο από το μέλλον. Αυτά για σήμερα, καλή επιτυχία!

Ζητήματα PhantomJS στα Windows

Απλώς συνέβη, αλλά δοκίμασα όλα τα παραδείγματα για αυτό το άρθρο όχι σε Linux, αλλά με τα παλιά καλά Windows 7. Αποδεικνύεται ότι το PhantomJS έχει κάποια προβλήματα όταν εργάζεται σε συστήματα που χρησιμοποιούν πολλούς προσαρμογείς βίντεο. Στον φορητό υπολογιστή μου, εκτός από το ενσωματωμένο τσιπ βίντεο, κάνει παρέα και η NVIDIA, και εξαιτίας αυτού, το PhantomJS αρνήθηκε κατηγορηματικά να απαντήσει στην εντολή phantom.exit (). Ως αποτέλεσμα, μετά την εκτέλεση του σεναρίου, η διαδικασία PhantomJS δεν τελείωσε τη δουλειά της και συνέχισε να κρέμεται στη μνήμη. Το παράθυρο του τερματικού σταμάτησε επίσης να ανταποκρίνεται στις εντολές εξόδου ( δεν βοήθησε).

Αν αντιμετωπίζετε παρόμοιο πρόβλημα και σκοπεύετε να χρησιμοποιήσετε το PhantomJS στα Windows, τότε ετοιμαστείτε να κάνετε το παρακάτω hack. ανοιχτό πάνελ Έλεγχος NVIDIA. Βρείτε το στοιχείο "Ρυθμίσεις 3D" στο δέντρο. Στη δεξιά πλευρά, η επιλογή "Προτιμώμενο προσαρμογέας γραφικών". Από προεπιλογή. Η τιμή του ορίζεται σε Αυτόματη επιλογή. Πρέπει να το αλλάξουμε σε "High Performance NVIDIA Processor" ή "Integrated Graphics Hardware". Μετά από αυτό το απλό κόλπο, το PhantomJS άρχισε να συμπεριφέρεται υπάκουα.

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

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

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

Υπάρχουν 2 προσεγγίσεις για τα σενάρια δοκιμών δόμησης:

  • άσπρο κουτίδοκιμή– οι δοκιμές γραφής βασίζονται στην υλοποίηση της λειτουργικότητας. Εκείνοι. ελέγχουμε για τους ίδιους αλγόριθμους στους οποίους βασίζεται η εργασία των modules του συστήματός μας. Αυτή η προσέγγιση δεν εγγυάται τη σωστή λειτουργία του συστήματος στο σύνολό του.
  • μαύρο κουτίδοκιμή– το σενάριο βασίζεται σε προδιαγραφές και απαιτήσεις συστήματος. Με αυτόν τον τρόπο μπορείτε να ελέγξετε την ορθότητα των αποτελεσμάτων ολόκληρης της εφαρμογής, αλλά αυτή η προσέγγιση δεν σας επιτρέπει να πιάσετε μικρά και σπάνια σφάλματα.

Τι να δοκιμάσετε

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

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

Έτσι, μπορούμε να διατυπώσουμε 3 περιπτώσεις όπου δικαιολογείται η χρήση δοκιμών μονάδας:

1) Εάν οι δοκιμές καθιστούν δυνατό τον εντοπισμό σφαλμάτων πιο γρήγορα από ό,τι με τη συνήθη αναζήτησή τους.

2) Μειώστε τον χρόνο εντοπισμού σφαλμάτων

3) Σας επιτρέπει να δοκιμάσετε τον κώδικα που αλλάζετε συχνά.

Από τα 3 κύρια στοιχεία της διεπαφής (HTML, CSS, JavaScript), ίσως μόνο ο κώδικας JavaScript χρειάζεται να ελεγχθεί. Το CSS επικυρώνεται οπτικά μόνο όταν προβάλλει ο προγραμματιστής/ελεγκτής/πελάτης GUIσε διάφορα προγράμματα περιήγησης. HTML - η σήμανση ελέγχεται με την ίδια μέθοδο.

Πώς να δοκιμάσετε

Όταν σχεδιάζετε σενάρια δοκιμών, θα πρέπει να καθοδηγηθείτε από τις ακόλουθες αρχές:

  • Οι δοκιμές σας πρέπει να είναι όσο το δυνατόν απλούστερες.Τότε θα είναι πιο πιθανό το σφάλμα που προσπαθείτε να επαναλάβετε να επηρεάσει τα αποτελέσματα της υλοποίησής του.
  • Αποσύνθεση δοκιμών μεγάλων ενοτήτων. Grove για να βρείτε τη συγκεκριμένη τοποθεσία του σφάλματος.
  • Κάντε τα τεστ ανεξάρτητα.Το αποτέλεσμα μιας δοκιμής δεν πρέπει σε καμία περίπτωση να εξαρτάται από τα αποτελέσματα μιας άλλης.
  • Τα αποτελέσματα των δοκιμών πρέπει να είναι πλήρως επαναλαμβανόμενα και αναμενόμενα.Κάθε φορά που εκτελείτε ξανά τη δοκιμή, το αποτέλεσμα θα πρέπει να είναι το ίδιο με την τελευταία φορά.
  • Για οποιοδήποτε σφάλμα κατά την εκτέλεση της εφαρμογής, πρέπει να δημιουργηθεί ένα δοκιμαστικό σενάριο.Με αυτόν τον τρόπο θα είστε σίγουροι ότι το σφάλμα έχει όντως διορθωθεί και δεν εμφανίζεται στους χρήστες.

Πώς να δοκιμάσετε

Υπάρχουν πολλές βιβλιοθήκες για τη δοκιμή κωδικών js σε μονάδες. Ίσως το πιο συνηθισμένο είναι το QUnit. Για να πραγματοποιήσουμε δοκιμές μονάδας χρησιμοποιώντας αυτήν τη βιβλιοθήκη, πρέπει να δημιουργήσουμε ένα "sandbox" - μια απλή σελίδα html στην οποία θα συνδεθεί η βιβλιοθήκη δοκιμών, ο κώδικας που θα ελεγχθεί και οι ίδιες οι δοκιμές.

Λειτουργίες για δοκιμές:

(function() ( window.stepen = function(int) ( var result = 2; for (var i = 1; i< int; i ++) { result = result * 2; } return result; } window.returnFunc = function() { return "ok"; } })();

Δοκιμαστική λίστα:

Test("stepen()", function() (qual(stepen(2), 4, "2^2 - ίση μέθοδος"); ok(stepen(3) === 8, "2^3 - ok μέθοδος" DeepEqual(stepen(5), 32, "2^5 - deepEqual μέθοδος"); )); asyncTest("returnFunc()", function() ( setTimeout(function() (qual(returnFunc(), "ok", "Async Func Test"); start(); ), 1000); ));

Όπως μπορείτε να δείτε, το QUnit υποστηρίζει 3 λειτουργίες για τη σύγκριση των αποτελεσμάτων της εκτέλεσης κώδικα με το αναμενόμενο:

  • Εντάξει()- θεωρεί τη δοκιμή επιτυχημένη εάν το αποτέλεσμα επιστροφής = αληθές
  • ίσος()- συγκρίνει το αποτέλεσμα με το αναμενόμενο
  • deepEqual()- συγκρίνει το αποτέλεσμα με το αναμενόμενο, ελέγχοντας τον τύπο του

Αποτέλεσμα εκτέλεσης:

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

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

Σημαντικό να θυμάστε

Ένα χαρακτηριστικό του σύγχρονου κώδικα js είναι ο ασυγχρονισμός της εκτέλεσής του. Οι βιβλιοθήκες για δοκιμές έχουν συνήθως τη δυνατότητα να διεξάγουν ασύγχρονες δοκιμές. Αλλά για παράδειγμα, εάν προσπαθείτε να δοκιμάσετε μια συνάρτηση που, ας πούμε, στέλνει ένα αίτημα λήψης στο backend και επιστρέφει μια απάντηση από αυτό, τότε για να πραγματοποιήσετε δοκιμές, θα πρέπει να σταματήσετε το νήμα με τη συνάρτηση stop(), start τη συνάρτηση υπό δοκιμή και, στη συνέχεια, επανεκκινήστε το νήμα με τη μέθοδο start() , "τυλίγοντάς το" στη setTimeout(). Εκείνοι. πρέπει να ορίσετε κάποιο χρονικό διάστημα κατά το οποίο θα πρέπει να ολοκληρωθεί η εκτέλεση της συνάρτησης. Κάποιος πρέπει να επιλέξει προσεκτικά τη διάρκεια αυτού του τμήματος, .k. αφενός, η μακροχρόνια εργασία της μεθόδου μπορεί να είναι είτε χαρακτηριστικό ή ακόμα και αναγκαιότητα για μια συγκεκριμένη υλοποίηση της λειτουργικότητας της εφαρμογής, είτε λανθασμένη συμπεριφορά.

Δοκιμές Εφαρμογών Backbone

Για ένα παράδειγμα δοκιμής εφαρμογών γραμμένων με χρήση του Backbone.js, θα χρησιμοποιήσουμε το έργο που περιγράφεται στο .

Μπορείτε να ελέγξετε με δοκιμές μονάδας:

  • Ορθότητα δημιουργίας μοντέλων και ελεγκτών
  • Ορθότητα δεδομένων σε μοντέλα
  • Εκτέλεση μεθόδων ελεγκτή (για αυτό πρέπει να επιστρέψουν ένα αποτέλεσμα)
  • Προβολή επιτυχίας φόρτωσης

Κωδικός δοκιμής:

Test("Backbone.js", function() ( ok(δείγμα, "Έλεγχος χώρου ονομάτων"); ok(sample.routers.app, "έλεγχος δρομολογητή"); ok(sample.core.pageManager.open("chat") , "Δοκιμή ανοίγματος σελίδας (κλήση μεθόδου ελεγκτή)") ok(sample.core.state, "Έλεγχος μοντέλου"); ισοδύναμο(sample.core.state.get("περιεχόμενο"), "sintel", "Δοκιμή λήψης δεδομένων μοντέλου" "); stop(); ok(function() ($.ajax(( url: "app/templates/about.tpl", dataType: "text" )).done(function(data) (self.$el. html(data); επιστροφή δεδομένων; )) ), "Έλεγχος φόρτωσης προτύπου"); setTimeout(function() (start(); ), 1000); ));

Το αποτέλεσμα της εργασίας με σφάλματα δοκιμών:

Δοκιμαστική αυτοματοποίηση εκτέλεσης

Συνήθως, η ανάπτυξη μιας εφαρμογής είναι μια εργασία που πρέπει να γίνεται αρκετά συχνά κατά τη διάρκεια εντατικής ανάπτυξης. Επομένως, αυτή η λειτουργία είναι συνήθως αυτοματοποιημένη. Χρησιμοποιούμε το Jenkins, ένα εργαλείο συνεχούς ολοκλήρωσης, στη δουλειά μας. Η ιδέα είναι να συνδυαστεί η ανάπτυξη μέσω του Jenkins με αυτοματοποιημένες δοκιμές.

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

/** * Περιμένετε έως ότου η συνθήκη δοκιμής είναι αληθής ή λήξει χρονικό όριο. * Χρήσιμο για την αναμονή * σε μια απόκριση διακομιστή ή για μια αλλαγή στο περιβάλλον χρήστη (fadeIn, κ.λπ.). * * @param testFx συνθήκη javascript που αξιολογείται σε boolean, * μπορεί να μεταβιβαστεί ως συμβολοσειρά (π.χ.: "1 == 1" ή * "$("#bar").is(":visible")" ή * ως συνάρτηση επανάκλησης. * @param onReady τι να κάνετε όταν πληρούται η συνθήκη testFx, * μπορεί να μεταβιβαστεί ως συμβολοσειρά (π.χ.: "1 == 1" ή * "$("#bar"). είναι (":visible")" ή * ως συνάρτηση επανάκλησης. * @param timeOutMillis είναι ο μέγιστος χρόνος αναμονής. Εάν δεν έχει καθοριστεί *, χρησιμοποιούνται 3 δευτερόλεπτα. */ λειτουργία waitFor(testFx, onReady, timeOutMillis) ( var maxtimeOutMillis = timeOutMillis - timeOutMillis: 3001, //< Default Max Timout is 3s start = new Date().getTime(), condition = false, interval = setInterval(function() { if ((new Date().getTime() - start < maxtimeOutMillis) && !condition) { // If not time-out yet and condition not yet fulfilled condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code } else { if(!condition) { // If condition still not fulfilled // (timeout but condition is "false") console.log(""waitFor()" timeout"); phantom.exit(1); } else { // Condition fulfilled (timeout and/or condition is //"true") console.log(""waitFor()" finished in " + (new Date().getTime() - start) + "ms."); typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it"s supposed to do once the // condition is fulfilled clearInterval(interval); //< Stop this interval } } }, 100); // repeat check every 250ms }; }; if (phantom.args.length === 0 || phantom.args.length >2) console.log("Usage: run-qunit.js URL"); phantom.exit(); ) var page = new WebPage(); // Δρομολογήστε τις κλήσεις "console.log()" από το περιβάλλον της Σελίδας // στο κύριο πλαίσιο Phantom (δηλαδή το τρέχον "αυτό") page.onConsoleMessage = function(msg) ( console.log(msg); ); page.open(phantom.args, function(status)( if (status !== "success") ( console.log("Δεν είναι δυνατή η πρόσβαση στο δίκτυο"); phantom.exit(); ) else (wameFor(function() ( return page.evaluate(function()( var el = document.getElementById("qunit-testresult"); if (el && el.innerText.match("ολοκληρώθηκε")) ( return true; ) return false; )); ), function()( var failedNum = page.evaluate(function()( var el = document.getElementById("qunit-testresult"); console.log(el.innerText); try ( return document.getElementsByClassName("fail" ).innerHTML.length; ) catch (e) ( return 0; ) return 10000; )); phantom.exit((parseInt(failedNum, 10) > 0) ? 1: 0); )); ) ));

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

Τώρα ο ιστότοπος είναι διαθέσιμος για δοκιμές για γνώση των ακόλουθων θεμάτων: HTML, css, JavaScript, PHP, SQL.

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

Φυσικά, τα πάντα οι εξετάσεις είναι δωρεάνκαι ο καθένας μπορεί να περάσει.

ΔΙΑΔΙΚΑΣΙΑ ΕΞΕΤΑΣΗΣ:

  1. Ακολουθήστε τον σύνδεσμο " Ξεκινήστε τις δοκιμές" του αντίστοιχου τεστ.
  2. Απαντήστε στις ερωτήσεις επιλέγοντας ο μοναδικόςσωστή επιλογή.
  3. Με την ολοκλήρωση των δοκιμών, θα δείτε το σκορ σας, αριθμός λαθών, και ανάλυση κάθε ερώτησηςαπό το τεστ.

Προσοχή!Η επιστροφή στην προηγούμενη ερώτηση δεν θα λειτουργήσει, οπότε πριν απαντήσετε, σκεφτείτε.

Δοκιμές διαθέσιμες αυτήν τη στιγμή

  1. HTML

    • Συνολικά πέρασε το τεστ: 75424 άτομα
    • Μέσος όρος: 2,83 στα 5σημεία.

    Τεστ βασικών γνώσεων HTML. Θα πρέπει να γνωρίζετε τα βασικά Ετικέτες HTMLκαι τη σωστή χρήση τους. Είναι επίσης απαραίτητο να κατανοήσουμε τα χαρακτηριστικά του προτύπου XHTML 1.1.

  2. css

    • Συνολικά πέρασε το τεστ: 32828 άτομα
    • Μέσος όρος: 3,37 στα 5σημεία.

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

  3. JavaScript

    • Συνολικά πέρασε το τεστ: 24845 άτομα
    • Μέσος όρος: 3,31 στα 5σημεία.

    Αυτό το κουίζ ελέγχει τις γνώσεις σας στη γλώσσα JavaScript. Οι ερωτήσεις από το τεστ καλύπτουν διαφορετικούς τομείς εφαρμογής δεδομένης γλώσσας. Υπάρχουν πολλά ερωτήματα σχετικά με την κατανόηση των «μικρών» αποχρώσεων. Διαφορετικά, απαιτείται να γνωρίζετε βασικά πράγματα: εργασία με μεταβλητές, βασικές λειτουργίες JavaScript, προτεραιότητες χειριστή και ούτω καθεξής.

  4. PHP

    • Συνολικά πέρασε το τεστ: 33239 άτομα
    • Μέσος όρος: 3,03 από 5σημεία.

    Αυτό το κουίζ ελέγχει τις γνώσεις σας στη γλώσσα PHP. Απαιτείται να γνωρίζετε βασικές κατασκευές PHP, να εργάζεστε με μεταβλητές, περιόδους λειτουργίας, υλοποίηση ανακατεύθυνσης και άλλα τυπικά πράγματα.
    Το πειστικό αίτημα:Το τεστ περιέχει πολλές ερωτήσεις όπως: "Τι θα βγει το σενάριο;". Μεγάλο αίτημα, μην το αντιγράψετε και ελέγξτε το. Να είσαι ειλικρινής με τον εαυτό σου.

  5. SQL

    • Συνολικά πέρασε το τεστ: 18014 άτομα
    • Μέσος όρος: 3,28 από 5σημεία.

    Αυτό το τεστ ελέγχει τις γνώσεις σας στη γλώσσα Ερωτήματα SQL. Οι ερωτήσεις καλύπτουν μόνο τις πιο βασικές γνώσεις αυτής της γλώσσας, χωρίς καμία εμβάθυνση. Θα χρειαστείτε γνώση των πιο βασικών ερωτημάτων SQL, καθώς και την κατάλληλη χρήση τους.

Στο παράδειγμα μιας απλής εφαρμογής αριθμομηχανής στο Node.js. Θα δοκιμάσουμε χρησιμοποιώντας το πλαίσιο Mocha.

Τι πρέπει να μπορεί να κάνει η εφαρμογή μας:

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

Αυτό που χρειαζόμαστε:

  • Node.js και npm
  • Γνώση JavaScript: δομή σύνταξης και κώδικα, τύποι δεδομένων, μαθηματικές πράξεις και εκφράσεις υπό όρους.

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

Ρύθμιση του περιβάλλοντος

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

Δημιουργώ νέος φάκελος υπολογ. Στη γραμμή εντολών, αλλάξτε σε αυτόν τον κατάλογο και δημιουργήστε ένα νέο έργο με npm init , το οποίο θα δημιουργήσει νέο αρχείο πακέτο.jsonγια το πρόγραμμά μας.

Θα σας ζητηθεί να εισαγάγετε το όνομα του πακέτου, την έκδοση, την περιγραφή και άλλες πληροφορίες σχετικά με το πακέτο. Μπορείτε να εισάγετε ένα όνομα calc.jsκαι συνεχίστε να πιέζετε Εισαγωγια να εκχωρήσετε προεπιλεγμένες τιμές. Όταν φτάσετε στην εντολή test , πληκτρολογήστε mocha - αυτό είναι το πλαίσιο δοκιμής που θα χρησιμοποιήσουμε:

εντολή δοκιμής: μόκα

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

( "όνομα": "calc.js", "έκδοση": "1.0.0", "περιγραφή": "Απλή αριθμομηχανή στο Node.js", "κύριος": "index.js", "scripts": ( " δοκιμή": "μόκα" ), "συγγραφέας": "", "άδεια χρήσης": "ISC" )

Το τελευταίο βήμα σε αυτό το βήμα είναι η εγκατάσταση της Mocha. Εισαγάγετε την ακόλουθη εντολή για εγκατάσταση:

npm εγκατάσταση --save-dev mocha

Μετά την εφαρμογή αυτής της εντολής, θα εμφανιστεί ένας φάκελος node_modules, αρχείο package-lock.json, και στο αρχείο πακέτο.jsonθα εμφανιστούν οι ακόλουθες γραμμές:

"devDependencies": ( "mocha": "^4.0.1" )

Δημιουργήστε ένα αρχείο test.js. Θα χρησιμοποιήσουμε την ενσωματωμένη μονάδα στο Node.js διεκδικώγια να ελέγξετε αν είναι αληθή και αληθή. Εφόσον είναι αλήθεια, το τεστ πρέπει να περάσει:

Const assert = απαιτώ ("assert"); it("θα πρέπει να επιστρέψει true", () => (assert.equal(true, true); ));

Τώρα εκτελέστε τη δοκιμή από τη γραμμή εντολών:

$ npm test > μόκα ✓ θα πρέπει να επιστρέψει αληθινό 1 πέρασμα (8ms)

Η δοκιμή πήγε όπως αναμενόταν, επομένως η ρύθμιση του περιβάλλοντος έχει ολοκληρωθεί. Αφαιρώ από test.jsτα πάντα εκτός από τη γραμμή const assert = require("assert"); .

Θα χρησιμοποιήσουμε το αρχείο test.jsσε όλη τη διαδικασία ανάπτυξης εφαρμογών. Δημιουργήστε άλλα δύο αρχεία: λειτουργίες.jsγια συναρτήσεις αριθμητικής και επικύρωσης και calc.jsγια την ίδια την εφαρμογή. Χρησιμοποιούμε τόσα πολλά αρχεία που δεν γίνονται πολύ μεγάλα και περίπλοκα. Εδώ είναι η τρέχουσα λίστα των αρχείων μας:

  • calc.js;
  • node_modules;
  • λειτουργίες.js;
  • package-lock.json;
  • πακέτο.json;
  • test.js;

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

Προσθήκη μαθηματικών πράξεων

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

Ας ξεκινήσουμε με την προσθήκη. Θα γράψουμε ένα τεστ που θα λαμβάνει μοναδικά το αναμενόμενο άθροισμα δύο αριθμών. Στον παρακάτω κώδικα, ελέγχουμε αν το άθροισμα του 1 και του 3 είναι ίσο χρησιμοποιώντας τη συνάρτηση add() 4:

Const assert = απαιτώ ("assert"); it("βρίσκει σωστά το άθροισμα του 1 και του 3", () => ( assert.equal(add(1, 3), 4); ));

Αφού εκτελέσουμε τη δοκιμή με την εντολή npm test, βλέπουμε τα εξής:

> μόκα 0 περνώντας (9ms) 1 αποτυχία 1) βρίσκει σωστά το άθροισμα του 1 και του 3: ReferenceError: η προσθήκη δεν ορίζεται στο Context.it (test.js:5:16) npm ERR! η δοκιμή απέτυχε. Δείτε παραπάνω για περισσότερες λεπτομέρειες.

Η δοκιμή απέτυχε με ένα Σφάλμα αναφοράς: η προσθήκη δεν έχει οριστεί . Δοκιμάζουμε τη συνάρτηση add(), η οποία δεν υπάρχει ακόμα, οπότε αυτό το αποτέλεσμα είναι αρκετά αναμενόμενο.

Ας δημιουργήσουμε μια συνάρτηση add() σε ένα αρχείο λειτουργίες.js:

Const add = (x, y) => (+x) + (+y);

Αυτή η συνάρτηση παίρνει δύο ορίσματα x και y και επιστρέφει το άθροισμά τους. Ίσως έχετε παρατηρήσει ότι γράφουμε (+x) + (+y) αντί για x + y . Χρησιμοποιούμε τον unary τελεστή για να ρίξουμε το όρισμα σε έναν αριθμό, σε περίπτωση που η είσοδος είναι συμβολοσειρά.

Σημείωση Χρησιμοποιεί μια συνάρτηση βέλους που προστέθηκε από το ES6 και μια σιωπηρή επιστροφή.

Εφόσον χρησιμοποιούμε το Node.js και χωρίζουμε τον κώδικα σε πολλά αρχεία, πρέπει να χρησιμοποιήσουμε το module.exports για την εξαγωγή του κώδικα:

Const add = (x, y) => (+x) + (+y); module.exports = (προσθήκη)

Στην αρχή του αρχείου test.jsεισάγουμε κωδικό από λειτουργίες.jsμε την απαίτηση() . Εφόσον χρησιμοποιούμε τη συνάρτηση μέσω της μεταβλητής Operations, πρέπει να αλλάξουμε την add() σε operations.add():

Const Operations = require("./operations.js"); const assert = απαιτώ("assert"); it("βρίσκει σωστά το άθροισμα του 1 και του 3", () => ( assert.equal(operations.add(1, 3), 4); ));

Ας κάνουμε το τεστ:

$ npm test > μόκα ✓ βρίσκει σωστά το άθροισμα των 1 και 3 1 περασμένα (8ms)

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

It("βρίσκει σωστά το άθροισμα του 1 και του 3", () => ( assert.equal(operations.add(1, 3), 4); )); it("βρίσκει σωστά το άθροισμα των -1 και -1", () => ( assert.equal(operations.add(-1, -1), -2); )); it("βρίσκει σωστά τη διαφορά μεταξύ 33 και 3", () => ( assert.equal(operations.subtract(33, 3), 30); )); it("βρίσκει σωστά το γινόμενο του 12 και του 12", () => ( assert.equal(operations.multiply(12, 12), 144); )); it("βρίσκει σωστά το πηλίκο του 10 και του 2", () => ( assert.equal(operations.divide(10, 2), 5); ));

Τώρα ας δημιουργήσουμε και ας εξάγουμε όλες τις συναρτήσεις σε test.js:

Const add = (x, y) => (+x) + (+y); const αφαίρεση = (x, y) => (+x) - (+y); const πολλαπλασιάζω = (x, y) => (+x) * (+y); const divide = (x, y) => (+x) / (+y); module.exports = (προσθήκη, αφαίρεση, πολλαπλασιασμός, διαίρεση, )

Και εκτελέστε νέες δοκιμές:

$ npm test > mocha ✓ βρίσκει σωστά το άθροισμα του 1 και του 3 ✓ βρίσκει σωστά το άθροισμα του -1 και του -1 ✓ βρίσκει σωστά τη διαφορά μεταξύ 33 και 3 ✓ βρίσκει σωστά το γινόμενο του 12 και του 12 ✓ βρίσκει σωστά το πηλίκο του 10 και 2 5 πάσα (8ms)

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

Προσθήκη επικύρωσης

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

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

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

  1. Και οι δύο είσοδοι είναι αριθμοί.
  2. Η μία είσοδος είναι ένας αριθμός και η άλλη είναι μια συμβολοσειρά.
  3. Και οι δύο είσοδοι είναι συμβολοσειρές.
it("αναφέρει ένα σφάλμα όταν χρησιμοποιείται μια συμβολοσειρά αντί για έναν αριθμό", () => ( assert.equal(operations.validateNumbers("sammy", 5), false); )); it("αναφέρει ένα σφάλμα όταν χρησιμοποιούνται δύο συμβολοσειρές αντί για αριθμούς", () => ( assert.equal(operations.validateNumbers("sammy", "sammy"), false); )); it("επιτυχία κατά τη χρήση δύο αριθμών", () => ( assert.equal(operations.validateNumbers(5, 5), true); ));

Η συνάρτηση validateNumbers() θα επικυρώσει και τις δύο παραμέτρους. Η συνάρτηση isNaN() ελέγχει εάν η παράμετρος δεν είναι αριθμός και αν όχι, επιστρέφει false . Διαφορετικά, επιστρέφει true , που σημαίνει επιτυχής επικύρωση.

Const validateNumbers = (x, y) => ( if (isNaN(x) && isNaN(y)) ( return false; ) return true; )

Μην ξεχάσετε να προσθέσετε validateNumbers στο module.exports στο τέλος του αρχείου. Τώρα μπορείτε να εκτελέσετε νέες δοκιμές:

Δοκιμή $ npm 1) αναφέρει ένα σφάλμα κατά τη χρήση μιας συμβολοσειράς αντί για έναν αριθμό ✓ αναφέρει ένα σφάλμα κατά τη χρήση δύο συμβολοσειρών αντί για αριθμούς ✓ επιτυχία κατά τη χρήση δύο αριθμών 7 επιτυχία (12ms) 1 αποτυχία 1) αναφέρει ένα σφάλμα κατά τη χρήση μιας συμβολοσειράς αντί για αριθμούς ενός αριθμού: AssertionError : true == false + αναμενόμενη - actual -true + false

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

Αν κοιτάξουμε ξανά τη λειτουργία μας, μπορούμε να το δούμε αυτό και τα δυοΟι παράμετροι πρέπει να είναι NaN για να επιστρέψει η συνάρτηση false. Εάν θέλουμε να επιτύχουμε το ίδιο αποτέλεσμα όταν τουλάχιστον μία από τις παραμέτρους είναι NaN , πρέπει να αντικαταστήσουμε το && με || :

Const validateNumbers = (x, y) => ( if (isNaN(x) || isNaN(y)) ( return false; ) return true; )

Εάν εκτελέσετε ξανά τη δοκιμή npm μετά από αυτές τις αλλαγές, τότε όλες οι δοκιμές θα περάσουν:

✓ αναφέρει ένα σφάλμα κατά τη χρήση μιας συμβολοσειράς αντί για έναν αριθμό ✓ αναφέρει ένα σφάλμα κατά τη χρήση δύο συμβολοσειρών αντί για αριθμούς ✓ επιτυχία κατά τη χρήση δύο αριθμών 8 πέρασμα (9ms)

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

Δημιουργία διεπαφής

Έχουμε ήδη τις απαραίτητες λειτουργίες, αλλά ο χρήστης εξακολουθεί να μην μπορεί να τις χρησιμοποιήσει με κανέναν τρόπο. Χρειαζόμαστε λοιπόν μια διεπαφή. Για την εφαρμογή μας, θα δημιουργήσουμε μια διεπαφή γραμμής εντολών.

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

Const Operations = require("./operations.js");

Η ίδια η διεπαφή θα χρησιμοποιεί την ενσωματωμένη μονάδα Readline CLI του Node.js:

Const readline = απαιτείται ("readline");

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

Const rl = readline.createInterface(( input: process.stdin, output: process.stdout ));

Το πρώτο πράγμα που πρέπει να δει ο χρήστης μετά την εκκίνηση του προγράμματος είναι ένα μήνυμα καλωσορίσματος και οδηγίες χρήσης. Για να το κάνουμε αυτό, θα χρησιμοποιήσουμε το console.log():

Console.log(` Calc.js Έχετε ανοίξει μια αριθμομηχανή Node.js! Έκδοση: 1.0.0. Χρήση: ο χρήστης πρέπει να εισάγει δύο αριθμούς και στη συνέχεια να επιλέξει τι θα κάνει με αυτούς. `);

Πριν μπούμε στις ίδιες τις λειτουργίες της αριθμομηχανής, ας ελέγξουμε ότι η console.log() λειτουργεί όπως θα έπρεπε. Θα κάνουμε το πρόγραμμα να εκτυπώσει ένα μήνυμα και να βγούμε. Για να το κάνετε αυτό, προσθέστε μια κλήση στη μέθοδο rl.close() στο τέλος.

Για να εκτελέσετε την εφαρμογή, εισαγάγετε τον κόμβο ακολουθούμενο από ένα όνομα αρχείου:

$ node calc.js Calc.js Έχετε ανοίξει την αριθμομηχανή Node.js! Έκδοση: 1.0.0. Χρήση: Ο χρήστης πρέπει να εισαγάγει δύο αριθμούς και στη συνέχεια να επιλέξει τι θα κάνει με αυτούς.

Το πρόγραμμα εμφανίζει ένα μήνυμα καλωσορίσματος και βγαίνει. Τώρα πρέπει να προσθέσουμε είσοδο χρήστη. Ο χρήστης πρέπει να επιλέξει δύο αριθμούς και μία λειτουργία. Κάθε είσοδος θα ζητηθεί από τη μέθοδο rl.question():

Rl.question("Εισάγετε τον πρώτο αριθμό: ", (x) => ( rl.question("Εισαγάγετε τον δεύτερο αριθμό: ", (y) => ( rl.question(` Επιλέξτε μία από τις ακόλουθες πράξεις: Προσθήκη ( +) Αφαίρεση (-) Πολλαπλασιασμός (*) Διαίρεση (/) Η επιλογή σας: `, (επιλογή) => ( // περισσότερος κώδικας θα εμφανιστεί εδώ rl.close(); )); )); ));

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

Μετά την τρίτη εισαγωγή, πρέπει να ελέγξετε ότι έχουν εισαχθεί μόνο αριθμοί. Για να το κάνουμε αυτό, θα χρησιμοποιήσουμε τη συνάρτηση validateNumbers(). Χρησιμοποιώντας τον τελεστή NOT, θα ελέγξουμε αν έχουν εισαχθεί αριθμοί και, εάν όχι, θα βγούμε από το πρόγραμμα:

Εάν (!operations.validateNumbers(x, y)) ( console.log("Επιτρέπονται μόνο αριθμοί! Κάντε επανεκκίνηση του προγράμματος."); )

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

If (!operations.validateNumbers(x, y)) ( console.log("Μπορούν να εισαχθούν μόνο αριθμοί! Παρακαλούμε επανεκκινήστε το πρόγραμμα."); ) else ( διακόπτης (επιλογή) (περίπτωση "1": console.log(` Το άθροισμα $(x) και $(y) ισούται με $(operations.add(x, y)).`); break, case "2": console.log(`Η διαφορά των $(x) και $(y) ισούται $( operations.subtract(x, y)).`); break; case "3": console.log(`Το γινόμενο των $(x) και $(y) ισούται με $(operations.multiply(x, y) ).`) ; break; case "4": console.log(`Private $(x) and $(y) is ίσον $(operations.divide(x, y)).`); break; default: console.log ("Παρακαλώ επανεκκινήστε το πρόγραμμα και επιλέξτε έναν αριθμό μεταξύ 1 και 4."); break; ) )

Σημείωση Οι συναρτήσεις console.log() εδώ χρησιμοποιούν συμβολοσειρές προτύπων που επιτρέπουν εκφράσεις.

/** * Μια απλή αριθμομηχανή Node.js που χρησιμοποιεί την εφαρμογή αριθμομηχανής που χρησιμοποιεί * την ενσωματωμένη διεπαφή γραμμής εντολών Readline. */ const operations = require("./operations.js"); const readline = απαιτώ ("readline"); // Χρησιμοποιήστε τη γραμμή ανάγνωσης για να δημιουργήσετε μια διεπαφή const rl = readline.createInterface(( input: process.stdin, output: process.stdout )); console.log(` Calc.js Έχετε ανοίξει μια αριθμομηχανή Node.js! Έκδοση: 1.0.0. Χρήση: Ο χρήστης πρέπει να εισάγει δύο αριθμούς και στη συνέχεια να επιλέξει τι θα κάνει με αυτούς. `); rl.question("Εισάγετε τον πρώτο αριθμό: ", (x) => ( rl.question("Εισαγάγετε τον δεύτερο αριθμό: ", (y) => ( rl.question(` Επιλέξτε μία από τις ακόλουθες πράξεις: Προσθήκη ( +) Αφαίρεση (-) Πολλαπλασιασμός (*) Διαίρεση (/) Η επιλογή σας: `, (επιλογή) => (αν (!operations.validateNumbers(x, y)) ( console.log("Μπορείτε να εισάγετε μόνο αριθμούς! Παρακαλώ επανεκκινήστε το πρόγραμμα. "); ) else ( διακόπτης (επιλογή) (περίπτωση "1": console.log(`Το άθροισμα των $(x) και των $(y) ισούται με $(operations.add(x, y)). `); break; case "2": console.log(`Η διαφορά μεταξύ $(x) και $(y) είναι $(operations.subtract(x, y)).`); break; case "3": console.log(`Το γινόμενο των $( x) και $(y) ισούται με $(operations.multiply(x, y)).`); break; case "4": console.log(`Private $(x) και $(y) ισούται με $(λειτουργίες. divide(x, y)).`); break; default: console.log("Please restart the program και επιλέξτε έναν αριθμό μεταξύ 1 και 4."); break; ) ) rl.close(); )); )) ;));

Τώρα η εφαρμογή μας είναι έτοιμη. Ας ελέγξουμε τη δουλειά του στο τέλος. Πληκτρολογήστε 999 και 1 και επιλέξτε τη λειτουργία αφαίρεσης:

$ node calc.js Εισαγάγετε τον πρώτο αριθμό: 999 Εισαγάγετε τον δεύτερο αριθμό: 1 Η επιλογή σας: 2 Η διαφορά μεταξύ 999 και 1 είναι 998.

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



Φόρτωση...
Μπλουζα