Οι σημερινοί προγραμματιστές χρησιμοποιούν όλο και περισσότερες ευέλικτες πρακτικές στην καθημερινή τους εργασία. Ακόμη και έργα που ακολουθούν τον τυπικό κύκλο ζωής ανάπτυξης λογισμικού μπορούν να επωφεληθούν από την προσαρμογή τους. Οι αυτόματες δοκιμές και η TDD έφεραν περισσότερη εμπιστοσύνη στη δουλειά μας, διευκόλυναν την εφαρμογή τροποποιήσεων σε υπάρχοντα χαρακτηριστικά και συχνά μας οδηγούσαν σε καλύτερο σχεδιασμό κώδικα. Τώρα όμως δεν αρκούν μόνο αυτά. Πρέπει να ωθήσουμε τα οφέλη από τις δοκιμές στα όρια και η BDD το επιτρέπει αυτό. η BDD βασίζεται πάνω στην TDD και προσθέτει στις πρακτικές της μεγάλη αξία. Φέρνει την πανταχού παρούσα γλώσσα στο έργο, επιτρέπει την καλύτερη επικοινωνία μεταξύ πελάτη και προγραμματιστών. Προσφέρει πολλά για τους διαχειριστές και τους επικεφαλής του έργου, αλλά και κάνει τη ζωή ενός προγραμματιστή πολύ πιο εύκολη. Η τήρηση των αρχών BDD μας δίνει σαφείς απαιτήσεις, οι δοκιμές είναι πιο κατανοητές και μπορούν να χρησιμεύσουν ως τεκμηρίωση. Η BDD μετατοπίζει την εστίαση των θεμάτων ελέγχου και μας δίνει την αυτοπεποίθηση ότι ελέγχουμε αυτό που πρέπει να ελέγχουμε - τη συμπεριφορά.
Αν χρησιμοποιείτε την TDD, η έναρξη της BDD θα είναι εύκολη - πρόκειται ουσιαστικά για ένα σύνολο βέλτιστων πρακτικών γι' αυτήν. Το BDD έχει ένα σύνολο απλών κανόνων, οι οποίοι λένε πώς να γράψετε προδιαγραφές και τι να δοκιμάσετε. Οι προδιαγραφές χωρίζονται σε τρία μέρη: Given (δημιουργία συνθηκών δοκιμής), When (κλήση ενέργειας στο υποκείμενο) και Then (ισχυρισμοί). Οι δοκιμές πρέπει να έχουν περιγραφικά ονόματα και τα υπάρχοντα πλαίσια δοκιμών επιτρέπουν τη χρήση μεθόδων και ισχυρισμών που είναι παρόμοιες με τη φυσική γλώσσα - όλα αυτά σε συνδυασμό μας δίνουν δοκιμές που είναι αναγνώσιμες τόσο από τεχνικούς όσο και από μη τεχνικούς χρήστες. Οι καλές συμβάσεις ονοματοδοσίας αποδεικνύονται χρήσιμες κατά τη διάρκεια των δοκιμών παλινδρόμησης.
Η BDD συνοδεύεται επίσης από ένα σύνολο κατευθυντήριων γραμμών για τα υποκείμενα δοκιμών. Σε αντίθεση με την TDD μετατοπίζει την εστίαση από τη δοκιμή της υλοποίησης στη δοκιμή της συμπεριφοράς - και η χρήση της οδηγεί σε καλύτερο σχεδιασμό και παρέχει μεγαλύτερη ευελιξία όταν πρέπει να εισαχθεί αλλαγή. Οι προδιαγραφές θα πρέπει να είναι σαν γραπτές και εκτελέσιμες απαιτήσεις του πελάτη - οι απαιτήσεις υψηλού επιπέδου θα πρέπει να λειτουργούν ως δοκιμές αποδοχής. Ο στόχος είναι να γράφονται οι δοκιμές με τέτοιο τρόπο ώστε να χρειάζεται να αλλάζουν μόνο όταν αλλάζουν οι απαιτήσεις. Η χρήση της BDD μας δίνει τη σιγουριά ότι δοκιμάζουμε αυτό που πραγματικά πρέπει να καλυφθεί και είναι μια πιο ρεαλιστική προσέγγιση από την TDD.
Αν θέλετε να δείτε το BDD σε δράση, σας προτείνουμε το Ruby. Είναι μια ισχυρή και διασκεδαστική γλώσσα και διαθέτει ένα εξαιρετικό σύνολο εργαλείων BDD.
Αγγούρι
Το Cucumber είναι το πιο δημοφιλές πλαίσιο για BDD στη Ruby. Εισάγει ειδική γλώσσα, που ονομάζεται Gherkin, στην οποία θα γράφετε τις δοκιμές σας. Σε αντίθεση με την RSpec, τα χαρακτηριστικά που περιγράφονται στο Gherkin είναι απλό κείμενο, όχι κωδικός, και ως τέτοια μπορεί - και πρέπει - να γίνει κατανοητή από οποιονδήποτε, κυρίως από τον πελάτη.
Το χαρακτηριστικό Cucumber μοιάζει με αυτό (το παράδειγμα προέρχεται από το wiki του Cucumber):
Χαρακτηριστικό γνώρισμα: Κάποιο συνοπτικό αλλά περιγραφικό κείμενο για το τι είναι επιθυμητό
Περιγραφή της επιχειρησιακής αξίας αυτής της δυνατότητας.
Επιχειρηματικοί κανόνες που διέπουν το πεδίο εφαρμογής του χαρακτηριστικού
Οποιαδήποτε πρόσθετη πληροφορία που θα διευκολύνει την κατανόηση του χαρακτηριστικού.
Σενάριο: Κάποια προσδιορίσιμη επιχειρηματική κατάσταση
Δεδομένης κάποιας προϋπόθεσης
Και κάποια άλλη προϋπόθεση
Όταν κάποια ενέργεια από τον δράστη
Και κάποια άλλη ενέργεια
Και μια ακόμη ενέργεια
Τότε επιτυγχάνεται κάποιο ελέγξιμο αποτέλεσμα
Και συμβαίνει και κάτι άλλο που μπορούμε να ελέγξουμε
Σενάριο: Μια διαφορετική κατάσταση
...
Τα χαρακτηριστικά θα περιγραφούν λεπτομερώς αργότερα.
Χρήση του Cucumber στο Ruby on Rails
Εγκατάσταση
Πρώτο βήμα για να χρησιμοποιήσετε το αγγούρι στο έργο το εγκαθιστά. Απλά προσθέστε αυτά τα δύο gems στο Gemfile σας:
group :test do
gem 'cucumber-rails', :require => false
gem 'database_cleaner'
end
Συγκεντρώστε τα εκτελώντας την εντολή εγκατάσταση δέσμης, και δημιουργήστε σενάρια και καταλόγους Cucumber με την ακόλουθη εντολή:
rails generate cucumber:install
Αυτό θα δημιουργήσει config/cucumber.yml, script/cucumber και χαρακτηριστικά/κατάλογος, το οποίο θα περιέχει .feature αρχεία, καθώς και ορισμούς βημάτων και υποστηρικτικά αρχεία. Για να εκτελέσετε τα χαρακτηριστικά σας, χρησιμοποιήστε μια νέα εντολή rake:
τσουγκράνα αγγούρι
Χαρακτηριστικά
Ας ρίξουμε μια πιο προσεκτική ματιά στα χαρακτηριστικά. Ένα χαρακτηριστικό είναι κάτι που έχει ή κάνει η εφαρμογή σας - για παράδειγμα στέλνει περιοδικά ενημερωτικό δελτίο ή επιτρέπει στο χρήστη να μοιράζεται τις φωτογραφίες του δημόσια. Ένα χαρακτηριστικό αποτελείται από πολλαπλά σενάρια, τα οποία περιγράφουν τον τρόπο λειτουργίας αυτού του χαρακτηριστικού σε διαφορετικά πλαίσια.
Για να επιδείξουμε τη βασική χρήση του Cucumber στο Rails, θα γράψουμε ένα χαρακτηριστικό από το μηδέν. Αυτό το χαρακτηριστικό παράδειγμα θα είναι το πρώτο που θα γράψουμε στην εφαρμογή, η οποία θα παρουσιαστεί στο επερχόμενο δεύτερο μέρος αυτού του άρθρου. Αυτή η εφαρμογή θα επιτρέπει στον χρήστη να δημιουργεί αντικείμενα και καταστήματα (τα καταστήματα πωλούν αντικείμενα) και στη συνέχεια να δημιουργεί λίστες αγορών.
Στην απλούστερη έκδοση, μετά τη σύνταξη της λίστας αγορών, η εφαρμογή θα δείχνει σε ποια καταστήματα τα είδη που επιθυμεί ο χρήστης είναι τα φθηνότερα.
Αρχικά, δημιουργήστε ένα νέο αρχείο με όνομα create_item.feature στο χαρακτηριστικά/ κατάλογο. Στην κορυφή ενός .feature αρχείο υπάρχει ένα Χαρακτηριστικό γνώρισμα λέξη-κλειδί, ακολουθούμενη από μια σύντομη περιγραφή της. Για παράδειγμα:
Χαρακτηριστικό γνώρισμα: Δημιουργία αντικειμένων
Στις επόμενες γραμμές μπορείτε να γράψετε έναν επιχειρηματικό στόχο που θα υλοποιεί αυτό το χαρακτηριστικό. Δεδομένου ότι το Cucumber αγνοεί το κείμενο που γράφεται πριν από το πρώτο Σενάριο, δεν είναι απαραίτητο να γράψετε τίποτα, αλλά είναι σίγουρα μια καλή ιδέα.
Για να δημιουργήσετε εύκολα λίστες αγορών με αντικείμενα που πωλούνται σε κοντινά καταστήματα
Ως χρήστης
Θέλω να προσθέσω αντικείμενα στο σύστημα
Στο απόσπασμα, μπορείτε να δείτε ένα αρκετά δημοφιλές μοτίβο παραπάνω με το οποίο μπορείτε να περιγράψετε τους επιχειρηματικούς στόχους. Αποτελείται από τρία μέρη: γιατί είναι απαραίτητο το χαρακτηριστικό, ποιος το θέλει και τι είναι αυτό. Φυσικά, δεν χρειάζεται να ακολουθήσετε αυτό το σχήμα, αλλά φροντίστε να συμπεριλάβετε απαντήσεις σε αυτές τις τρεις ερωτήσεις στην περιγραφή σας.
Σενάρια
Στη συνέχεια, γράφουμε μερικά σενάρια. Κάθε σενάριο αρχίζει με τη λέξη-κλειδί "Σενάριο" και περιέχει πολλαπλά βήματα.
Σενάριο: δημιουργία μοναδικού στοιχείου
Δεδομένου ότι υπάρχει ένα στοιχείο "Γάλα"
Όταν πηγαίνω στην κεντρική σελίδα
Και δημιουργώ το στοιχείο "Ψωμί"
Τότε βλέπω το "Ψωμί" στη λίστα στοιχείων.
Έτσι, αν κάποιος δημιούργησε το στοιχείο με το όνομα Γάλα, τότε η δημιουργία του Ψωμιού είναι δυνατή και έχει ως αποτέλεσμα την εμφάνιση του Ψωμιού στη λίστα στοιχείων. Δεν θα πρέπει να ελέγξουμε τη δημιουργία εγγραφής στη βάση δεδομένων, αφού αυτό το γεγονός δεν έχει πραγματική αξία για τον πελάτη.
Τα βήματα του σεναρίου χρησιμοποιούν τρεις βασικές λέξεις-κλειδιά:
Δεδομένου, για την παροχή πλαισίου στο σενάριο
Όταν, για την περιγραφή δράσεων
Τότε, για την περιγραφή των αποτελεσμάτων
Είναι σημαντικό να σημειωθεί ότι το Cucumber αγνοεί το βήμα της λέξης-κλειδί με το οποίο ξεκινάει και ταιριάζει μόνο με το μεταγενέστερο μέρος. Έτσι, μπορείτε να ξεκινήσετε τα βήματά σας με "And" όπου σας φαίνεται φυσικό. Ο μόνος κανόνας για την επιλογή της σωστής λέξης-κλειδί είναι ότι το Σενάριο πρέπει να είναι εύκολα κατανοητό.
Ορισμοί βημάτων
Η εκτέλεση του Cucumber παράγει τώρα αυτή την έξοδο:
[...]
Χαρακτηριστικό: Δημιουργία αντικειμένων
Για να δημιουργήσετε εύκολα λίστες αγορών με αντικείμενα που πωλούνται σε κοντινά καταστήματα
Ως χρήστης
Θέλω να προσθέσω αντικείμενα στο σύστημα
Σενάριο: δημιουργία μοναδικού αντικειμένου # features/create_item.feature:6
Δεδομένου ότι υπάρχει ένα στοιχείο "Γάλα" # features/create_item.feature:7
Απροσδιόριστο βήμα: "υπάρχει ένα στοιχείο "Milk" Item" (Cucumber::Undefined)
[...]
Αυτό συμβαίνει επειδή το Cucumber δεν ξέρει τι εννοούμε όταν λέμε "υπάρχει ένα στοιχείο Milk Item". Για να προσθέσετε κάποιο νόημα στα βήματά σας πρέπει να τα ορίσετε στο step_definitions κατάλογο.
Ένας συνιστώμενος τρόπος για να οργανώσετε τους ορισμούς των βημάτων σας είναι να τους χωρίσετε ανά τομέα. Για παράδειγμα, τα περισσότερα από τα βήματα που έχουμε δημιουργήσει, ανήκουν στον τομέα Item. Έτσι, θα πρέπει να δημιουργήσουμε ένα αρχείο με όνομα step_definitions/item_steps.rb και τοποθετήστε εκεί τον ακόλουθο κώδικα:
Δεδομένου ότι "υπάρχει ένα στοιχείο "$name"" do |name|
Fabricate :item, name: name
end
Όταν "δημιουργώ αντικείμενο "$name"" do |name|
μέσα στο "#new_item" do
fill_in "Όνομα", με: name
click_on "Create"
end
end
Then "I see "$name" on the Item list" do |name|
εντός ".items" do
expect(page).to have_content name
end
end
Οι ορισμοί των βημάτων θα βασίζονται συνήθως στο Capybara. Εάν δεν είστε εξοικειωμένοι με το Capybara, φροντίστε να ελέγξετε τους συνδέσμους στο τέλος αυτού του άρθρου.
Υπάρχει ένα ακόμη βήμα που χρειάζεται ορισμό και δεν ταιριάζει πραγματικά στα βήματα του στοιχείου. Θα μπορούσατε να το βάλετε στο main_page_steps.rb:
Όταν "πηγαίνω στην κεντρική σελίδα" κάνω
επισκεφτείτε τη διαδρομή root_path
end
Συμπέρασμα
Αυτή είναι μια πολύ απλή ιστορία για μια πολύ απλή λειτουργία. Σκοπός της ήταν να επιδείξει τις βασικές έννοιες του BDD όπως αυτές χρησιμοποιούνται στο Cucumber. Η συγγραφή καλών ιστοριών απαιτεί όμως λίγο περισσότερα. Ως προγραμματιστής, θα πρέπει να αλλάξετε εντελώς τη νοοτροπία σας - ξεχάστε την υλοποίηση και επικεντρωθείτε στους επιχειρηματικούς στόχους. Το Cucumber διευκολύνει αυτή τη μετάβαση με την έξυπνη χρήση ιστοριών απλού κειμένου.