Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial Internet of Things >> Ingebed

Statusmachines ontwikkelen met testgestuurde ontwikkeling

Aangezien state machine-modellen veel worden gebruikt in embedded systemen, onderzoekt dit artikel verschillende strategieën om state machine (SM)-software te ontwikkelen volgens de Test-Driven Development (TDD)-benadering. Deze publicatie begint met het uitleggen van basisconcepten van toestandsmachines en de TDD-techniek. Ten slotte introduceert het eenvoudige en geordende methoden om state machine-software te ontwikkelen die is geschreven in C met behulp van de TDD-benadering.

Een SM-model is opgebouwd uit toestanden, overgangen en acties. Terwijl een toestand een toestand is van een systeem of een element, is een overgang een pad van de ene toestand naar de andere, meestal geïnitieerd door een interessante gebeurtenis die een voorgaande (bron) toestand verbindt met een volgende (doel) toestand. Het daadwerkelijke gedrag dat door het element wordt uitgevoerd, wordt weergegeven in acties.

In de UML-statusmachine kunnen acties worden geassocieerd met het binnenkomen in een staat, het verlaten van een staat, een transitie op zich, of wat een 'interne transitie' of 'reactie' wordt genoemd. Alle formalismen van de toestandsmachine (inclusief UML-toestandsmachines) gaan er universeel van uit dat een toestandsmachine de verwerking van elke gebeurtenis voltooit voordat deze kan beginnen met de verwerking van de volgende. Dit uitvoeringsmodel wordt Run To Completion (RTC) genoemd. In dit model kunnen acties enige tijd in beslag nemen, maar alle lopende gebeurtenissen moeten wachten tot de toestandsmachine is voltooid - inclusief de volledige exit-actie, de transitieactie en de invoeractiereeks in die volgorde.

Alvorens in te gaan op de strategieën om toestandsmachines te ontwikkelen met behulp van TDD, is het de moeite waard om de definitie, het belang en de toepassing ervan te vermelden.

Ten eerste is TDD een techniek om software stapsgewijs te bouwen. Simpel gezegd, er wordt geen productiecode geschreven zonder eerst een falende unittest te schrijven. Testen zijn klein. Testen zijn geautomatiseerd. Testrijden is logisch, d.w.z. in plaats van in de productiecode te duiken (testen overlaten voor later) drukt de TDD-beoefenaar het gewenste gedrag van de code uit in een test. Zodra de test mislukt, schrijft de TDD-beoefenaar de code, waardoor de test slaagt. De kern van het TDD-proces is een zich herhalende cyclus die bestaat uit korte stappen die bekend staan ​​als "TDD-microcycli".

De stappen van de TDD-cyclus in de volgende lijst zijn gebaseerd op het boek 'Test-Driven Development for Embedded C' van James Grenning:

  • Voeg een kleine test toe.
  • Voer alle tests uit en als de nieuwe mislukt, wordt deze mogelijk niet eens gecompileerd.
  • Maak de kleine wijzigingen die nodig zijn om de test te doorstaan.
  • Voer alle tests uit en bewijs of de nieuwe slaagt.
  • Refactor om duplicatie te verwijderen en de expressiviteit te verbeteren.

Laten we het diagram in figuur 1 gebruiken om een ​​eenvoudigere manier te vinden om een ​​toestandsmachine te ontwikkelen met behulp van TDD. Wanneer de statusmachine is geïnitialiseerd, begint deze vanaf de StateA staat. Zodra het de Alpha . heeft ontvangen gebeurtenis, gaat de toestandsmachine over naar de StateB state door de acties xStateA(), effect() en nStateB() in die volgorde uit te voeren. Dus, hoe kan men de SM van figuur 1 testen om te bepalen of deze zich correct gedraagt?


Figuur 1. Basisstatusmachine (Bron:VortexMakes)

De meest traditionele en eenvoudigste manier om een ​​SM zoals figuur 1 te testen, bestaat voornamelijk uit het verifiëren van de toestandsovergangstabel van de SMUT (State Machine Under Test). Dit maakt een testcase per staat , waarbij de SMUT wordt gestimuleerd door de gebeurtenissen die van belang zijn om te verifiëren welke overgangen worden geactiveerd. Tegelijkertijd houdt dit in dat de doelstatus en de uitgevoerde acties voor elke geactiveerde overgang worden gecontroleerd. Als een actie voldoende complex is, is het geschikter om daar een specifieke testcase voor te maken. (Het artikel State-machines testen met unit-test legt deze strategie uitgebreid uit).

