Menu

Cv-parsing testfixtures die bruikbaar blijven

Cv-parsing testfixtures moeten lay-outvarianten dekken in plaats van bestandsnummers. Zo organiseer je ze, wat ze moeten vaststellen, en hoe ze vervallen.

Gepubliceerd

  • testdata
  • carrière
  • parsing

Cv-parsing testfixtures zijn de kleine bibliotheek van documenten die een team bijhoudt zodat een parser kan worden getest tegen iets anders dan het bestand dat iemand toevallig open had. Ze zijn het minst glamoureuze deel van een recruitmentsysteem en het deel dat beslist of parsingdefecten in een testrun of in productie worden opgevangen.

Dit artikel behandelt waarom het formaatprobleem niet kan worden opgelost door een standaard te kiezen, welke lay-outs parsers werkelijk breken, hoe je de fixtures organiseert zodat een fout naar een oorzaak wijst, en waarom een set fixtures nooit af is.

Waarom is er geen standaardformaat voor een cv?

Omdat niets in het proces er een vereist. Een cv is een document dat iemand schrijft om door een mens te worden gelezen, in welk tool ze ook hebben, en de tools leggen helemaal geen gedeelde structuur op. Een tekstverwerkingsbestand met een tweekolomsindeling, een tekstexport uit een onlineprofiel, een gescande print, een slidevormig deck — al deze komen in dezelfde inbox aan en al deze zijn legitiem.

De afwezigheid van een standaard is geen omissie die betere tooling zal dichten, omdat de prikkels de andere kant op wijzen. De persoon die het cv schrijft, optimaliseert voor de indruk die een menselijke lezer in de eerste paar seconden vormt. De persoon die het leest, optimaliseert voor wat hij snel kan extraheren. Geen van beiden heeft enige reden om de lay-out te beperken om een parser te behagen.

Dat is het uitgangspunt waarop de hele teststrategie rust. Het doel is niet formaatconformiteit, want er is geen formaat om je aan te conformeren. Het doel is de juiste velden terughalen uit documenten waarvan niemand de lay-out beheert.

Welke lay-outvarianten moeten parsingtests dekken?

Die welke inhoud verplaatsen. Volgorde, kolommen en nabijheid tussen een label en zijn waarde zijn wat extractie breekt, veel vaker dan ongebruikelijke lettertypen of een ander paginabestand.

Lay-outvariant Wat het breekt
Tweekolomstekst De leesorde gaat verloren, zodat een datum in de rechterkolom aan een functie in de linkerkolom blijft hangen
Sectietitels in een ongebruikelijke volgorde Een parser die opleiding eerst verwacht, registreert niets voor de vermeldingen die later komen
Ervaring als proza geschreven Geen herhaalde blokstructuur, dus een parser die er een nodig heeft, vindt er geen
Vaardigheden als een tagrij Items lopen zonder scheidingstekens in elkaar over, en de splitsing ertussen wordt verzonnen
Tabellen gebruikt voor lay-out Een functie, een werkgever en een datum zitten in drie cellen zonder semantische relatie
Datums in niet-numerieke vorm Maandnamen, seizoenslabels en benaderende formulering verslaan numerieke matching
Kop- en voetteksten Contactgegevens worden op elke pagina gedupliceerd en kunnen de echte overschrijven

Een tweede as is even belangrijk: op welke pagina’s de contactgegevens staan, en of het document één variant of twee heeft. Een cv dat twee keer uit hetzelfde tool wordt geëxporteerd met een andere taal, heeft de sectietitels in een andere taal, en een parser die op die titels sleutelt, extraheert stil niets uit de tweede export.

Moeten fixtures op scenario of op nummer worden georganiseerd?

Op scenario, altijd. Het nummer vertelt je niets wanneer een test faalt, en het scenario vertelt je bijna alles.

Een fixture vernoemd naar wat ze bevat — een tweekolomsindeling, een tagrij van vaardigheden, een ervaringssectie als een paragraaf geschreven — is zelfdocumenterend. Wanneer ze faalt, is de naam een hypothese over waar de parser brak. Een fixture vernoemd met een index of een datum is een opzoeking die via een tweede document moet worden opgelost voordat er kan worden gedebugd, en dat tweede document is altijd verouderd.

De organisatie bepaalt ook wat er ontbreekt. Een bibliotheek gesorteerd op scenario toont haar eigen gaten in één oogopslag: als er geen fixture is voor een document zonder opleidingssectie, dan is dat geval nooit getest, en de afwezigheid is zichtbaar. Een bibliotheek gesorteerd op bestandsnummer verbergt dezelfde afwezigheid volledig.

Er is een tweede voordeel dat telt voor onderhoud. Scenarionamen overleven veranderingen aan de parser. Wanneer de implementatie wordt herschreven, beschrijft de fixturebibliotheek nog steeds de vormen die echte documenten aannemen, wat het deel is dat niet verandert.

Waarom maakt willekeurige generatie fouten onreproduceerbaar?

