Δοκιμές από άκρο σε άκρο με Joomla! και Cypress - Τα πρώτα μου βήματα και σκέψεις

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

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

Παρεμπιπτόντως, όποιος θέλει να ελέγξει το Cypress θα βρει αυτό το κείμενο μια καλή αρχή. Μπορείτε να δοκιμάσετε προβλήματα χωρίς να χρειάζεται να εγκαταστήσετε και να ρυθμίσετε τα πάντα μόνοι σας. Στο αποθετήριο Github του έργου Joomla όλα είναι έτοιμα.

Εισαγωγή

"Αν και είναι αλήθεια ότι η ποιότητα δεν μπορεί να δοκιμαστεί, είναι εξίσου προφανές ότι χωρίς δοκιμή είναι αδύνατο να αναπτυχθεί οτιδήποτε ποιοτικό." - [James A. Whittaker]

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

  • όσο το δυνατόν πιο κοντά στον προγραμματισμό,
  • αυτομάτως,
  • συχνά - ιδανικά μετά από κάθε αλλαγή προγράμματος,

    φέρνετε περισσότερα από αυτά που κοστίζουν Και ακόμη περισσότερο: η δοκιμή μπορεί να είναι ακόμη και διασκεδαστική.

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

Ποιος πρέπει να διαβάσει αυτό το κείμενο;

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

Κάποια θεωρία

Το μαγικό τρίγωνο

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

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

 

Το Μαγικό Τρίγωνο στη Διαχείριση Έργων - Εάν επενδυθούν περισσότερα χρήματα στο έργο, αυτό έχει θετικό αντίκτυπο στην ποιότητα ή στο χρόνο.

Το αντίστροφο, μια εξοικονόμηση κόστους θα αναγκάσει την ποιότητα να μειωθεί ή/και να καθυστερήσει η ολοκλήρωση.

Το Μαγικό Τρίγωνο στη Διαχείριση Έργων - Εάν επενδυθούν λιγότερα χρήματα στο έργο, αυτό έχει αρνητικό αντίκτυπο στην ποιότητα ή στο χρόνο.

Τώρα η μαγεία μπαίνει στο παιχνίδι: Ξεπερνάμε τη συσχέτιση μεταξύ χρόνου, κόστους και ποιότητας γιατί, μακροπρόθεσμα, αυτό μπορεί πραγματικά να ξεπεραστεί.

Η σύνδεση μεταξύ χρόνου, κόστους και ποιότητας μπορεί να ξεπεραστεί μακροπρόθεσμα.

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

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

Το τεχνικό χρέος αναφέρεται στην πρόσθετη προσπάθεια που απαιτείται για την πραγματοποίηση αλλαγών και βελτιώσεων σε μη καλά προγραμματισμένο λογισμικό σε σύγκριση με καλογραμμένο λογισμικό.Ο Martin Fowler διακρίνει τους ακόλουθους τύπους τεχνικού χρέους: Αυτά που κάποιος έχει συνάψει εσκεμμένα και αυτά που έχει συνάψει κατά λάθος Διακρίνει επίσης μεταξύ συνετών και απερίσκεπτων τεχνικών χρεών.

Τεχνικό χρέος

Κόστος και οφέλη

Στη βιβλιογραφία θα βρείτε καταστροφικά στατιστικά στοιχεία σχετικά με τις πιθανότητες επιτυχίας των έργων λογισμικού Ελάχιστα έχουν αλλάξει στην αρνητική εικόνα που είχε ήδη καταγραφεί σε μια μελέτη του AW Feyhl τη δεκαετία του 1990. Εδώ, σε μια ανάλυση 162 έργων σε 50 οργανισμούς , προσδιορίστηκε η απόκλιση κόστους σε σύγκριση με τον αρχικό σχεδιασμό: το 70% των έργων παρουσίασαν απόκλιση κόστους τουλάχιστον 50%!Κάτι δεν είναι σωστό!Δεν μπορείτε απλά να το αποδεχτείτε, έτσι δεν είναι;

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

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

Ενσωματώστε τη δοκιμή λογισμικού στη ροή εργασίας σας

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

Σχετικό κόστος για την αντιμετώπιση προβλημάτων σε διάφορα στάδια του έργου

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

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

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

Συνεχής ολοκλήρωση (CI)
Συνεχής ενσωμάτωση τεστ

Φανταστείτε το ακόλουθο σενάριο. Μια νέα έκδοση ενός δημοφιλούς συστήματος διαχείρισης περιεχομένου πρόκειται να κυκλοφορήσει. Όλα όσα έχουν συνεισφέρει οι προγραμματιστές της ομάδας από την τελευταία κυκλοφορία χρησιμοποιούνται τώρα μαζί για πρώτη φορά. Η ένταση αυξάνεται! λειτουργεί; Θα είναι επιτυχείς όλες οι δοκιμές - εάν το έργο ενσωματώσει καθόλου δοκιμές. Ή μήπως θα πρέπει να αναβληθεί ξανά η κυκλοφορία της νέας έκδοσης και θα ακολουθήσουν τρομακτικές ώρες επιδιόρθωσης σφαλμάτων; Παρεμπιπτόντως, η αναβολή της ημερομηνίας κυκλοφορίας δεν είναι επίσης καλό για την εικόνα του προϊόντος λογισμικού! Σε κανέναν προγραμματιστή δεν αρέσει να βιώνει αυτό το σενάριο. Είναι πολύ καλύτερο να γνωρίζετε ανά πάσα στιγμή σε ποια κατάσταση βρίσκεται το έργο λογισμικού; Ο κώδικας που δεν ταιριάζει με τον υπάρχοντα θα πρέπει να ενσωματωθεί μόνο μετά από έχουν «φτιαχτεί για να ταιριάζουν».Ειδικά σε περιόδους που είναι ολοένα και πιο συνηθισμένο ότι πρέπει να διορθωθεί ένα κενό ασφαλείας, ένα έργο θα πρέπει πάντα να μπορεί να δημιουργήσει μια κυκλοφορία!Και εδώ είναι που παίζει ρόλο η συνεχής ενσωμάτωση.

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

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

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

Ανάπτυξη βάσει δοκιμής (TDD)

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

Οι δοκιμές TDD σας βοηθούν να γράψετε σωστά το πρόγραμμα .

