Δοκιμές στη διαδρομή Arturo

Μάθε πώς να δοκιμάζεις τις ασκήσεις σου σε Arturo στο Exercism


Το track του Arturo χρησιμοποιεί το πακέτο τεστ μονάδας Unitt 3.0.0 για όλα τα τεστ των ασκήσεων. Αυτό το πακέτο παρέχει ένα framework για τεστ που υποστηρίζει και τη σύγχρονη σύνταξη εμπνευσμένη από το RSpec και την παλιότερη σύνταξη εμπνευσμένη από το XUnit. Το να τρέξεις το arturo tester.art ή το exercism test μέσα από τον τοπικό φάκελο της άσκησης θα εγκαταστήσει το πακέτο από το διαδίκτυο την πρώτη φορά. Εναλλακτικά, μπορείς να εγκαταστήσεις το Unitt τρέχοντας arturo --package install unitt 3.0.0. Θα τρέξει μόνο το πρώτο τεστ και το αποτέλεσμά του θα σου εμφανιστεί. Μόλις περάσει αυτό το τεστ, ενεργοποίησε το επόμενο και τρέξε ξανά τα τεστ, μέχρι να περάσει το καθένα. Και για τις δύο ρυθμίσεις, του RSpec και του XUnit, αρκεί να αφαιρέσεις το .skip από το it.skip ή το test.skip αντίστοιχα. Μόλις περάσουν όλα τα τεστ, υπέβαλε τη λύση σου, αλλά πρόσεξε: ο εκτελεστής τεστ τρέχει όλα τα τεστ, ακόμα και τα παραλειπόμενα.

Ξεκινώντας

Ο φάκελος της άσκησης που κατέβασες θα περιέχει κάποια αρχεία, αλλά αυτά είναι τα τρία βασικά.

leap/
├── src/leap.art         # Your solution file
├── tests/test-leap.art  # Test cases for the exercise
└── tester.art           # Test runner entry point

Όταν τρέξεις το arturo tester.art, θα ρυθμιστεί το Unitt και μετά θα τρέξουν τα τεστ μέσα στο tests/test-leap.art. Τα τεστ θα κάνουν import το src/leap.art, που περιέχει τη λύση σου, και μετά θα κάνουν μια σειρά από βεβαιώσεις για το τι πρέπει να επιστρέφει η λύση σου για συγκεκριμένες εισόδους.

Το αρχείο της λύσης

isLeap?: function [year][
    panic "please implement the isLeap? function"
]

Όταν ξεκινάς μια άσκηση, το αρχείο της λύσης σου έρχεται με ένα πρότυπο που περιέχει τη βασική δομή αυτού που αναμένεται. Σε αυτό το παράδειγμα από την άσκηση Leap, το αρχείο περιέχει έναν στοιχειώδη ορισμό της αναμενόμενης συνάρτησης isLeap? και, το σημαντικότερο, ένα panic που σταματά την εκτέλεση των τεστ. Αφαίρεσε τη γραμμή με το panic και μετά ξεκίνα να γράφεις την υλοποίησή σου για το isLeap?.

Η δομή των τεστ RSpec

import.version:3.0.0 {unitt}!
import {src/leap}!

describe "Leap" [
    it "a year not divisible by 4 is a common year" [
        expects.be:'false? @[isLeap? 2015]
    ]

    it.skip "a year divisible by 4 and not divisible by 100 is a leap year" [
        expects.be:'true? @[isLeap? 1996]
    ]
]
  • Το describe ορίζει ένα μπλοκ περιπτώσεων τεστ που επαληθεύουν κάτι κοινό. Τα μπλοκ αυτά μπορούν να είναι εμφωλευμένα.
  • Τα it και it.skip ορίζουν και τα δύο μία μόνο περίπτωση τεστ, η οποία είτε εκτελείται είτε παραλείπεται αντίστοιχα.
  • Το expects εισάγει τη βεβαίωση που βρίσκεται στην καρδιά μιας περίπτωσης τεστ. Το expects.be παίρνει μια συνάρτηση κατηγορήματος που χρησιμοποιείται για να γίνει η βεβαίωση.

