Github actions, unit testen en validatie

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Yariva
  • Registratie: November 2012
  • Laatst online: 15:44

Yariva

Moderator Internet & Netwerken

Power to the people!

Topicstarter
Mijn vraag
Ik beheer een stukje geschreven open source Python code welke inmiddels in tractie flink toeneemt. Steeds meer gebruikers zijn er afhankelijk van en hoewel ik vandaag steeds meer werk met code en hier steeds comfortabeler mee word ben ik nog niet bekend genoeg om hier de juiste knopen mee door te hakken.

Nu er steeds meer feature requests in het project plaatsvinden en commits / PR's door 3 maintainers worden ingeschoten wil ik nu ingrijpen voordat het overzicht echt weg is.

In het kort: het stukje code wordt gebruikt om 2 systemen aan elkaar te koppelen. Dit maakt het voor mij lastig gezien een test hierop draaien een stuk lastiger (voor mij) zal zijn met HTTP API REST calls tussen de 2 systemen. Ik heb hier iets vernomen over het "mocken" van API's maar hier heb ik simpelweg nog te weinig verstand van. Mocht dit het ei van Columbus zijn heb ik er geen probleem mee om hier extra tijd aan te spenderen, echter was ik al een andere richting op gegaan.

Relevante software en hardware die ik gebruik
Github actions, Git, Python, Docker, Docker compose

Wat ik al gevonden of geprobeerd heb
Gisteravond heb ik geprobeerd om een Github action op te zetten waarin een ubuntu-latest image wordt gebruikt, de nodige dependencies wordt geinstalleerd (docker compose, docker, python), binding naar onderliggende docker stack en daarna een git clone gedaan van een van de 2 software pakketten in compose vorm. Ik kreeg de stack verder niet operationeel, de applicatie kreeg geen verbinding met de database in de zelfde compose stack.

Het globale idee wat ik voor nu voor ogen heb:
1. Github action inrichten met unittests / script draaien tegen 2 test systemen. Een van deze 2 test systemen is gevuld met dummy data (pg export inladen in postgresql voordat de volledige compose stack operationeel is). Het andere systeem is ontvanger, hier moet ook een DB dump naar toe maar dan vooral voor een account met token voor HTTP REST API toegang.
2. Draai het script met verschillende parameters, opties etc. en kijk of deze crashed of niet. Bij een crash zal het script zelf een foute exit code sturen en zal de Git action dan ook falen.
3. Unittests op de modules waarop dit wel kan zoals class functies en modules zonder REST calls.

Zit ik hiermee op de juiste weg en heeft er iemand ervaring om op een soortgelijke manier een test uit te voeren met docker (compose) in een Github action? Of zitten we hier wel veel haken en ogen aan.

Uiteraard een linkje naar de code voor wie er geinteresseerd in is / wil kijken onder de motorkap :) https://github.com/TheNetworkGuy/netbox-zabbix-sync

En uiteraard heb ik zelf naar vergelijkbare resources gekeken:
https://medium.com/@nima....ion-template-4c0b77abe3c3
https://datawookie.dev/blog/2024/04/dind-in-github-actions/

[ Voor 4% gewijzigd door Yariva op 15-04-2025 09:59 ]

Mensen zijn gelijk, maar sommige zijn gelijker dan andere | Humans need not apply

Alle reacties


Acties:
  • +3 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Je moet denk onderscheid maken tussen Unit testen, Integratie testen en e2e testen.

Unit testen werken doorgaans binnen het process en heb je dus geen http integratie voor nodig, daar instancieer je meestal een kleiner deel van de code en test je die unit.

Als de 2 componenten binnen dezelfde verantwoordelijkheid vallen is het ook handig om daar inderdaad integratie testen voor te hebben waarbij ze tegen elkaar integreren. Binnne je test suite run je dan beide componenten die echt tegen elkaar praten. Voor externe systemen is het inderdaad vaak handig om een mock/dummy te hebben waar je tegen kunt testen, de externe services zijn namelijk niet perse betrouwbaar, en je wil controle hebben over de output die je krijgt om bijvoorbeeld foutsituaties te kunnen testen.

Voor een mock zijn er verschillende oplossingen, je kunt zelf een eenvoudige implementatie schrijven, of je kunt gebruik maken van een tool die bijvoorbeeld gewoon een soort recording kan afspelen. Ik ben niet zo thuis in Python wat hier de beste tools zijn, voor bijvoorbeeld .NET gebruik ik Wiremock om dat te doen. Maar er zijn ook gewoon losse tools die je er voor kunt gebruiken.

Voor betrouwbare testen binnen je CI pipeline wil je vooral dat alles gecontroleerd binnen de pipeline draait, en je dus geen shared resources hebt die kunnen veranderen, want er is niks zo vervelend als een wispelturige build die je regelmatig nog een keer moet draaien omdat er een extern systeem niet beschikbaar was, of dat je testen aan moet passen omdat de data aangepast is, of er meerdere runs van de testen draaine.