Όταν ακούσετε για πρώτη φορά για αυτήν την τεχνική, μπορεί να μην αισθάνεστε άνετα με την ιδέα. "Ο "Άνθρωπος"" θέλει πάντα να κάνει κάτι παραγωγικό πρώτα, τελικά. Και η συγγραφή δοκιμών δεν φαίνεται παραγωγική με την πρώτη ματιά. Δοκιμάστε το. Μερικές φορές γίνεσαι φίλος με μια νέα τεχνική μόνο αφού τη γνωρίσεις!Σε έργα με υψηλή κάλυψη δοκιμών, νιώθω πιο άνετα όταν προσθέτω νέες δυνατότητες.

Εάν διαβάσετε το μέρος της άσκησης στο τέλος του κειμένου, μπορείτε να το δοκιμάσετε. Πρώτα δημιουργήστε το τεστ και μετά γράψτε τον κώδικα για το Joomla Core. Στη συνέχεια υποβάλετε τα πάντα μαζί ως PR στο Github . Αν όλοι θα το έκαναν αυτό , Joomla θα είχε ιδανική κάλυψη δοκιμής.

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

Το BDD δεν είναι άλλη τεχνική προγραμματισμού ή τεχνική δοκιμής, αλλά ένα είδος βέλτιστης πρακτικής για την ανάπτυξη λογισμικού. Το BDD χρησιμοποιείται ιδανικά μαζί με το TDD. Κατ 'αρχήν, το Behaviour-Driven-Development σημαίνει δοκιμή όχι της υλοποίησης του κώδικα προγράμματος, αλλά της εκτέλεσης - δηλαδή τη συμπεριφορά του προγράμματος Μια δοκιμή ελέγχει εάν πληρούνται οι προδιαγραφές, δηλαδή η απαίτηση του πελάτη.

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

Τι εννοώ με αυτό: "Γράψτε το σωστό πρόγραμμα"; Συμβαίνει οι χρήστες να βλέπουν τα πράγματα διαφορετικά από τους προγραμματιστές. Η ροή εργασίας της διαγραφής ενός άρθρου στο Joomla είναι ένα παράδειγμα. Ξανά και ξανά συναντώ χρήστες που κάνουν κλικ στο εικονίδιο κατάστασης στο στον κάδο απορριμμάτων και εκπλήσσονται. Ο χρήστης συνήθως υποθέτει διαισθητικά ότι το στοιχείο έχει πλέον διαγραφεί οριστικά, αλλά γίνεται εναλλαγή από τον κάδο απορριμμάτων για να ενεργοποιηθεί. Για τον προγραμματιστή, το κλικ στο εικονίδιο κατάστασης αποτελεί αλλαγή κατάστασης, εναλλαγή. σε όλες τις άλλες προβολές. Γιατί να είναι διαφορετικό στον κάδο απορριμμάτων; Για τον προγραμματιστή, η συνάρτηση υλοποιείται χωρίς σφάλματα. Το Joomla λειτουργεί σωστά. Αλλά κατά τη γνώμη μου η συνάρτηση δεν είναι η σωστή σε αυτό το μέρος, επειδή οι περισσότεροι χρήστες θα την περιέγραφαν / το ζητούσαν εντελώς διαφορετικά .

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

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

Το έργο Joomla εισήγαγε το BDD σε ένα έργο Google Summer of Code . Ελπιζόταν ότι οι χρήστες χωρίς γνώσεις προγραμματισμού θα μπορούσαν να συμμετέχουν πιο εύκολα χρησιμοποιώντας Gherkin ). Η προσέγγιση δεν ακολουθήθηκε με συνέπεια. Εκείνη την εποχή, το Joomla χρησιμοποιούσε Codeception ως εργαλείο δοκιμής Με το Cypress, η ανάπτυξη BDD είναι επίσης δυνατή με τον τρόπο BDD.

Σχεδίαση

Τύποι δοκιμών
  • Δοκιμές μονάδων: Μια δοκιμή μονάδας είναι μια δοκιμή που ελέγχει ανεξάρτητα τις μικρότερες μονάδες προγράμματος.
  • Δοκιμές ολοκλήρωσης: Μια δοκιμή ολοκλήρωσης είναι μια δοκιμή που ελέγχει την αλληλεπίδραση μεμονωμένων μονάδων.
  • Δοκιμές E2E ή Δοκιμές Αποδοχής: Μια δοκιμή αποδοχής ελέγχει εάν το πρόγραμμα εκπληρώνει την εργασία που καθορίστηκε στην αρχή.
Στρατηγικές

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

Το top-down και το bottom-up είναι δύο θεμελιωδώς διαφορετικές προσεγγίσεις για την κατανόηση και την παρουσίαση πολύπλοκων ζητημάτων. Το top-down πηγαίνει βήμα προς βήμα από το αφηρημένο και γενικό στο συγκεκριμένο και συγκεκριμένο. Για να το δείξουμε αυτό με ένα παράδειγμα: Ένα σύστημα διαχείρισης περιεχομένου όπως το Joomla Γενικά παρουσιάζει ιστοτόπους σε ένα πρόγραμμα περιήγησης. Συγκεκριμένα, ωστόσο, υπάρχει μια σειρά από μικρές δευτερεύουσες εργασίες σε αυτή τη διαδικασία. Μία από αυτές είναι η εργασία εμφάνισης ενός συγκεκριμένου κειμένου σε μια επικεφαλίδα.

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

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

Στρατηγικές δοκιμών: Δοκιμές από πάνω προς τα κάτω και δοκιμές από κάτω προς τα πάνω

  • Δοκιμές από πάνω προς τα κάτω: Κατά την εφαρμογή της στρατηγικής από πάνω προς τα κάτω, ξεκινάμε με τις δοκιμές αποδοχής - δηλαδή με το τμήμα του συστήματος που είναι πιο στενά συνδεδεμένο με τις απαιτήσεις του χρήστη. Για λογισμικό που είναι γραμμένο για ανθρώπινους χρήστες, αυτή είναι συνήθως η διεπαφή χρήστη . Η εστίαση είναι στη δοκιμή του τρόπου με τον οποίο ένας χρήστης αλληλεπιδρά με το σύστημα. Ένα μειονέκτημα των δοκιμών από πάνω προς τα κάτω είναι ότι πρέπει να αφιερωθεί πολύς χρόνος για τη δημιουργία διπλότυπων δοκιμών. Τα στοιχεία που δεν έχουν ακόμη ενσωματωθεί πρέπει να αντικατασταθούν από σύμβολα κράτησης θέσης. Εκεί Δεν είναι πραγματικός κώδικας προγράμματος στην αρχή. Επομένως, τα μέρη που λείπουν πρέπει να δημιουργηθούν τεχνητά.Σταδιακά, αυτά τα τεχνητά δεδομένα αντικαθίστανται στη συνέχεια από πραγματικά υπολογισμένα δεδομένα.

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

