La création de fonctionnalités CLI se résume souvent à :
Chaque étape nécessite la précédente et oups, nous avons réinventé la gestion de projet en cascade. Vous êtes épuisé par la douleur en essayant d'effacer gracieusement les erreurs jusqu'à ce que vous boitiez jusqu'à devenir fonctionnel, mais vous vous retirez bien avant l'exceptionnel. Et ne me lancez pas dans la maintenance du groupe de « correctifs » et de verrues ad hoc qui en résulte.
J'y suis allé, j'ai fait ça. Nous savions que nous devions dépasser l’approche en cascade.
Voici l'histoire de la façon dont nous y sommes arrivés et quelques-uns des outils qui nous ont aidé tout au long du chemin.
Nous souhaitions une itération rapide et bon marché jusqu'à ce que nous comprenions la fonctionnalité, et ensuite seulement nous nous engageons dans une mise en œuvre coûteuse et un support à long terme. En tant que petite équipe, je faisais souvent ce processus de bout en bout et je voulais me concentrer sur chaque partie à tour de rôle. Nous voulions simuler des éléments d'implémentation jusqu'à ce que nous nous sentions suffisamment en confiance pour y parvenir.
Pour en revenir au processus, cela commence par proposer des fonctionnalités. Nous voulions sortir de l’abstrait, mais pas si cela impliquait une mise en œuvre à moitié cuite. Nous l'avons simulé avec des « croquis », inspirés de l'approche de croquis CLI de Google Docs décrite par Github ici.
Malheureusement, les croquis statiques ne nous ont pas donné le retour que nous souhaitions. Notre CLI modifie la sortie au fil du temps, plus comme une animation que comme un dessin. Pour obtenir une plus grande fidélité, j'ai écrit de petits programmes Ruby pour prendre en compte les entrées de base et répondre en imprimant des réponses prédéfinies appropriées.
Depuis, nous avons trouvé un moyen encore meilleur de capturer une sortie CLI animée, mais pour expliquer cela nécessite un petit détour.
Alors que nous commencions à étoffer notre CLI, nous souhaitions également tester les cas extrêmes et détecter les régressions. J'ai interrogé les CLI publiques basées sur Cobra/Bubbletea pour rechercher des idées et j'ai trouvé, de manière frustrante, peu de tests. Ensuite, nous sommes tombés sur le test de Charm qui nous a donné un point de départ.
Teatest se concentre sur les tests de référence, capturant un bon résultat connu, puis affirmant que les futurs résultats continuent de lui correspondre. Ce qui nous a ramené, une fois de plus, à la capture haute fidélité des sorties CLI animées. Teatest nous a donné l'idée géniale d'une solution basée sur des cadres, comme un flipbook, sur laquelle nous avons construit :
─── SigninHeader ─────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` ─── SigninInput --────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` ? What is your username? ? user ─── SigninInput ──────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` * Signing in to your CLI account… ⠋ ─── SigninInput ──────────────────────────────────────────────────────────────── # Signin To Your CLI Account `cli auth signin` * Signed in to your CLI account: user@example.com
Cet exemple simplifié montre à quoi pourrait ressembler une sortie dorée pour une commande d'autorisation de base. Les lignes horizontales délimitent les cadres, avec des étiquettes indiquant le modèle actif. Ensemble, nous obtenons une capture haute fidélité de la sortie même lorsque des lignes sont ajoutées, supprimées ou remplacées.
Nous utilisons un indicateur dans notre suite de tests pour mettre à jour les fichiers avec les sorties dorées, sinon les tests échouent si la sortie ne correspond pas aux fichiers. Cela nous tient au courant des changements de sortie et facilite les examens des relations publiques en nous permettant de comprendre à quoi devrait ressembler le résultat et s'il a changé. Nous l'aimons tellement que nous prévoyons de remplacer nos programmes de croquis par une sortie de style doré dans des documents Google de style Github afin de pouvoir capturer à la fois des idées d'animation et de style.
Avec nos croquis une fois et futurs en main, revenons à la prise en main des nouveaux points de terminaison d'API.
Nous travaillons simultanément sur l'API et la CLI, car les meilleures conceptions pour celles-ci naissent d'une intégration étroite. Nous sommes capables de le faire, tout en évitant les périls de la cascade, en itérant sur des conceptions dans des contextes moins chers et en attendant la mise en œuvre jusqu'à ce que les exigences se solidifient. Pour nos API, cela signifie dessiner avec OpenAPI :
openapi: 3.1.0 info: contact: email: contact@example.com description: An example API. title: Example API version: 0.0.1 servers: - url: https://api.example.com tags: - description: account operations name: account paths: '/v0/auth/signin': post: description: Signin to CLI. operationId: auth_signin responses: '200': content: 'application/json': schema: additionalProperties: false properties: email: description: Email address for authenticated user. example: username@example.com type: string required: - email type: object description: Successful signin. summary: Signin to CLI. tags: - account
Cet exemple simplifié montre à quoi pourrait ressembler un schéma pour une commande d'autorisation de base. Nous utilisons le linter spectral pour simplifier le travail sur ces fichiers.
Avec un croquis en main, nous utilisons ensuite prism comme serveur API fictif pendant que nous implémentons la CLI. Lorsque nous réalisons inévitablement que des erreurs ont été commises, nous pouvons simplement modifier les spécifications et revenir à notre itération CLI. Travailler à ce niveau élevé nous permet de faire évoluer l'API et la CLI ensemble et de différer une mise en œuvre coûteuse jusqu'à ce que nous ayons de meilleures connaissances.
Nous nous appuyons également sur nos spécifications OpenAPI pour rester honnêtes lors de la mise en œuvre en utilisant le comité. assert_schema_conform teste l'alignement et le middleware nous informe de toute divergence en direct. Ceux-ci se combinent pour permettre la mise en œuvre du rouge vert tout en nous protégeant des régressions.
Pour compléter les choses, notre suite de tests utilise des indicateurs pour exécuter Prism en mode simulé ou proxy. En utilisant des indicateurs, nous pouvons nous concentrer sur l'écriture d'un seul type de test, même si cela signifie que nous ignorons certains tests dans un mode ou dans l'autre. Nous utilisons des tests simulés pour leur vitesse et sur Windows et macOS où notre pile complète ne fonctionne pas en CI. Nos tests proxy nous permettent d'exécuter des tests sur l'ensemble de notre pile en ajoutant simplement un indicateur, ce qui facilite l'exécution de tests de bout en bout chaque fois que nous le jugeons nécessaire.
Les croquis et les spécifications nous aident à parcourir le résumé sans avoir à nous enliser dans la mise en œuvre. Ensuite, les simulations et les proxys nous aident à garantir que les implémentations correspondent aux croquis. En continuant à répéter notre processus, chaque fonctionnalité est moins pénible, ce que nous avons profondément apprécié tout en créant l'expérience des équipes que nous proposerons plus tard ce mois-ci.
Nous continuerons à répéter notre processus, j'espère que vous en avez appris quelque chose et j'aimerais apprendre de vous. Qu'avez-vous essayé, où êtes-vous fier et qu'est-ce qui reste frustrant ?
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!