Στο expects.be:'false? @[isLeap? 2015], η σουίτα τεστ βεβαιώνει ότι η συνάρτηση isLeap? πρέπει να επιστρέψει false για το έτος 2015. Ένας άλλος τρόπος να το γράψεις αυτό είναι expects.be:'equal? @[false isLeapYear? 2015], όπου βεβαιωνόμαστε ότι η τιμή επιστροφής του isLeapYear? 2015 είναι ίση με false. Αυτή η εκτενέστερη μορφή, που συγκρίνει δύο τιμές, είναι ο πιο συνηθισμένος τύπος βεβαίωσης στο track του Arturo. Η αναμενόμενη τιμή έρχεται πάντα πρώτη στο μπλοκ, πριν από την τιμή του αποτελέσματος.

Η δομή των τεστ XUnit

suite "Leap" [
    test "a year not divisible by 4 is a common year" [
        result: isLeap? 2015
        assert -> false = result
    ]

    test.skip "a year divisible by 4 and not divisible by 100 is a leap year" [
        result: isLeap? 1996
        assert -> true = result
    ]
]

Το API τύπου XUnit που παρουσιάστηκε στην έκδοση 1 του Unitt υποστηρίζεται για συμβατότητα με τα παλιότερα και είναι σε μεγάλο βαθμό ισοδύναμο με το σύγχρονο API τύπου RSpec, με τη διαφορά ότι οι βεβαιώσεις του είναι λιγότερο ευέλικτες.

  • Το suite ορίζει ένα μπλοκ περιπτώσεων τεστ που επαληθεύουν κάτι κοινό. Τα μπλοκ αυτά μπορούν να είναι εμφωλευμένα.
  • Τα test και test.skip ορίζουν και τα δύο μία μόνο περίπτωση τεστ, η οποία είτε εκτελείται είτε παραλείπεται αντίστοιχα.
  • Το assert εισάγει τη βεβαίωση που βρίσκεται στην καρδιά μιας περίπτωσης τεστ. Η έκφραση στα δεξιά του -> που ακολουθεί πρέπει να είναι αληθής.

Στα τεστ XUnit, συνήθως δημιουργούνται μεταβλητές που αναπαριστούν το αποτέλεσμα και, προαιρετικά, την αναμενόμενη τιμή, πριν από τη γραμμή assert.

Η έξοδος των τεστ

Είτε χρησιμοποιείς το API του RSpec είτε του XUnit, η έξοδος των τεστ θα είναι σε γενικές γραμμές παρόμοια. Η μόνη διαφορά θα είναι αυτό που εκτυπώνεται κάτω από το όνομα κάθε τεστ. Το XUnit αναφέρει τη βεβαίωση χρησιμοποιώντας τις τιμές που αξιολογήθηκαν, οπότε θα δεις false = false. Το RSpec, όμως, την αναφέρει ως false? false, επειδή χρησιμοποιήσαμε τη συνάρτηση false? με το expects.

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

Uncaught error in tests/test-leap.art:
#[
        output: {
                
                ══╡ Program Error ╞═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════ <script> ══
                
                  Please implement the isLeap? function
                
                
        }
        code: 1
]

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

======== .unitt/tests/test-leap.art ========

Describe: Leap

    ✅ - assert that a year not divisible by 4 is a common year
         ✅: false? false

    ⏩ - assert that a year divisible by 4 and not divisible by 100 is a leap year
         skipped!


========== Summary ==========

⏏️   TOTAL: 2 assertions
✅  PASSED: 1 assertion
⏩ SKIPPED: 1 assertion
❌  FAILED: 0 assertion

========== ======= ==========

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

======== .unitt/tests/test-leap.art ========

Describe: Leap

    ✅ - assert that a year not divisible by 4 is a common year
         ✅: false? false

    ❌ - assert that a year divisible by 4 and not divisible by 100 is a leap year
         ❌: true? false


========== Summary ==========

⏏️   TOTAL: 2 assertions
✅  PASSED: 1 assertion
⏩ SKIPPED: 0 assertion
❌  FAILED: 1 assertion

========== ======= ==========

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