Η δοκιμαστική πυραμίδα του Mike Cohn

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

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

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

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

Απαιτήσεις

Τι εξοπλισμό χρειάζεστε για να εργαστείτε στο παρακάτω πρακτικό μέρος;

Ποιες απαιτήσεις πρέπει να εργαστείτε ενεργά στο ακόλουθο πρακτικό μέρος; Δεν χρειάζεται να πληροίτε πολλές απαιτήσεις για να μπορείτε να εργαστείτε με τα περιεχόμενα αυτού του εγχειριδίου. Φυσικά, πρέπει να έχετε υπολογιστή. Ένα περιβάλλον ανάπτυξης με Git, Το NodeJS και το Composer και ένας τοπικός διακομιστής ιστού θα πρέπει να εγκατασταθούν ή να εγκατασταθούν σε αυτό.

Τι γνώσεις πρέπει να έχετε εσείς προσωπικά;

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

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

Εγκαθιστώ

Ρύθμιση του Cypress με το Joomla!

Στην έκδοση προγραμματιστή που είναι διαθέσιμη στο Github, το Joomla είναι έτοιμο για Cypress. Υπάρχουν ήδη δοκιμές που μπορείτε να χρησιμοποιήσετε ως οδηγό. Επομένως, δεν είναι απαραίτητο να ρυθμίσετε τα πάντα μόνοι σας για να έχετε μια πρώτη επισκόπηση. Με αυτόν τον τρόπο, μπορείτε να πειραματιστείτε με το Cypress , μάθετε για τα πλεονεκτήματα και τα μειονεκτήματά του και αποφασίστε μόνοι σας εάν θέλετε να χρησιμοποιήσετε το εργαλείο δοκιμής.

Βήματα για τη ρύθμιση του τοπικού περιβάλλοντος:

Κλωνοποιήστε το αποθετήριο στη ρίζα του τοπικού σας διακομιστή ιστού:

$ git clone https://github.com/joomla/joomla-cms.git

Μεταβείτε στον φάκελο joomla-cms:

$ cd joomla-cms

Σύμφωνα με το Joomla Roadmap, η επόμενη σημαντική έκδοση 5.0 θα κυκλοφορήσει τον Οκτώβριο του 2023. Για να είμαι ενημερωμένη, χρησιμοποιώ αυτήν την έκδοση ανάπτυξης εδώ.

Αλλαγή στον κλάδο 5.0-dev :

$ git checkout 5.0-dev

Εγκαταστήστε όλα τα απαραίτητα πακέτα συνθέτη:

$ composer install

Εγκαταστήστε όλα τα απαραίτητα πακέτα npm:

$ npm install

Για περισσότερες πληροφορίες και βοήθεια σχετικά με τη ρύθμιση του σταθμού εργασίας σας, ανατρέξτε στο άρθρο τεκμηρίωσης του Joomla "Ρύθμιση του σταθμού εργασίας σας για την ανάπτυξη του Joomla" . Για το Cypress, υπάρχουν πληροφορίες στο cypress.io . Αλλά αυτό δεν είναι απαραίτητο σε αυτό το σημείο. Το Joomla ρυθμίζει τα πάντα Απλά πρέπει να ρυθμίσετε τα ατομικά σας δεδομένα μέσω του αρχείου διαμόρφωσης joomla-cms/cypress.config.js.

Ρυθμίστε τα ατομικά σας δεδομένα. Για αυτό μπορείτε να χρησιμοποιήσετε το πρότυπο joomla-cms/cypress.config.dist.jsως προσανατολισμό. Στην περίπτωσή μου αυτό το αρχείο μοιάζει με αυτό:

const { defineConfig } = require('cypress')

module.exports = defineConfig({
  fixturesFolder: 'tests/cypress/fixtures',
  videosFolder: 'tests/cypress/output/videos',
  screenshotsFolder: 'tests/cypress/output/screenshots',
  viewportHeight: 1000,
  viewportWidth: 1200,
  e2e: {
    setupNodeEvents(on, config) {},
    baseUrl: 'http://localhost/joomla-cms',
    specPattern: [
      'tests/cypress/integration/install/*.cy.{js,jsx,ts,tsx}',
      'tests/cypress/integration/administrator/**/*.cy.{js,jsx,ts,tsx}',
      'tests/cypress/integration/module/**/*.cy.{js,jsx,ts,tsx}',
      'tests/cypress/integration/site/**/*.cy.{js,jsx,ts,tsx}'
    ],
    supportFile: 'tests/cypress/support/index.js',
    scrollBehavior: 'center',
    browser: 'firefox',
    screenshotOnRunFailure: true,
    video: false
  },
  env: {
    sitename: 'Joomla CMS Test',
    name: 'admin',
    email: Αυτή η διεύθυνση Email προστατεύεται από τους αυτοματισμούς αποστολέων ανεπιθύμητων μηνυμάτων. Χρειάζεται να ενεργοποιήσετε τη JavaScript για να μπορέσετε να τη δείτε.',
    username: 'admin',
    password: 'adminadminadmin',
    db_type: 'MySQLi',
    db_host: 'mysql',
    db_name: 'test_joomla',
    db_user: 'root',
    db_password: 'root',
    db_prefix: 'j4_',
  },
})

Συγκεκριμένα πρόσθεσα τον κατάλογο tests/cypress/integration/module/**/*.cy.{js,jsx,ts,tsx}στον specPattern πίνακα, επειδή θέλω να αποθηκεύσω αργότερα τη δοκιμή για ενότητες. Στη συνέχεια άλλαξα το όνομα χρήστη και τους κωδικούς πρόσβασης επειδή θέλω επίσης να δοκιμάσω την εγκατάσταση με μη αυτόματο τρόπο και να θυμάμαι καλύτερα τις εκχωρημένες από τον εαυτό μου. Χρησιμοποιώ ένα κοντέινερ Docker Ως βάση δεδομένων.Έτσι άλλαξα τον διακομιστή βάσης δεδομένων και τα δεδομένα πρόσβασης.Και τελικά έπρεπε να ορίσω το root URL http://localhost/joomla-cmsτης εγκατάστασης του Joomla.

Χρησιμοποιήστε το Cypress

Μέσω Webbrowser

Κλήση npm run cypress:openμέσω CLI στον ριζικό κατάλογο του Joomla. Λίγο αργότερα θα ανοίξει η εφαρμογή Cypress. Έχουμε δημιουργήσει προηγουμένως το αρχείο joomla-cms/cypress.config.dist.js. Το ότι αυτό εντοπίζεται φαίνεται από το γεγονός ότι το E2E Testing έχει οριστεί ως ρυθμισμένο.

