Κάποιος μου έκανε πρόσφατα την εξής ερώτηση:
Αναπτύσσω ένα έργο pytest για να δοκιμάσω ένα API. Πώς μπορώ να μεταβιβάσω πληροφορίες περιβάλλοντος στις δοκιμές μου; Πρέπει να εκτελέσω δοκιμές σε διαφορετικά περιβάλλοντα όπως DEV, TEST και PROD. Κάθε περιβάλλον έχει διαφορετική διεύθυνση URL και ένα μοναδικό σύνολο χρηστών.
Αυτό είναι ένα κοινό πρόβλημα για αυτοματοποιημένες σουίτες δοκιμών, όχι μόνο σε Python ή pytest. Οποιαδήποτε πληροφορία χρειάζεται μια δοκιμή σχετικά με το υπό δοκιμή περιβάλλον καλείται μεταδεδομένα διαμόρφωσης. Οι διευθύνσεις URL και οι λογαριασμοί χρήστη είναι κοινές τιμές μεταδεδομένων διαμόρφωσης. Οι δοκιμές πρέπει να γνωρίζουν σε ποιον ιστότοπο θα επισκεφθούν και πώς να ελέγξουν την ταυτότητα.
Χρήση αρχείων διαμόρφωσης με μεταβλητή περιβάλλοντος
Υπάρχουν πολλοί τρόποι χειρισμού εισροών όπως αυτός. Μου αρέσει να δημιουργώ αρχεία JSON για την αποθήκευση των μεταδεδομένων διαμόρφωσης για κάθε περιβάλλον. Λοιπόν, κάτι σαν αυτό:
dev.json
test.json
prod.json
Κάθε ένα θα μπορούσε να μοιάζει με αυτό:
{
"base_url": "http://my.site.com/",
"username": "pandy",
"password": "DandyAndySugarCandy"
}
Η δομή κάθε αρχείου πρέπει να είναι η ίδια, ώστε οι δοκιμές να μπορούν να τα αντιμετωπίζουν εναλλακτικά.
Μου αρέσει να χρησιμοποιώ αρχεία JSON γιατί:
- είναι αρχεία απλού κειμένου με τυπική μορφή
- είναι εύκολο να διαφοροποιηθούν
- αποθηκεύουν δεδομένα ιεραρχικά
- Το πρότυπο της Python
json
Η ενότητα τα μετατρέπει σε λεξικά σε 2 γραμμές επίπεδες
Στη συνέχεια, δημιουργώ μια μεταβλητή περιβάλλοντος για να ορίσω το επιθυμητό αρχείο διαμόρφωσης:
export TARGET_ENV=dev.json
Στο έργο μου στο pytest, γράφω ένα εξάρτημα για να λάβω τη διαδρομή του αρχείου διαμόρφωσης από αυτήν τη μεταβλητή περιβάλλοντος και μετά να διαβάσω αυτό το αρχείο ως λεξικό:
import json
import os
import pytest
@pytest.fixture
def target_env(scope="session"):
config_path = os.environ['TARGET_ENV']
with open(config_path) as config_file:
config_data = json.load(config_file)
return config_data
Θα βάλω αυτό το εξάρτημα σε α conftest.py
αρχείο, ώστε όλες οι δοκιμές να μπορούν να το μοιραστούν. Δεδομένου ότι χρησιμοποιεί το εύρος της περιόδου λειτουργίας, το pytest θα το εκτελέσει μία φορά πριν από όλες τις δοκιμές. Οι συναρτήσεις δοκιμής μπορούν να το ονομάσουν ως εξής:
import requests
def test_api_get(target_env):
url = target_env['base_url']
creds = (target_env['username'], target_env['password'])
response = requests.get(url, auth=creds)
assert response.status_code == 200
Επιλογή του αρχείου διαμόρφωσης με όρισμα γραμμής εντολών
Εάν δεν θέλετε να χρησιμοποιήσετε μεταβλητές περιβάλλοντος για να επιλέξετε το αρχείο διαμόρφωσης, θα μπορούσατε να δημιουργήσετε ένα προσαρμοσμένο όρισμα γραμμής εντολών pytest. Ο Bas Dijkstra έγραψε ένα εξαιρετικό άρθρο δείχνοντας πώς να το κάνετε αυτό. Βασικά, μπορείτε να προσθέσετε την ακόλουθη συνάρτηση conftest.py
για να προσθέσετε το προσαρμοσμένο όρισμα:
def pytest_addoption(parser):
parser.addoption(
'--target-env',
action='store',
default="dev.json",
help='Path to the target environment config file')
Στη συνέχεια, ενημερώστε το target_env
αναπόσπαστο εξάρτημα:
import json
import pytest
@pytest.fixture
def target_env():
config_path = request.config.getoption('--target-env')
with open(config_path) as config_file:
config_data = json.load(config_file)
return config_data
Κατά την εκτέλεση των δοκιμών σας, θα πρέπει να καθορίσετε τη διαδρομή του αρχείου config ως εξής:
python -m pytest --target-env dev.json
Γιατί να ασχοληθείτε με τα αρχεία JSON;
Θεωρητικά, θα μπορούσες να περάσεις όλα εισάγει στις δοκιμές σας με ορίσματα γραμμής εντολών pytest ή μεταβλητές περιβάλλοντος. Δεν το κάνεις χρειάζομαι αρχεία διαμόρφωσης. Ωστόσο, θεωρώ ότι η αποθήκευση μεταδεδομένων διαμόρφωσης σε αρχεία είναι πολύ πιο βολική από τον ορισμό μιας δέσμης εισόδων κάθε φορά που χρειάζεται να εκτελώ τις δοκιμές μου. Στο παραπάνω παράδειγμά μας, η μετάδοση μιας τιμής για τη διαδρομή του αρχείου διαμόρφωσης είναι πολύ πιο εύκολη από τη διαβίβαση τριών διαφορετικών τιμών για τη διεύθυνση URL βάσης, το όνομα χρήστη και τον κωδικό πρόσβασης. Τα έργα δοκιμών πραγματικού κόσμου ενδέχεται να χρειάζονται περισσότερες πληροφορίες. Επιπλέον, οι διαμορφώσεις δεν αλλάζουν τη συχνότητα, επομένως είναι εντάξει να τις αποθηκεύσετε σε ένα αρχείο για επαναλαμβανόμενη χρήση. Απλώς βεβαιωθείτε ότι διατηρείτε τα αρχεία διαμόρφωσης ασφαλή εάν έχουν μυστικά.
Επικύρωση εισροών
Κάθε φορά που διαβάζετε εισροές, είναι καλή πρακτική να βεβαιωθείτε ότι οι τιμές τους είναι καλές. Διαφορετικά, οι δοκιμές θα μπορούσαν να καταρρεύσουν! Θα ήθελα να προσθέσω μερικούς βασικούς ισχυρισμούς ως ελέγχους ασφαλείας:
import json
import os
import pytest
@pytest.fixture
def target_env():
config_path = request.config.getoption('--target-env')
assert os.path.isfile(config_path)
with open(config_path) as config_file:
config_data = json.load(config_file)
assert 'base_url' in config_data
assert 'username' in config_data
assert 'password' in config_data
return config_data
Τώρα, το pytest θα σταματήσει αμέσως εάν οι είσοδοι είναι λανθασμένες.