Omdat een willekeurige invoer geen registratie van iets is. Wanneer een test faalt tegen een willekeurig gegenereerd document, bestaat de fout in één run en nergens anders, en de enige manier om te onderzoeken is de generator aan te passen zodat hij het geval reproduceert — dat wil zeggen, er een fixture van te maken.

Dat is geen argument tegen willekeurige generatie, die echt goed is in het vinden van onverwachte vormen. Het is een argument over welke kant van de grens elk tool thuishoort. Willekeurige generatie hoort in de verkennende fase, waar het doel is een geval te ontdekken waar niemand aan dacht. Op het moment dat een geval wordt ontdekt, is het niet langer willekeurig en wordt het een fixture, met de invoer bevroren en de verwachte uitvoer vastgelegd. De regressie is dan vergrendeld op een geval dat bestaat.

Er is een subtieler probleem met willekeurige generatie naar de regressiesuite promoveren. Een willekeurig gegenereerd document varieert in elke dimensie tegelijk, dus een fout die eruit voortkomt kan niet aan één enkele dimensie worden toegeschreven. Een scenariofixture varieert met opzet één dimensie, en de fout die ze produceert noemt haar eigen oorzaak.

Hoe vervallen fixtures?

Langzaam, en op drie manieren die gemakkelijk te missen zijn omdat elk ervan als niets lijkt.

De echte documenten die ze imiteren veranderen: templates worden opnieuw ontworpen, een lay-out die vijf jaar geleden gangbaar was verdwijnt, en een nieuwe neemt haar plaats in. De fixture blijft slagen en blijft een vorm dekken die niemand meer indient. De talen verschuiven: een fixtureset die in één taal is gebouwd, test labelmatching alleen in die taal, en een tweede taal toevoegen is geen wijziging aan een fixture maar de toevoeging van een hele parallelle set. En de verwachtingen rotten weg tegen de parser: een assertie geschreven tegen een vroege versie van de extractielogica kan gedrag coderen dat later is gecorrigeerd, zodat de test nu een bekende bug handhaaft.

Geen van deze wordt door de suite zelf gedetecteerd, omdat elke fixture nog steeds slaagt. Verval wordt gevonden door review: de bibliotheek periodiek heropenen en vragen of elke fixture nog op iets echts lijkt, of elke ondersteunde taal er een heeft, en of elke assertie nog het gedrag beschrijft dat je wilt.

Voor ontwikkelaars: fixturevorm en verwachte velden

Houd de invoer en de verwachting samen, en houd de verwachting smal.

Een fixture is een paar: het document, en de velden die de parser eruit moet teruggeven. Ze op dezelfde plek houden betekent dat een wijziging aan een verwachting wordt beoordeeld naast de vorm die haar veroorzaakte. Houd de verwachte waarde leesbaar in plaats van gecodeerd, zodat een reviewer kan zien dat een datum in een bepaalde maand wordt verwacht zonder eerst een serienummer op te lossen.

Vier praktijken voorkomen de meeste pijn. Stel vast op de velden die de lay-out is ontworpen om te belasten, en laat de rest van de extractie losjes controleren, zodat een fixture niet wordt gebroken door een ongerelateerde verbetering elders. Leg de herkomst van elke fixture vast in een regel proza — voor dit doel geconstrueerd, lay-out gemodelleerd naar een gangbare vorm, geen echt document gebruikt — zodat niemand later hoeft te gissen of een bestand ergens gevoeligs vandaan kwam. Versioneer de fixtures met de parser zodat het mogelijk is te zien met welke set een gegeven resultaat is geproduceerd. En houd een bewust gat in de bibliotheek voor het geval waarvan je weet dat het niet wordt ondersteund, gedocumenteerd in plaats van stil afwezig, omdat een bekend gat een beslissing is en een onbekend gat een defect.

Alles wat een fixture bevat, moet voor het doel zijn geconstrueerd. De voorbeelddocumenten en verwachte velden die hier worden beschreven, zijn gebouwde voorbeelden die geen inhoud bevatten die uit een echte cv is gehaald, en ze bestaan om parsinglogica te oefenen in plaats van iemand te vertegenwoordigen.

Volgende stappen

Kies drie fixtures uit uw bestaande set en hernoem ze zodat de naam de lay-out beschrijft in plaats van een index. De oefening onthult bijna altijd dat twee ervan hetzelfde scenario twee keer zijn en dat een voor de hand liggende volledig ontbreekt. De sollicitatieformuliergevallen die de geparsede uitvoer consumeren, zijn de andere helft van hetzelfde testoppervlak, en als het doel volume is in plaats van lay-outs, dekt de walkthrough over het seeden van een stagingdatabase het op schaal. Wanneer u documenten nodig hebt om de bibliotheek uit op te bouwen, produceert de carrièreprofieltool het onderliggende record waarvan de fixtures de velden moeten verwachten.

Verder lezen

Handleidingen over Generator voor valse cv's en werkgegevens