Η εφαρμογή Cypress ανοίγει αφού καλέσει το 96;npm run cypress:open96;.

Εδώ μπορείτε να επιλέξετε εάν θέλετε να εκτελέσετε τις δοκιμές E2E και ποιο πρόγραμμα περιήγησης θέλετε να χρησιμοποιήσετε. Για παράδειγμα, επέλεξα την επιλογή "Έναρξη δοκιμής στον Firefox".

Δοκιμές E2E στην εφαρμογή Cypress: επιλέξτε το πρόγραμμα περιήγησης που θα χρησιμοποιήσετε.

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

Δοκιμαστική σουίτα Joomla στον Firefox μέσω της εφαρμογής Cypress.

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

Δοκιμή εγκατάστασης Joomla σε εξέλιξη.

Δοκιμάστε το. Εάν χρησιμοποιείτε όπως db_host: 'localhost',μπορείτε να δοκιμάσετε την εγκατάσταση και έτσι έχετε ρυθμίσει σωστά το Joomla για την εργασία στο παρακάτω μέρος αυτού του κειμένου.

Εάν εσείς, όπως εγώ, χρησιμοποιείτε μια εξωτερική πηγή (όχι lcoalhost, χρησιμοποιώ ένα κοντέινερ docker) db_host, καθώς η δοκιμή για αυτό το είδος εγκατάστασης δεν είναι ακόμα έτοιμη. Σε αυτήν την περίπτωση, υπάρχει ζήτημα ασφάλειας στη ρουτίνα εγκατάστασης, η οποία είναι δεν λαμβάνονται ακόμη υπόψη στις δοκιμές. Σε αυτήν την περίπτωση, εγκαταστήστε το Joomla με μη αυτόματο τρόπο με τις πληροφορίες που εισάγονται στο αρχείο joomla-cms/cypress.config.js. Οι ακόλουθες δοκιμές θα χρησιμοποιήσουν τις ρυθμίσεις από αυτό το αρχείο διαμόρφωσης, για παράδειγμα για τη σύνδεση στην περιοχή διαχείρισης του Joomla. Με αυτόν τον τρόπο ο προγραμματιστής δοκιμών κάνει Ο χρήστης και ο κωδικός πρόσβασης που ταιριάζουν χρησιμοποιούνται πάντα αυτόματα από το αρχείο διαμόρφωσης.

Ακέφαλος

Από προεπιλογή, cypress runεκτελεί όλες τις δοκιμές χωρίς κεφαλή . Η ακόλουθη εντολή εκτελεί όλες τις ήδη κωδικοποιημένες δοκιμές και αποθηκεύει στιγμιότυπα οθόνης στον κατάλογο /joomla-cms/tests/cypress/output/screenshotsσε περίπτωση σφάλματος. Ο κατάλογος εξόδου ορίστηκε στο cypress.config.jsαρχείο.

$ npm run cypress:run

Άλλες εντολές CLI

Υπάρχουν άλλες χρήσιμες εντολές που δεν υλοποιούνται ως σενάρια στο package.jsonέργο Joomla. Τις εκτελώ μέσω npx [docs.npmjs.com/commands/npx].

κυπαρίσσι επαληθεύω

Η cypress verifyεντολή επαληθεύει ότι το Cypress έχει εγκατασταθεί σωστά και μπορεί να εκτελεστεί.

$ npx cypress verify

✔  Verified Cypress! /.../.cache/Cypress/12.8.1/Cypress
πληροφορίες κυπαρισσιού

Η cypress infoεντολή εξάγει πληροφορίες για το Cypress και το τρέχον περιβάλλον.

$ npx cypress info
Displaying Cypress info...

Detected 2 browsers installed:

1. Chromium
  - Name: chromium
  - Channel: stable
  - Version: 113.0.5672.126
  - Executable: chromium
  - Profile: /.../snap/chromium/current

2. Firefox
  - Name: firefox
  - Channel: stable
  - Version: 113.0.1
  - Executable: firefox
  - Profile: /.../snap/firefox/current/Cypress/firefox-stable

Note: to run these browsers, pass : to the '--browser' field

Examples:
- cypress run --browser chromium
- cypress run --browser firefox

Learn More: https://on.cypress.io/launching-browsers

Proxy Settings: none detected
Environment Variables: none detected

Application Data: /.../.config/cypress/cy/development
Browser Profiles: /.../.config/cypress/cy/development/browsers
Binary Caches: /.../.cache/Cypress

Cypress Version: 12.8.1 (stable)
System Platform: linux (Ubuntu - 22.04)
System Memory: 4.08 GB free 788 MB
έκδοση κυπαρισσιού

Η cypress versionεντολή εκτυπώνει την εγκατεστημένη δυαδική έκδοση Cypress, την έκδοση του πακέτου Cypress, την έκδοση του Electron που χρησιμοποιήθηκε για τη δημιουργία του Cypress και την έκδοση του bundled node.

$ npx cypress version
Cypress package version: 12.8.1
Cypress binary version: 12.8.1
Electron version: 21.0.0
Bundled Node version: 16.16.0

Η τεκμηρίωση του Cypress παρέχει πιο λεπτομερείς πληροφορίες.

Γράφοντας το πρώτο δικό μου Τεστ

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

Λάβετε μια επισκόπηση

Μαθαίνοντας από τεστ που έχουν ήδη αναπτυχθεί

Στην έκδοση ανάπτυξης του Joomla CMS υπάρχουν ήδη δοκιμές Cypress. Αυτά βρίσκονται στο φάκελο /tests/System/integration. Όσοι θέλουν να μάθουν με το παράδειγμα θα βρουν μια κατάλληλη εισαγωγή εδώ.

Εισαγωγή κωδικού για επαναλαμβανόμενες εργασίες

Οι προγραμματιστές του Joomla εργάζονται στο έργο NodeJs joomla-cypress , το οποίο παρέχει κώδικα δοκιμής για συνήθεις περιπτώσεις δοκιμής. Αυτοί εισάγονται κατά την εγκατάσταση της έκδοσης προγραμματιστή του CMS χρησιμοποιώντας npm installμέσω

  • package.jsonκαι μέσω του
  • αρχείο υποστήριξης /tests/System/support/index.jsΤο αρχείο υποστήριξης ορίζεται στη διαμόρφωση cypress.config.js.