[ Voor 15% gewijzigd door Woy op 15-04-2025 10:53 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • itons
  • Registratie: Oktober 2003
  • Niet online
Eerst maar eens stukje theorie:
https://martinfowler.com/testing/
https://carloarg02.medium...st-flakiness-a87be42b37aa

Hierna regels voor je project opstellen dat alle MR's met tests moeten komen, en in de pipeline je test coverage bepalen. MR's die de coverage onder een bepaald percentage brengen niet mergen.

Acties:
  • 0 Henk 'm!

  • TheGhostInc
  • Registratie: November 2000
  • Niet online
Yariva schreef op dinsdag 15 april 2025 @ 09:54:
Mijn vraag
Nu er steeds meer feature requests in het project plaatsvinden en commits / PR's door 3 maintainers worden ingeschoten wil ik nu ingrijpen voordat het overzicht echt weg is.
Neem je maintainers en community ook gewoon mee.

Misschien zit er wel iemand tussen die dit even in elkaar ramt.
En maak ook afspraken over wat je verwacht bij een change. Code zonder unit tests? Niet geaccepteerd.
Refactor zonder integratie tests? Terug naar de zolderkamer.

Acties:
  • 0 Henk 'm!

  • Yariva
  • Registratie: November 2012
  • Laatst online: 15:44

Yariva

Moderator Internet & Netwerken

Power to the people!

Topicstarter
Duidelijk, zo te horen moet ik van het huidige plan afwijken en meer gaan leren over het mocken van API's voor integratie tests. Verder kan ik wel beginnen met wat basis unittests die kleine functies controleren.

Mensen zijn gelijk, maar sommige zijn gelijker dan andere | Humans need not apply


Acties:
  • 0 Henk 'm!

  • Yariva
  • Registratie: November 2012
  • Laatst online: 15:44

Yariva

Moderator Internet & Netwerken

Power to the people!

Topicstarter
Woy schreef op dinsdag 15 april 2025 @ 10:51:
Je moet denk onderscheid maken tussen Unit testen, Integratie testen en e2e testen.

Unit testen werken doorgaans binnen het process en heb je dus geen http integratie voor nodig, daar instancieer je meestal een kleiner deel van de code en test je die unit.

Als de 2 componenten binnen dezelfde verantwoordelijkheid vallen is het ook handig om daar inderdaad integratie testen voor te hebben waarbij ze tegen elkaar integreren. Binnne je test suite run je dan beide componenten die echt tegen elkaar praten. Voor externe systemen is het inderdaad vaak handig om een mock/dummy te hebben waar je tegen kunt testen, de externe services zijn namelijk niet perse betrouwbaar, en je wil controle hebben over de output die je krijgt om bijvoorbeeld foutsituaties te kunnen testen.
Om hier toch nog op terug te komen: is het omgekeerde ook niet waar? Namelijk dat zodra externe systemen een API endpoint veranderen / iets in hun logica aanpassen dat het met een mock vanaf mijn kant niet zal worden opgevangen en de code dus wordt gepubliceerd terwijl deze eigenlijk niet goed zal werken.

Mensen zijn gelijk, maar sommige zijn gelijker dan andere | Humans need not apply


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 27-09 13:03
Dat zou dan moeten worden opgevangen met e2e testen wright?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Yariva
  • Registratie: November 2012
  • Laatst online: 15:44

Yariva

Moderator Internet & Netwerken

Power to the people!

Topicstarter
farlane schreef op woensdag 23 april 2025 @ 12:25:
Dat zou dan moeten worden opgevangen met e2e testen wright?
Yes maar tot zover heb ik een manier om dit op te zetten of voorbeelden hiervan nog niet goed langs zien komen. Bijvoorbeeld wat ik aanhaalde in de TS: zou je dan een zooi docker compose instances met een Github Action moeten opspinnen?

Verder begint het mocken nu gelukkig eindelijk een beetje te klikken. Geloof het of niet maar het is erg ongrijpbaar voor mij als code leek :) Maar dit doet nu wat ik wil van een functie welke een GET en POST API call doet naar een extern systeem.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def test_device_deletion():
    """Checks device deletion process"""
    nb_device = mock_nb_device()
    nb_device.status.value = "decommissioning"
    nb_device.status.label = "Decommissioning"
    nb_device.custom_fields["zabbix_hostid"] = 1956

    mock_zabbix_api = MagicMock()
    mock_zabbix_api.host.get.return_value = True
    mock_zabbix_api.host.delete.return_value = True

    device = PhysicalDevice(nb_device, mock_zabbix_api, netbox_journals, nb_version,
                            create_journal, logger)
    device.cleanup()
    assert nb_device.custom_fields["zabbix_hostid"] == None


Gezien het object nb_device flink wat herbruikbare data bevat gooi ik dit in een algemene functie welke ik voor veel verschillende tests kan hergebruiken. Vervolgens pas ik per test een aantal specifieke variabele aan welke echt vereist zijn voor de test om te werken.

[ Voor 9% gewijzigd door Yariva op 23-04-2025 13:33 ]

Mensen zijn gelijk, maar sommige zijn gelijker dan andere | Humans need not apply

Pagina: 1