Elke testcase is verdeeld in vier verschillende fasen volgens xUnit-patronen:

  • Instellen stelt de randvoorwaarden van de test vast, zoals de huidige status van de SM (StateA ), de gebeurtenis die moet worden verwerkt (Alpha ), en de verwachte testresultaten, die de doelstatus van de overgang zijn (StateB ) en de gesorteerde lijst met uit te voeren acties (xStateA(), effect() en nStateB()).
  • Oefening stimuleert de toestandsmachine met de Alpha evenement.
  • Verifiëren controleert de verkregen resultaten.
  • Opruimen zet de te testen toestandsmachine na de test terug in de begintoestand. Het is optioneel.

De hierboven genoemde strategie is voldoende om een ​​SM te ontwikkelen met behulp van TDD. In sommige gevallen is echter meer dan een enkele overgang nodig om de functionaliteit te controleren. Dit komt omdat het effect alleen zichtbaar wordt door een reeks acties van opeenvolgende overgangen, wat betekent dat functionaliteit een reeks toestanden, gebeurtenissen en overgangen van de SMUT omvat. In deze gevallen is het beter om een ​​volledig en functioneel scenario te testen dan geïsoleerde toestandsovergangen. Hierdoor zijn testgevallen functioneler en minder abstract dan de eerder genoemde strategieën.

Laten we de toestandsmachine in figuur 2 gebruiken om dit concept te verkennen.


Figuur 2. De DoWhile-statusmachine (Bron:VortexMakes)

Afbeelding 2 toont een toestandsmachine genaamd DoWhile, die een uitvoeringslus modelleert die lijkt op een 'do-while'-lus. DoWhile is getekend met behulp van Yakindu Statechart Tool. De acties 'x =0' en 'output =0' worden aangeroepen wanneer DoWhile wordt gemaakt en deze acties stellen de standaardwaarde van alle attributen van DoWhile in. Het aantal lus-iteraties moet worden ingesteld via 'x++' of 'x =(x> 0) ? x–:x’ acties. De actie 'i =0' stelt beginvoorwaarden voor de lus vast. De body van de lus wordt uitgevoerd door de actie 'i++', die de iteraties van de lus bijhoudt, waarna de beëindigingsvoorwaarde wordt geëvalueerd door de pseudostate van de keuze via de 'i ==x'-guard. Als het waar is, wordt de hoofdtekst van de lus opnieuw geëvalueerd, enzovoort. Wanneer de beëindigingsvoorwaarde onwaar wordt, beëindigt de lus het uitvoeren van de actie 'output =i'.

Het is handig om een ​​testlijst te maken voordat u nieuwe functionaliteit ontwikkelt. De testlijst is afgeleid van de specificatie en definieert de beste visie van wat er moet gebeuren. Omdat het niet perfect hoeft te zijn, is de vorige lijst slechts een tijdelijk document dat later kan worden gewijzigd. De eerste testlijst voor DoWhile wordt hieronder weergegeven:

  • Alle gegevens worden standaard ingesteld nadat SM is geïnitialiseerd
  • X-kenmerk verhogen
  • X-kenmerk verlagen
  • Er kan een enkele iteratielus worden uitgevoerd
  • Er kan een meervoudige iteratielus worden uitgevoerd
  • Een niet-iteratielus kan worden uitgevoerd
  • Check out-of-bounds waarden

Om de DoWhile-statusmachine te ontwikkelen, zullen Ceedling en Unity worden gebruikt in combinatie met de meest eenvoudige maar heldere programmeertechniek:het gebruik van 'switch-case'-zinnen. Ceedling is een bouwsysteem om een ​​volledige test- en bouwomgeving voor een C-project te genereren; Unity is een lichtgewicht, draagbaar, expressief C-taal testharnas voor C-projecten.

Twee bestanden vertegenwoordigen deze statusmachine, DoWhile.h en DoWhile.c, dus ze zijn de broncode die wordt getest. Codelijst 1 toont een fragment van het test_DoWhile.c-bestand, dat de bovenstaande testlijst implementeert door de eerder genoemde strategie toe te passen. Om dit artikel eenvoudig te houden, toont Code Listing 1 alleen de testcase:'Een enkele iteratielus kan worden uitgevoerd', die wordt geïmplementeerd door test_SingleIteration(). Zowel de code als het model zijn beschikbaar in https://github.com/leanfrancucci/sm-tdd.git repository.