// package.json
{
  "name": "joomla",
  "version": "5.0.0",
  "description": "Joomla CMS",
  "license": "GPL-2.0-or-later",
  "repository": {
    "type": "git",
    "url": "https://github.com/joomla/joomla-cms.git"
  },
...
  "devDependencies": {
    ...
    "joomla-cypress": "^0.0.16",
    ...
  }
}

Ένα παράδειγμα είναι το κλικ σε ένα κουμπί της γραμμής εργαλείων. Για παράδειγμα, Cypress.Commands.add('clickToolbarButton', clickToolbarButton)προκαλεί τη clickToolbarButton()διαθεσιμότητα της εντολής στις προσαρμοσμένες δοκιμές και μέσω cy.clickToolbarButton('new')ενός κλικ στο κουμπί Newπροσομοιώνεται. Ο κωδικός που απαιτείται για αυτό εμφανίζεται στους κωδικούς που παρατίθενται παρακάτω.

// node_modules/joomla-cypress/src/common.js
...
const clickToolbarButton = (button, subselector = null) => {
  cy.log('**Click on a toolbar button**')
  cy.log('Button: ' + button)
  cy.log('Subselector: ' + subselector)

  switch (button.toLowerCase())
  {
    case "new":
      cy.get("#toolbar-new").click()
      break
    case "publish":
      cy.get("#status-group-children-publish").click()
      break
    case "unpublish":
      cy.get("#status-group-children-unpublish").click()
      break
    case "archive":
      cy.get("#status-group-children-archive").click();
      break
    case "check-in":
      cy.get("#status-group-children-checkin").click()
      break
    case "batch":
      cy.get("#status-group-children-batch").click()
      break
    case "rebuild":
      cy.get('#toolbar-refresh button').click()
      break
    case "trash":
      cy.get("#status-group-children-trash").click()
      break
    case "save":
      cy.get("#toolbar-apply").click()
      break
    case "save & close":
      cy.get(".button-save").contains('Save & Close').click()
      break
    case "save & new":
      cy.get("#save-group-children-save-new").click()
      break
    case "cancel":
      cy.get("#toolbar-cancel").click()
      break
    case "options":
      cy.get("#toolbar-options").click()
      break
    case "empty trash":
    case "delete":
      cy.get("#toolbar-delete").click()
      break
    case "feature":
      cy.get("#status-group-children-featured").click()
      break
    case "unfeature":
      cy.get("#status-group-children-unfeatured").click()
      break
    case "action":
      cy.get("#toolbar-status-group").click()
      break
    case "transition":
      cy.get(".button-transition.transition-" + subselector).click()
      break
  }

  cy.log('--Click on a toolbar button--')
}

Cypress.Commands.add('clickToolbarButton', clickToolbarButton)
...

Ο παρακάτω κώδικας δείχνει ένα άλλο παράδειγμα, τη σύνδεση στην περιοχή διαχείρισης.

// /node_modules/joomla-cypress/src/user.js
...
const doAdministratorLogin = (user, password, useSnapshot = true) => {
  cy.log('**Do administrator login**')
  cy.log('User: ' + user)
  cy.log('Password: ' + password)

  cy.visit('administrator/index.php')
  cy.get('#mod-login-username').type(user)
  cy.get('#mod-login-password').type(password)
  cy.get('#btn-login-submit').click()
  cy.get('h1.page-title').should('contain', 'Home Dashboard')

  cy.log('--Do administrator login--')
}

Cypress.Commands.add('doAdministratorLogin', doAdministratorLogin)

...
Κοινές εργασίες στο ατομικό περιβάλλον

Στον κατάλογο /tests/System/supportθα βρείτε κοινές εργασίες στο μεμονωμένο περιβάλλον. Για να μπορούν να επαναχρησιμοποιηθούν εύκολα, εισάγονται μέσω του αρχείου υποστήριξης. Ένα /tests/System/support/index.jsπαράδειγμα μιας εργασίας που επαναλαμβάνεται συχνά είναι η σύνδεση στην περιοχή διαχείρισης, η οποία γίνεται στο αρχείο /tests/System/support/commands.jsχρησιμοποιώντας τη συνάρτηση doAdministratorLogin.

Ο ακόλουθος κώδικας δείχνει επίσης πώς χρησιμοποιούνται οι πληροφορίες από τη cypress.config.jsδιαμόρφωση στις δοκιμές. Cypress.env('username')Αποδίδεται η τιμή της usernameιδιότητας εντός της ομάδας env.

Επίσης, μπορούμε να δούμε εδώ πώς γίνεται η αντικατάσταση εντολών.αντικαθιστά Cypress.Commands.overwrite('doAdministratorLogin' ...),τον κώδικα που μόλις είδαμε στο πακέτο.Το joomla-cypressπλεονέκτημα είναι ότι ο χρήστης και ο κωδικός πρόσβασης χρησιμοποιούνται αυτόματα από τη μεμονωμένη διαμόρφωση.

// /tests/System/support/commands.js
...
Cypress.Commands.overwrite('doAdministratorLogin', (originalFn, username, password, useSnapshot = true) => {
  // Ensure there are valid credentials
  const user = username ?? Cypress.env('username');
  const pw = password ?? Cypress.env('password');

  // Do normal login when no snapshot should be used
  if (!useSnapshot) {
    // Clear the session data
    Cypress.session.clearAllSavedSessions();

    // Call the normal function
    return originalFn(user, pw);
  }

  // Do login through the session
  return cy.session([user, pw, 'back'], () => originalFn(user, pw), { cacheAcrossSpecs: true });
});
...

Εγκαταστήστε τη δική σας επέκταση Joomla

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

Εγκαταστήστε τη δική σας επέκταση Joomla.

Μετά την εγκατάσταση, μπορείτε να βρείτε έναν σύνδεσμο προς την προβολή του στοιχείου Foo στην αριστερή πλαϊνή γραμμή του backend του Joomla.

Προβολή του παραδείγματος συστατικού στο backend του Joomla.

Τώρα έχουμε ρυθμίσει ένα περιβάλλον δοκιμής και κώδικα για να το δοκιμάσουμε.

Το πρώτο δικό του τεστ

Άγκιστρα

Κατά τη δοκιμή του backend, θα παρατηρήσετε ότι πρέπει να ξεκινήσετε κάθε δοκιμή με μια σύνδεση. Μπορούμε να αποτρέψουμε αυτόν τον περιττό κωδικό χρησιμοποιώντας τη συνάρτηση. beforeEach()Αυτό το λεγόμενο άγκιστρο εκτελεί τον κωδικό που εισάγουμε πριν από την εκτέλεση κάθε δοκιμής. Εξ ου και το όνομα beforeEach().

