Software die direct op een machine draait, stelt totaal andere eisen aan testen dan een webapplicatie of een mobiele app. Er is geen browser om in te refreshen, geen server om opnieuw op te starten en geen gebruiker die een foutmelding wegklikt. Als de software faalt, staat de machine stil, of erger nog: beweegt hij verkeerd. Voor een embedded software engineer is testen daardoor een vak apart. In dit artikel beantwoorden we de meest gestelde vragen over het testen van machinesoftware, van de eerste unit test tot het draaien op echte hardware.
Wat maakt het testen van machinesoftware anders dan gewone software?
Machinesoftware werkt in een fysieke omgeving met harde tijdseisen, beperkte resources en directe koppeling aan hardware. Fouten hebben directe gevolgen voor beweging, veiligheid en productie. Dat maakt het testen fundamenteel anders dan het testen van applicatiesoftware, waarbij een bug hooguit een scherm laat bevriezen.
Bij gewone software kun je omgevingen eenvoudig nabootsen en ontkoppelen. Bij embedded en machinesoftware ben je afhankelijk van sensoren, actuatoren, besturingskaarten en communicatieprotocollen die zich niet altijd laten simuleren. Bovendien zijn de timing en de volgorde van events cruciaal: een reactie die 10 milliseconden te laat komt, kan in een real-time systeem al een fout veroorzaken.
Daarnaast spelen veiligheidseisen een grote rol. Machines in de hightech industrie en machinebouw moeten voldoen aan normen voor functionele veiligheid. Testen is daar geen optie, maar een verplichting die ook gedocumenteerd moet worden.
Welke testmethoden zijn geschikt voor embedded en machinesoftware?
Voor embedded software development zijn unit testing, integration testing, hardware-in-the-loop testing en system testing de meest gebruikte methoden. Welke combinatie je kiest, hangt af van het type systeem, de beschikbaarheid van hardware en de veiligheidseisen van het project.
Een goede teststrategie voor machinesoftware bevat doorgaans meerdere lagen:
- Unit tests: geïsoleerde tests van individuele functies of klassen, uitgevoerd op de ontwikkelomgeving zonder hardware
- Integration tests: testen of modules correct samenwerken, inclusief communicatie via protocollen zoals CAN, EtherCAT of Modbus
- Hardware-in-the-loop (HIL): de software draait op echte hardware, maar de machine zelf wordt gesimuleerd via een testopstelling
- System tests: volledige tests op de echte machine, waarbij alle subsystemen samenwerken onder realistische omstandigheden
- Regression tests: geautomatiseerde herhaaltests die controleren of nieuwe code bestaande functionaliteit niet breekt
Test Driven Development (TDD) wordt steeds vaker toegepast in embedded omgevingen, ook al vraagt het om een andere aanpak dan in applicatieontwikkeling. Door tests eerst te schrijven, dwing je jezelf na te denken over de grenzen van een module voordat je de implementatie start.
Hoe test je real-time software zonder de machine stil te leggen?
Real-time software test je zonder de machine stil te leggen door gebruik te maken van simulatieomgevingen, testmodi in de software zelf en hardware-in-the-loop opstellingen. Zo kun je timing, volgorde en randgevallen valideren zonder productie te onderbreken.
Een veelgebruikte aanpak is het inbouwen van een testmodus in de software. De machine reageert dan op gesimuleerde inputsignalen in plaats van echte sensordata. Dit maakt het mogelijk om scenario’s te testen die in productie zelden of nooit voorkomen, zoals het uitvallen van een sensor of een onverwachte piekbelasting.
Daarnaast helpt het om de software modulair op te bouwen. Als de besturingslogica losgekoppeld is van de hardware-abstractielaag, kun je de logica testen op een standaard pc, zonder dat je de machine nodig hebt. Dit versnelt de ontwikkelcyclus aanzienlijk en maakt continue integratie ook in embedded trajecten haalbaar.
Wat is het verschil tussen testen op hardware en testen in simulatie?
Testen op hardware geeft de meest betrouwbare resultaten omdat de software draait in de echte omgeving met echte timing, echte signalen en echte mechanische responsen. Testen in simulatie is sneller, goedkoper en veiliger, maar kan nooit alle fysieke randgevallen volledig nabootsen.
Beide aanpakken vullen elkaar aan. Simulatie is ideaal in vroege ontwikkelingsfases, wanneer hardware nog niet beschikbaar is of wanneer je snel wilt itereren. Hardware-testen is onmisbaar voor validatie, veiligheidsgoedkeuring en het detecteren van problemen die alleen optreden in de fysieke wereld, zoals elektrische ruis, mechanische speling of temperatuurvariaties.
Een embedded software developer die beide aanpakken beheerst, kan efficiënter werken: simulatie voor de dagelijkse iteraties, hardware voor de definitieve validatie. Het risico van alleen op simulatie vertrouwen is dat je pas laat in het project ontdekt dat de software zich in de echte omgeving anders gedraagt dan verwacht.
Welke tools gebruiken software engineers voor het testen van machinesoftware?
Software engineers in de machinebouw en hightech industrie gebruiken een combinatie van generieke testframeworks en domeinspecifieke tools, afhankelijk van de programmeertaal, het platform en de vereisten van het project.
Veelgebruikte tools en frameworks zijn onder andere:
- Google Test (gtest): een populair C++ testframework dat goed werkt voor unit tests in embedded omgevingen
- Catch2: een lichtgewicht alternatief voor C++ met een leesbare syntax en goede integratie in CI-pipelines
- NUnit / xUnit: voor C#-gebaseerde machinesoftware, zoals toepassingen op Windows-gebaseerde besturingsplatforms
- pytest: voor Python-gebaseerde testscripts en automatisering van testsequenties
- LDRA / VectorCAST: professionele tools voor functionele veiligheid en code coverage in gecertificeerde omgevingen
- Jenkins / GitLab CI: voor het automatiseren van builds en testsuites in een continuous integration workflow
Welke tools het meest relevant zijn, hangt sterk af van het project. Bij werken als developer bij PROMEXX kom je in aanraking met uiteenlopende toolchains, afhankelijk van de klant en het type systeem.
Hoe voorkom je de meest gemaakte fouten bij het testen van machinesoftware?
De meest gemaakte fouten bij het testen van machinesoftware zijn: te laat beginnen met testen, te weinig aandacht voor randgevallen en het overslaan van integratietests omdat de tijdsdruk hoog is. Deze fouten zijn te voorkomen door testen structureel onderdeel te maken van het ontwikkelproces.
Concrete aandachtspunten om fouten te voorkomen:
- Begin met testen vanaf de eerste sprint, niet pas als de software “af” is
- Test expliciet op randgevallen: wat gebeurt er bij een sensor die uitvalt, een communicatietime-out of een onverwachte bewegingsopdracht?
- Documenteer testresultaten, zeker als er veiligheidsnormen gelden
- Zorg dat integratietests niet worden overgeslagen onder tijdsdruk; juist daar zitten de subtiele bugs
- Review testcode net zo serieus als productiecode
Een veelgehoorde valkuil is dat engineers testen zien als iets wat je aan het einde doet. In embedded software development geldt dat juist andersom: hoe eerder je test, hoe goedkoper het is om fouten te herstellen. Een bug die je op de machine ontdekt, kost veel meer tijd dan een bug die je in een unit test vindt.
Hoe PROMEXX engineers helpt bij het testen van machinesoftware
Het testen van software voor machines en hightech systemen vraagt om ervaring, de juiste tooling en een omgeving waarin je dit vak serieus kunt uitoefenen. Wij begrijpen dat en bouwen dat actief in hoe we werken en hoe we engineers begeleiden.
Als je bij ons werkt als embedded software engineer of embedded software developer, profiteer je van:
- Projecten bij grote hightechbedrijven en gespecialiseerde mkb-bedrijven, waar testen een serieus onderdeel is van het proces
- Kennissessies en trainingen over testmethoden, tooling en kwaliteitsborging
- Collega’s met diepgaande ervaring in C++, C#, real-time software en machinebesturing
- Begeleiding en coaching, zodat je je testvaardigheden structureel kunt uitbouwen
- Afwisselende projecten waarbij je telkens nieuwe omgevingen, platforms en uitdagingen tegenkomt
Wil je werken aan inhoudelijk uitdagende projecten waarbij software en hardware echt samenkomen? Bekijk dan onze openstaande vacatures voor C++ software engineers of lees meer over wat je kunt verwachten als je bij ons aan de slag gaat. We zijn actief vanuit onze kantoren in Eindhoven en Rotterdam en horen graag van je.
Veelgestelde vragen
Hoe begin ik als embedded software engineer met het opzetten van een teststrategie voor een nieuw project?
Begin met het inventariseren van de veiligheidseisen, de beschikbare hardware en de kritieke functionaliteit van het systeem. Stel op basis daarvan een gelaagde teststrategie op: start met unit tests voor de kernlogica, plan integratietests voor de communicatieprotocollen en bepaal vroeg in het project wanneer je hardware-in-the-loop testing nodig hebt. Hoe eerder je deze keuzes maakt, hoe makkelijker het is om de software modulair en testbaar te ontwerpen.
Wat doe ik als mijn unit tests slagen maar de software zich op de echte machine toch anders gedraagt?
Dit is een klassiek signaal dat de hardware-abstractielaag niet volledig overeenkomt met de werkelijkheid, of dat er timing- en omgevingsfactoren meespelen die in simulatie niet zichtbaar zijn. Controleer eerst of je mocks en stubs de echte hardware-signalen nauwkeurig genoeg nabootsen. Voeg vervolgens gerichte integratietests en hardware-in-the-loop tests toe om het gat tussen simulatie en realiteit te overbruggen, en gebruik logging of tracing op de hardware om het afwijkende gedrag te reproduceren.
Hoe richt ik een CI/CD-pipeline in voor embedded software waarbij niet altijd hardware beschikbaar is?
Splits je pipeline op in twee sporen: een snel spoor voor unit tests en statische code-analyse dat volledig op een standaard build-server draait, en een trager spoor voor hardware-in-the-loop en integratietests dat wordt getriggerd bij releases of nachtelijke builds. Tools zoals Jenkins of GitLab CI maken het mogelijk om hardware-afhankelijke teststappen conditioneel uit te voeren wanneer de testopstelling beschikbaar is. Zo profiteer je van continue integratie zonder dat elke commit hardware vereist.
Welke code coverage norm is realistisch en zinvol voor machinesoftware?
Voor machinesoftware zonder strikte veiligheidscertificering is een code coverage van 70–80% op unit testniveau een realistisch en zinvol streven, mits de kritieke paden volledig gedekt zijn. Bij systemen die onder functionele veiligheidsnormen vallen, zoals IEC 61508 of ISO 26262, kunnen strengere eisen gelden, tot 100% MC/DC-coverage voor de hoogste integriteitsniveaus. Vergeet niet dat coverage een middel is, geen doel: 80% coverage met doordachte tests is waardevoller dan 100% coverage met triviale tests die geen randgevallen raken.
Hoe test ik communicatieprotocollen zoals CAN of EtherCAT zonder een volledige machineomgeving?
Gebruik protocol-specifieke simulatietools of dedicated hardware interfaces om de communicatielaag geïsoleerd te testen. Voor CAN zijn tools zoals CANalyzer of open-source alternatieven zoals SocketCAN bruikbaar om berichten te simuleren en te monitoren. Voor EtherCAT bieden leveranciers vaak testmasters of slave-simulatoren aan. Door de communicatielaag achter een abstractie-interface te plaatsen, kun je in unit tests bovendien eenvoudig mock-implementaties gebruiken die het protocol nabootsen zonder fysieke hardware.
Hoe ga ik om met het testen van veiligheidskritieke functies, zoals noodstop-logica?
Veiligheidskritieke functies vereisen een combinatie van formele verificatie, uitputtende unit tests op alle mogelijke inputcombinaties en verplichte hardware-tests onder realistische omstandigheden. Documenteer elke testcase expliciet en koppel deze aan de functionele veiligheidseisen uit de risicoanalyse. Laat veiligheidskritieke testcases bij voorkeur reviewen door een collega-engineer en zorg dat de testresultaten traceerbaar zijn, zodat je bij een audit kunt aantonen dat elke eis gevalideerd is.
Hoe houd ik mijn regressietests onderhoudbaar naarmate het project groeit?
Investeer vroeg in een duidelijke testarchitectuur: groepeer tests per module, gebruik beschrijvende namen die aangeven wat er getest wordt en waarom, en verwijder of update tests actief wanneer de bijbehorende functionaliteit wijzigt. Behandel testcode als productiecode: review het, refactor het en houd het in hetzelfde versiebeheersysteem. Een testset die niet onderhouden wordt, groeit uit tot een last in plaats van een vangnet, en engineers beginnen dan tests te negeren of te omzeilen.