Codelijst 1:Single iteratietest (Bron:VortexMakes)

Deze test verifieert dat DoWhile slechts één iteratie correct kan uitvoeren. Om dat te doen, initialiseert de test_SingleIteration() de DoWhile-statusmachine door DoWhile_init() (regel 96) aan te roepen. Het stelt het iteratienummer voor nul in dat moet worden uitgevoerd door de DoWhile-lus. Daarna is de DoWhile klaar om gebeurtenissen te verwerken door DoWhile_dispatch() aan te roepen. Om een ​​enkele iteratie uit te voeren, stuurt test_SingleIteration() de Up evenement naar DoWhile (lijn 97). Deze gebeurtenis verhoogt het iteratienummer naar één. De test start de lus door de Start . te verzenden gebeurtenis (regel 98), dan verzendt het de Alpha event zodat DoWhile een enkele iteratie uitvoert (regel 99). Dit wordt gecontroleerd door te verifiëren dat de waarde van het out-attribuut gelijk is aan het aantal uitgevoerde iteraties (regel 101). Ten slotte moet DoWhile in de StateC . blijven staat (regel 102).

Om te bewijzen dat DoWhile meer dan één iteratie kan uitvoeren, wordt de test_SingleIteration() uitgebreid zoals weergegeven in Code Listing 2.


Codelijst 2:Test met meerdere iteraties (Bron:VortexMakes)

De test_NoneIteration()-test die wordt weergegeven in codelijst 3 controleert of DoWhile geen iteratie uitvoert bij het ontvangen van een Alpha evenement zonder vooraf het iteratienummer in te stellen via Omhoog evenementen.


Codelijst 3:Non-iteratietest (Bron:VortexMakes)

Hoewel de implementatiedetails van DoWhile niet het doel van dit artikel zijn, tonen Code Listing 4 en Code Listing 5 een deel van de DoWhile.c- en DoWhile.h-bestanden. Deze bestanden vertegenwoordigen in feite een demonstratieve implementatie van DoWhile met behulp van 'switch-case'-zinnen in C.


Codelijst 4:Fragment van DoWhile-implementatie (Bron:VortexMakes)


Codelijst 5:Fragment van DoWhile-specificatie (Bron:VortexMakes)

Beide hierboven geïntroduceerde strategieën bieden eenvoudige en geordende methoden om state machine-software te ontwikkelen met behulp van TDD - een van de belangrijkste benaderingen om de softwarekwaliteit te verbeteren.

De eerste strategie bestaat voornamelijk uit het verifiëren van de toestandsovergangstabel van de SMUT. Deze methode maakt een testcase per staat . De andere strategie stelt voor om een ​​testcase te realiseren voor een compleet en functioneel scenario , waarbij vaak een reeks staten, gebeurtenissen en acties van de SMUT betrokken zijn. Deze tweede strategie maakt de test functioneler en minder abstract dan de eerste. Hoewel deze strategieën onafhankelijk zijn van een bepaald soort systeem, programmeertaal of tool, zijn ze erg handig in embedded systemen, omdat veel van hen state-based gedrag vertonen dat doorgaans wordt gedefinieerd in een of meer state-machines.

De taal C is gekozen omdat het een van de meest populaire talen is voor de ontwikkeling van embedded software. Dus om TDD in die taal toe te passen, zijn Ceedling en Unity gekozen. Concluderend stellen deze methoden ontwikkelaars zeker in staat om op een eenvoudigere en geordende manier een veel flexibelere, onderhoudbare en herbruikbare software te bouwen dan traditionele benaderingen.


Ingebed

  1. maanden problemen met CNC-machines
  2. t uw kennis over productie met verticale freesmachines
  3. Frezen in harmonie met CNC-machines verhogen de betrouwbaarheid
  4. Kleine machines met een grote technologieportfolio
  5. Hoe problemen met gebruikte CNC-machines te voorkomen
  6. Evolutie van testautomatisering met kunstmatige intelligentie
  7. Projecten van de grond krijgen met outsourcing
  8. The State of Manufacturing 2021 - Deel 2 - Met Make UK
  9. Altijd een gladde afwerking met Okamoto-slijpmachines
  10. Wat kunt u maken met een CNC-machine?
  11. Module vervangt diskette door USB, Ethernet naar oudere machines