Το Cypress παρέχει διάφορους τύπους αγκίστρων , συμπεριλαμβανομένων beforeκαι afterαγκίστρων που τρέχουν πριν ή μετά τις δοκιμές σε μια δοκιμαστική ομάδα και beforeEachκαι afterEachάγκιστρα που τρέχουν πριν ή μετά από κάθε μεμονωμένη δοκιμή στην ομάδα. Τα άγκιστρα μπορούν να οριστούν συνολικά ή μέσα σε ένα συγκεκριμένο describedμπλοκ. Το επόμενο Το παράδειγμα κώδικα στο αρχείο tests/System/integration/administrator/components/com_foos/FoosList.cy.jsπροκαλεί την εκτέλεση σύνδεσης στο backend πριν από κάθε δοκιμή εντός του describedμπλοκ test com_foos features.

Τώρα ξεκινάμε με το πρακτικό μέρος και δημιουργούμε το αρχείο tests/System/integration/administrator/components/com_foos/FoosList.cy.jsμε τον επόμενο κωδικό αποκομμένο πριν γράψουμε την πρώτη παραγωγική δοκιμή. Το πρώτο μας παράδειγμα θα πρέπει να μας συνδέσει με επιτυχία στο backend πριν από οποιαδήποτε δοκιμή! Θα το δοκιμάσουμε αφού δημιουργήσουμε την πρώτη δοκιμή.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js

describe('Test com_foos features', () => {
  beforeEach(() => {
    cy.doAdministratorLogin()
  })

})

Σημείωση: Τα άγκιστρα, που υλοποιούνται μέσα στο αρχείο /tests/System/support/index.js, εφαρμόζονται σε κάθε αρχείο δοκιμής στο δοκιμαστικό κοστούμι.

Μια επιτυχημένη δοκιμή

Το στοιχείο που εγκαταστήσαμε για δοκιμή περιέχει τα τρία στοιχεία Astridκαι Nina.Πρώτον Elmar, ελέγχουμε εάν αυτά τα στοιχεία δημιουργήθηκαν με επιτυχία.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js

describe('Test com_foos features', () => {
  beforeEach(() => {
    cy.doAdministratorLogin()
  })

  it('list view shows items', function () {
    cy.visit('administrator/index.php?option=com_foos')

    cy.get('main').should('contain.text', 'Astrid')
    cy.get('main').should('contain.text', 'Nina')
    cy.get('main').should('contain.text', 'Elmar')

    cy.checkForPhpNoticesOrWarnings()
  })
})

Σημείωση: Η συνάρτηση checkForPhpNoticesOrWarnings()που βρίσκετε στο αρχείο /node_modules/joomla-cypress/src/support.js.

Παίρνουμε το στοιχείο DOM mainμέσω της εντολής Cypress get

Θα πρέπει να βρείτε το τεστ που μόλις δημιουργήσατε FooList.cy.jsστη λίστα με τις διαθέσιμες δοκιμές στην αριστερή πλαϊνή γραμμή. Εάν δεν συμβαίνει αυτό, κλείστε το πρόγραμμα περιήγησης και εκτελέστε npm run cypress:openξανά.

Δοκιμή εκτέλεσης Joomla για δική σας επέκταση.

Κάντε κλικ στο όνομα του τεστ για να το εκτελέσετε. Θα πρέπει να τελειώσει με επιτυχία και θα δείτε πράσινα μηνύματα.

Η προβολή μετά τη δοκιμή έχει εκτελεστεί με επιτυχία.

Μια αποτυχημένη δοκιμή

Προσθέστε τη γραμμή cy.get('main').should('contain.text', 'Sami')στο αρχείο δοκιμής για να αποτύχει η εκτέλεση. Δεν υπάρχει στοιχείο με αυτό το όνομα. Μετά την αποθήκευση του αρχείου δοκιμής, το Cypress παρατηρεί την αλλαγή. Μετά από κάθε αλλαγή, το Cypress εκτελεί αυτόματα όλες τις δοκιμές στο αρχείο δοκιμής.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js
describe('Test com_foos features', () => {
  beforeEach(() => {
    cy.doAdministratorLogin()
  })

  it('list view shows items', function () {
    cy.visit('administrator/index.php?option=com_foos')

    cy.get('main').should('contain.text', 'Astrid')
    cy.get('main').should('contain.text', 'Nina')
    cy.get('main').should('contain.text', 'Elmar')
    cy.get('main').should('contain.text', 'Sami')

    cy.checkForPhpNoticesOrWarnings()
  })
})

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

Η προβολή μετά τη δοκιμή απέτυχε.

Εκτελέστε μόνο μία δοκιμή σε ένα αρχείο

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

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js

describe('Test com_foos features', () => {
    beforeEach(() => {
        cy.doAdministratorLogin()
    })

    it('list view shows items', function () {
        cy.visit('administrator/index.php?option=com_foos')

        cy.get('main').should('contain.text', 'Astrid')
        cy.get('main').should('contain.text', 'Nina')
        cy.get('main').should('contain.text', 'Elmar')

        cy.checkForPhpNoticesOrWarnings()
    })

    it.only('emptystate layout', function () {
        cy.visit('administrator/index.php?option=com_foos&view=foos&layout=emptystate')
        cy.get('main').should('contain.text', 'No Foo have been created yet.')
    })
})

Κατά τη διάρκεια της ανάπτυξης, αυτό είναι πολύ βολικό.

Ειδικά χαρακτηριστικά δοκιμής

Τώρα μας αρέσει να δοκιμάσουμε το frontend για το στοιχείο μας. Αυτό το κάνουμε σε ξεχωριστό αρχείο /tests/System/integration/site/components/com_foos/FooItem.cy.js.

Τις περισσότερες φορές χρησιμοποιούμε μια κλάση CSS για να λάβουμε στοιχεία σε δοκιμές Joomla. Αν και αυτό είναι απολύτως έγκυρο και θα λειτουργήσει, στην πραγματικότητα δεν συνιστάται. Γιατί όχι; Όταν χρησιμοποιείτε κλάσεις ή αναγνωριστικά CSS, συνδέετε τις δοκιμές σας με πράγματα που πιθανότατα θα αλλάξουν με την πάροδο του χρόνου. Οι τάξεις και τα αναγνωριστικά προορίζονται για σχεδιασμό, διάταξη και μερικές φορές μέσω JavaScript για έλεγχο, ο οποίος μπορεί εύκολα να αλλάξει. Εάν κάποιος αλλάξει ένα όνομα τάξης ή ένα αναγνωριστικό, οι δοκιμές σας δεν θα λειτουργούν πλέον. Για να κάνετε τα τεστ σας λιγότερο εύθραυστα και Η Cypress συνιστά τη δημιουργία ειδικών χαρακτηριστικών δεδομένων για τα στοιχεία σας, ειδικά για δοκιμαστικούς σκοπούς.

Θα χρησιμοποιήσω το data-testχαρακτηριστικό για τα στοιχεία Πρώτα προσθέτω το χαρακτηριστικό data-test="foo-main"στον κώδικα παραγωγής.

// /components/com_foos/tmpl/foo/default.php

\defined('_JEXEC') or die;
?>
<div data-test="foo-main">
Hello Foos
</div>

Στη συνέχεια δοκιμάζω τον κωδικό παραγωγής αναζητώντας το χαρακτηριστικό [data-test="foo-main"].

// tests/System/integration/site/components/com_foos/FooItem.cy.js
describe('Test com_foo frontend', () => {
  it('Show frondend via query in url', function () {
    cy.visit('index.php?option=com_foos&view=foo')

    cy.get('[data-test="foo-main"]').should('contain.text', 'Hello Foos')

    cy.checkForPhpNoticesOrWarnings()
  })
})
Δοκιμή ενός στοιχείου μενού και μερικές σκέψεις για συμβάντα, αναμονή και βέλτιστες πρακτικές

Τώρα μου αρέσει να δοκιμάζω τη δημιουργία ενός στοιχείου μενού για το στοιχείο μας. Αυτό το κάνω σε ξεχωριστό αρχείο /tests/System/integration/administrator/components/com_foos/MenuItem.cy.js. Αυτός ο κώδικας είναι περίπλοκος και εμφανίζει πολλά ειδικά χαρακτηριστικά.

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

const testMenuItem = {
  'title': 'Test MenuItem',
  'menuitemtype_title': 'COM_FOOS',
  'menuitemtype_entry': 'COM_FOOS_FOO_VIEW_DEFAULT_TITLE'
}

Στη συνέχεια βλέπετε ολόκληρο τον κώδικα του αρχείου MenuItem.cy.js:

// tests/System/integration/administrator/components/com_foos/MenuItem.cy.js

describe('Test menu item', () => {
  beforeEach(() => {
    cy.doAdministratorLogin(Cypress.env('username'), Cypress.env('password'))
  })

  it('creates a new menu item', function () {
    const testMenuItem = {
      'title': 'Test MenuItem',
      'menuitemtype_title': 'COM_FOOS',
      'menuitemtype_entry': 'COM_FOOS_FOO_VIEW_DEFAULT_TITLE'
    }

    cy.visit('administrator/index.php?option=com_menus&view=item&client_id=0&menutype=mainmenu&layout=edit')
    cy.checkForPhpNoticesOrWarnings()
    cy.get('h1.page-title').should('contain', 'Menus: New Item')

    cy.get('#jform_title').clear().type(testMenuItem.title)

    cy.contains('Select').click()
    cy.get('.iframe').iframe('#collapse1-heading').contains(testMenuItem.menuitemtype_title).click()
    cy.get('.iframe').iframe('#collapse1-heading').contains(testMenuItem.menuitemtype_entry).click()

    cy.intercept('index.php?option=com_menus&view=items&menutype=mainmenu').as('item_list')
    cy.clickToolbarButton('Save & Close')
    cy.wait('@item_list')
    cy.get('#system-message-container').contains('Menu item saved.').should('exist')

    // Frontend
    cy.visit('index.php')
    cy.get('.sidebar-right').contains(testMenuItem.title).click()
    cy.get('[data-test="foo-main"]').should('contain.text', 'Hello Foos')
    cy.checkForPhpNoticesOrWarnings()

    // Trash
    cy.visit('administrator/index.php?option=com_menus&view=items&menutype=mainmenu')
    cy.searchForItem(testMenuItem.title)
    cy.checkAllResults()
    cy.clickToolbarButton('Action')
    cy.intercept('index.php?option=com_menus&view=items&menutype=mainmenu').as('item_trash')
    cy.clickToolbarButton('trash')
    cy.wait('@item_trash')
    cy.get('#system-message-container').contains('Menu item trashed.').should('exist')

    // Delete
    cy.visit('administrator/index.php?option=com_menus&view=items&menutype=mainmenu')
    cy.setFilter('published', 'Trashed')
    cy.searchForItem(testMenuItem.title)
    cy.checkAllResults()
    cy.on("window:confirm", (s) => {
      return true;
    });
    cy.intercept('index.php?option=com_menus&view=items&menutype=mainmenu').as('item_delete')
    cy.clickToolbarButton('empty trash');
    cy.wait('@item_delete')
    cy.get('#system-message-container').contains('Menu item deleted.').should('exist')
  })
})
  • Σε αυτόν τον κώδικα μπορείτε να δείτε ένα παράδειγμα δοκιμής κάτι και στη συνέχεια διαγραφής όλων - έτσι επαναφέρετε την αρχική κατάσταση. Με αυτόν τον τρόπο μπορείτε να επαναλάβετε τις δοκιμές όσες φορές θέλετε. Χωρίς επαναφορά της αρχικής κατάστασης, η δεύτερη δοκιμαστική εκτέλεση θα αποτύχει επειδή το Joomla δεν μπορεί να αποθηκεύσει δύο παρόμοια στοιχεία.

Σημείωση: Μια δοκιμή πρέπει να είναι:

  • επαναληπτός.
  • Με συγκεκριμένους όρους, αυτό σημαίνει ότι θα πρέπει να δοκιμάσει ένα περιορισμένο πρόβλημα και ο κωδικός για αυτό δεν πρέπει να είναι πολύ εκτενής.
  • ανεξάρτητα από άλλες δοκιμές.
  • Και μπορείτε να δείτε πώς να χρησιμοποιήσετε μια διαδρομή που έχει οριστεί cy.intercept()ως ψευδώνυμο με το [^docs.cypress.io/api/commands/intercept] και, στη συνέχεια, να περιμένετε τη διαδρομή που ορίζεται ως ψευδώνυμο cy.wait().

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

  • Ο κωδικός δείχνει επίσης πώς να περιμένετε μια ειδοποίηση και να την επιβεβαιώσετε .
cy.on("window:confirm", (s) => {
  return true;
});
  • Τελευταίο αλλά εξίσου σημαντικό, ο κώδικας δοκιμής περιέχει το Cypress build in και τις τυπικές λειτουργίες του Joomla που μπορούν να επαναχρησιμοποιηθούν από προγραμματιστές επεκτάσεων. Για παράδειγμα, cy.setFilter('published', 'Trashed')ή cy.clickToolbarButton('Save & Close')είναι λειτουργίες στις οποίες μπορούν να βρεθούν λύσεις για μεμονωμένες δοκιμές γενικά και τις οποίες χρειάζονται συχνά οι προγραμματιστές του Joomla ειδικότερα .
Ανάμειξη Async και Sync Code

Οι εντολές Cypress είναι ασύγχρονες, δηλαδή δεν επιστρέφουν τιμή, αλλά generateαυτήν.Όταν ξεκινάμε το Cypress, δεν εκτελεί αμέσως τις εντολές, αλλά τις διαβάζει σειριακά και τις βάζει στην ουρά.Αν αναμίξετε ασύγχρονο και σύγχρονο κώδικα σε δοκιμές, μπορεί να λάβετε απροσδόκητα αποτελέσματα. Εάν εκτελέσετε τον ακόλουθο κώδικα, θα λάβετε ένα σφάλμα ενάντια στο αναμενόμενο. Σίγουρα θα περιμένατε επίσης ότι αυτό mainText = $main.text()αλλάζει την τιμή mainText. Αλλά mainText === 'Initial'εξακολουθεί να ισχύει στο τέλος. Γιατί συμβαίνει αυτό; Το Cypress εκτελεί πρώτα τον σύγχρονο κώδικα στο η αρχή και το τέλος.Μόνο τότε καλεί το ασύγχρονο τμήμα μέσα then().Δηλαδή mainTextαρχικοποιείται η μεταβλητή και αμέσως μετά ελέγχεται αν έχει αλλάξει -κάτι που φυσικά δεν ισχύει.

let mainText = 'Initial';
cy.visit('administrator/index.php?option=com_foos&view=foos&layout=emptystate')
cy.get("main").then(
  ($main) => (mainText = $main.text())
);

if (mainText === 'Initial') {
  throw new Error(`Der Text hat sich nicht geändert. Er lautet: ${mainText}`);
}

Η επεξεργασία της ουράς γίνεται αρκετά σαφής και οπτική αν παρατηρήσει κανείς την εκτέλεση του παρακάτω κώδικα στην κονσόλα του προγράμματος περιήγησης: Το κείμενο «Cypress Test.» εμφανίζεται πολύ πριν εμφανιστεί το περιεχόμενο του στοιχείου, αν και οι γραμμές του κώδικα mainείναι με διαφορετική σειρά.

cy.get('main').then(function(e){
  console.log(e.text())
})
console.log('Cypress Test.')
Stubs και Spies

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

Το A spyείναι παρόμοιο με το stub, αλλά όχι ακριβώς το ίδιο. Δεν αλλάζει τη συμπεριφορά μιας συνάρτησης, αλλά την αφήνει ως έχει. Καταγράφει ορισμένες πληροφορίες σχετικά με τον τρόπο κλήσης της συνάρτησης. Για παράδειγμα, για να ελέγξετε αν καλείται η συνάρτηση με τις σωστές παραμέτρους ή για να μετρήσετε πόσο συχνά καλείται η συνάρτηση.

Το παρακάτω παράδειγμα δείχνει το a spyκαι το a stubσε δράση.Μέσω const stub = cy.stub()δημιουργούμε το stubστοιχείο και προσδιορίζουμε στο επόμενο βήμα που falseεπιστρέφεται για την πρώτη κλήση και trueγια τη δεύτερη.Χρησιμοποιώντας cy.on('window:confirm', stub)κάνουμε το stubbe used for.Στο window:confirm'επόμενο βήμα δημιουργούμε με cy.spy(win, 'confirm').as('winConfirmSpy')το Spyστοιχείο , το οποίο παρατηρεί την κλήση του 'window:confirm'. Τώρα δοκιμάζουμε ότι στην πρώτη κλήση η διαγραφή της κατηγορίας απορρίπτεται και στη δεύτερη κλήση επιβεβαιώνεται. Με αυτόν τον τρόπο, διασφαλίζει stubότι μπορούμε να περιμένουμε με βεβαιότητα ποιες θα είναι οι επιστρεφόμενες τιμές παραδίδεται. 'window:confirm'είναι ενθυλακωμένη. @winConfirmSpyβοηθά στη διασφάλιση της πραγματικής κλήσης της συνάρτησης - και της συχνότητας κλήσης της.

// tests/System/integration/administrator/components/com_foos/FoosList.cy.js
...
const stub = cy.stub()

stub.onFirstCall().returns(false)
stub.onSecondCall().returns(true)

cy.on('window:confirm', stub)

cy.window().then(win => {
  cy.spy(win, 'confirm').as('winConfirmSpy')
})

cy.intercept('index.php?option=com_categories&view=categories&extension=com_foos').as('cat_delete')
cy.clickToolbarButton('empty trash');

cy.get('@winConfirmSpy').should('be.calledOnce')
cy.get('main').should('contain.text', testFoo.category)


cy.clickToolbarButton('empty trash');
cy.wait('@cat_delete')

cy.get('@winConfirmSpy').should('be.calledTwice')

cy.get('#system-message-container').contains('Category deleted.').should('exist')
...

Εάν πρόκειται απλώς να ορίσετε μια σταθερή τιμή για την 'window:confirm'κλήση, ο παρακάτω κωδικός θα κάνει τη δουλειά.

cy.on("window:confirm", (s) => {
  return true;
});

συμπέρασμα

Σε αυτό το άρθρο έχετε δει βασικές θεωρίες και πρακτικά χαρακτηριστικά της δοκιμής E2E με το Cypress. Χρησιμοποίησα την εγκατάσταση του Joomla για να δείξω πώς να γράφω διαφορετικά τεστ για να διασφαλίσω ότι ένα στοιχείο Joomla σε έναν ιστότοπο λειτουργεί όπως αναμένεται. Έδειξα επίσης πώς να προσαρμόσω το Cypress Δοκιμάστε το Runner στο αρχείο cypress.json και πώς να χρησιμοποιήσετε προσαρμοσμένες εντολές Cypress. Αυτό έγινε χρησιμοποιώντας εύκολα παραδείγματα.

Ελπίζω να σας άρεσε η περιοδεία μέσω του Cypress χρησιμοποιώντας το Joomla ως παράδειγμα και ότι μπορέσατε να αφαιρέσετε πολλές γνώσεις και έμπνευση για τον εαυτό σας.

An online collaborative community manual for Joomla! users, developers or anyone interested in learning more about Joomla! Currently, we have more than 9,000 articles written, maintained, and translated by our Joomla! community members. 

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