{"id":37666,"date":"2019-10-31T22:18:55","date_gmt":"2019-10-31T19:18:55","guid":{"rendered":"https:\/\/prohoster.info\/blog\/unit-testy-v-subd-kak-my-delaem-eto-v-sportmastere-chast-vtoraya\/"},"modified":"2019-10-31T22:18:55","modified_gmt":"2019-10-31T19:18:55","slug":"unit-testy-v-subd-kak-my-delaem-eto-v-sportmastere-chast-vtoraya","status":"publish","type":"post","link":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/unit-testy-v-subd-kak-my-delaem-eto-v-sportmastere-chast-vtoraya","title":{"rendered":"Unit-tests in databases \u2014 hoe wij dit doen bij Sportmaster, deel twee","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i>Het eerste deel \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/sportmaster_lab\/blog\/464335\/\">hier<\/a><\/noindex>.<\/i><\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/sportmaster_lab\/blog\/465047\/\"><img decoding=\"async\" alt=\"Unit-tests in databases \u2014 hoe wij dit doen bij Sportmaster, deel twee\" src=\"\/wp-content\/uploads\/2019\/09\/b9fb8c934885abdf3ef928bfd75bdc2a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/a><\/noindex><\/p>\n<p>Stel je de situatie voor. Je hebt de taak om een nieuwe functionaliteit te ontwikkelen. Je hebt materiaal van je voorgangers. Als we aannemen dat je geen morele verplichtingen hebt, wat zou je dan doen?<\/p>\n<p>Meestal worden alle oude materialen vergeten en begint alles opnieuw. Niemand houdt ervan om in een andermans code te graven, en als er tijd is, waarom dan niet een eigen systeem cre\u00ebren? Dit is een typische aanpak en in veel opzichten correct. Maar in ons project hebben we het anders gedaan. We hebben de opbouw van een toekomstig automatisch testsysteem gebaseerd op de unit-tests van utPLSQL van onze voorgangers, en zijn vervolgens in verschillende parallelle richtingen gaan werken.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<ol>\n<li><b>Herstel van oude unit-tests.<\/b> Met herstel bedoelen we de aanpassing van tests aan de huidige staat van het loyaliteitsysteem en de aanpassing van tests aan de normen van utPLSQL. <\/li>\n<li><b>Oplossen van het probleem van het begrijpen van welke specifieke methoden en processen door onze autotests zijn gedekt. <\/b>Je moet deze informatie ofwel in je hoofd houden, of conclusies trekken op basis van de code van de autotests. Daarom hebben we besloten een catalogus op te stellen. We hebben elke autotest een unieke mnemonische code gegeven, een beschrijving opgesteld en de instellingen vastgelegd (bijvoorbeeld onder welke voorwaarden deze moet worden uitgevoerd, of wat er moet gebeuren als de test mislukt). In wezen hebben we metadata over de autotests ingevuld en deze metadata in de standaardtabellen van het utPLSQL-schema geplaatst.<\/li>\n<li><b>Bepaling van de uitbreidingsstrategie, oftewel de keuze van functionaliteit die onderworpen is aan autotests.<\/b> We hebben besloten om ons op drie dingen te concentreren: nieuwe aanvullingen op het systeem, incidenten uit de productie en sleutelprocessen van het systeem. Op deze manier ontwikkelen we ons gelijktijdig met de release, verbeteren we de kwaliteit ervan, breiden we het bereik van de regressietests uit en zorgen we voor de betrouwbaarheid van het systeem op kritieke punten. Het eerste knelpunt werd het proces van het toekennen van kortingen en bonussen aan de kassa.<\/li>\n<li><b>Natuurlijk hebben we ons beziggehouden met de ontwikkeling van nieuwe autotests. <\/b>Een van de eerste taken bij de release was het beoordelen van de prestaties van vooraf gedefinieerde selecties van het loyaliteitssysteem. In ons project is er een blok van vaste SQL-query's dat klanten selecteert op basis van bepaalde criteria. Bijvoorbeeld, een lijst verkrijgen van alle klanten wiens laatste aankoop in een specifieke stad was, of een lijst van klanten wiens gemiddelde aankoopbedrag boven een bepaalde waarde ligt. Door autotests te schrijven, hebben we de vooraf gedefinieerde selecties gecontroleerd, de referentieprestaties vastgelegd en bovendien hebben we last tests uitgevoerd.<\/li>\n<li><b>Werken met autotests moet gebruiksvriendelijk zijn<\/b>. De twee meest voorkomende acties zijn: het starten van autotests en het aanmaken van testgegevens. Zo zijn er in ons systeem twee ondersteunende modules ontstaan: de startmodule en de gegevensgeneratiemodule.\n<p>De startmodule is gepresenteerd als \u00e9\u00e9n universele procedure met \u00e9\u00e9n in tekstparameter. Als parameter kan de mnemonic code van de autotest, de naam van het pakket, de naam van de test, de configuratie van de autotest of een gereserveerd trefwoord worden doorgegeven. De procedure selecteert en start alle autotests die voldoen aan de voorwaarden.<\/p>\n<p>De gegevensgeneratiemodule is gepresenteerd in de vorm van een pakket, waarin voor elk object van het testingssysteem (tabel in de database) een speciale procedure is gemaakt die gegevens invoegt. In deze procedure zijn de standaardwaarden maximaal ingevuld, waardoor objecten letterlijk met een vingerclick kunnen worden gemaakt. En voor gebruiksgemak zijn er sjablonen voor de aangemaakte gegevens ontwikkeld. Bijvoorbeeld, het cre\u00ebren van een klant van een bepaalde leeftijd met een testtelefoon en een uitgevoerde aankoop.<\/li>\n<li><b>Autotests moeten worden gestart en functioneren binnen een acceptabele tijd voor uw systeem. <\/b>Daarom is er een dagelijkse nachtelijke start georganiseerd, waarvan de resultaten worden gerapporteerd en naar het gehele ontwikkelteam worden gestuurd via de bedrijfs-e-mail. Na het herstellen van oude autotests en het cre\u00ebren van nieuwe, bedroeg de totale werkduur 30 minuten. Deze prestaties bevielen iedereen, aangezien de start buiten werktijden plaatsvond.\n<p>Maar we moesten werken aan de optimalisatie van de snelheid. De update van het loyaliteitsysteem wordt 's nachts in productie uitgevoerd. In het kader van een van de releases moesten we 's nachts dringend wijzigingen aanbrengen. Een wachtperiode van een half uur voor de resultaten van de geautomatiseerde tests om drie uur 's nachts maakte de verantwoordelijke voor de release niet blij (hartelijke groeten aan Alexey Vasyukov!), en de volgende ochtend werden er veel warme woorden in de richting van ons systeem gezegd. Maar uiteindelijk werd een norm van 5 minuten voor de werking vastgesteld.<\/p>\n<p>Om de prestaties te versnellen, hebben we gebruikgemaakt van twee methoden: de geautomatiseerde tests worden uitgevoerd in drie parallelle stromen, wat erg handig is vanwege de architectuur van ons loyaliteitsysteem. En we hebben de oplossing verlaten waarbij de geautomatiseerde test geen testgegevens voor zichzelf cre\u00ebert, maar probeert iets geschikts in het systeem te vinden. Na de wijzigingen is de totale verwerkingstijd teruggebracht tot 3-4 minuten.<\/li>\n<li><b>Het project met geautomatiseerde tests moet op verschillende testomgevingen kunnen worden uitgerold.<\/b> Aan het begin van onze reis waren er pogingen om onze eigen batchbestanden te schrijven, maar het werd duidelijk dat het maken van een zelfgeschreven geautomatiseerde installatie een complete nachtmerrie was, en we hebben ons gericht op industri\u00eble oplossingen. Aangezien het project veel code bevat (voornamelijk slaan we de code van de geautomatiseerde tests op) en zeer weinig gegevens (de belangrijkste gegevens zijn metadata over de geautomatiseerde tests), bleek het heel eenvoudig om Liquibase in het project te implementeren.\n<p>Dit is een database-onafhankelijk bibliotheek met een open broncode voor het volgen, beheren en toepassen van wijzigingen in de databasestructuur. Beheerd via de opdrachtregel of frameworks zoals Apache Maven. Het principe van Liquibase is vrij eenvoudig. We hebben een op een bepaalde manier georganiseerde projectstructuur die bestaat uit wijzigingen of scripts die op de doelserver moeten worden toegepast, en besturingsbestanden die de volgorde en parameters defini\u00ebren waarmee deze wijzigingen moeten worden ge\u00efnstalleerd. <\/p>\n<p>Op het niveau van de database wordt een speciale tabel aangemaakt waarin Liquibase de log van aanpassingen opslaat. Elke wijziging heeft een berekende hash die telkens tussen het project en de status in de database wordt vergeleken. Dankzij Liquibase passen we eenvoudig wijzigingen in ons systeem toe op elke omgeving. Geautomatiseerde tests worden nu uitgevoerd op test- en productieomgevingen, evenals op containers (persoonlijke omgevingen van ontwikkelaars).<\/li>\n<\/ol>\n<p><img decoding=\"async\" alt=\"Unit-tests in databases \u2014 hoe wij dit doen bij Sportmaster, deel twee\" src=\"\/wp-content\/uploads\/2019\/09\/4306f6c33543d38f5d8b77f67e22e247.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLaten we het resultaat van ons unit-testingssysteem bespreken. <\/p>\n<ol>\n<li>Natuurlijk zijn we allereerst overtuigd dat we beter kwaliteitssoftware zijn gaan ontwikkelen. Geautomatiseerde tests worden dagelijks en na release uitgevoerd en vinden tientallen fouten. Bovendien zijn veel van deze fouten slechts indirect gerelateerd aan de functionaliteit die we daadwerkelijk wilden wijzigen. Er is grote twijfel of deze fouten door handmatige tests zijn gevonden. <\/li>\n<li>Het team heeft vertrouwen gekregen dat een specifieke functionaliteit correct werkt\u2026 Dit geldt in de eerste plaats voor onze kritische processen. Bijvoorbeeld, in de afgelopen zes maanden hebben we geen problemen gehad met de verdeling van kortingen en bonussen op de factuur, ondanks de dagelijkse wijzigingen, terwijl er in eerdere perioden met enige regelmaat fouten opdoken.<\/li>\n<li>We zijn erin geslaagd het aantal testiteraties te verminderen. Doordat geautomatiseerde tests worden geschreven voor nieuwe functionaliteiten, komt er hogere kwaliteit code terecht bij analisten en tevens testers, aangezien deze al gecontroleerd is.<\/li>\n<li>Een deel van de ontwikkelingen rond geautomatiseerd testen wordt door ontwikkelaars gebruikt. Bijvoorbeeld, testdata op containers wordt aangemaakt met behulp van een module voor objectgeneratie.<\/li>\n<li>Het is ook belangrijk dat we een acceptatie van het geautomatiseerde testsysteem hebben bij ontwikkelaars. Er is begrip dat dit belangrijk en nuttig is. Maar uit mijn ervaring kan ik zeggen dat dit lang niet altijd het geval is. Geautomatiseerde tests moeten worden geschreven, onderhouden en ontwikkeld, resultaten geanalyseerd, en vaak zijn deze tijdsinvesteringen het gewoon niet waard. Veel eenvoudiger is het om naar de productieomgeving te gaan en daar de problemen te onderzoeken. Bij ons staan ontwikkelaars in de rij en vragen ze om hun functionaliteit met geautomatiseerde tests te dekken.<\/li>\n<\/ol>\n<h2>Hier was eigenlijk een praktische sectie gepland met demonstratie van drie projecten op STM32 en STM8, speciaal voor dit artikel gemaakt met behulp van datasheets, met lampen, SPI, timers, PWM en interrupts:<\/h2>\n<p>\n<img decoding=\"async\" alt=\"Unit-tests in databases \u2014 hoe wij dit doen bij Sportmaster, deel twee\" src=\"\/wp-content\/uploads\/2019\/09\/a11596618e97c0afaa9f5f25b613575e.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nLaten we het hebben over de ontwikkelingsplannen van het project voor geautomatiseerd testen.<\/p>\n<p>Zeker, zolang het loyaliteitsprogramma van Sportmaster leeft en zich blijft ontwikkelen, kunnen we ook praktisch eindeloos de geautomatiseerde tests uitbreiden. Daarom is de belangrijkste ontwikkelingsrichting de uitbreiding van de dekking.<\/p>\n<p>Naarmate het aantal geautomatiseerde tests toeneemt, zal de totale uitvoeringstijd gestaag stijgen en zullen we weer moeten terugkomen op de vraag naar prestaties. Het lijkt erop dat de oplossing zal liggen in het verhogen van het aantal parallelle threads.<\/p>\n<p>Maar dit zijn voor de hand liggende ontwikkelingsroutes. Als we iets minder voor de hand liggend willen bespreken, laten we het volgende benadrukken:<\/p>\n<ol>\n<li>Momenteel wordt het beheer van geautomatiseerde tests uitgevoerd op het niveau van de database, dat wil zeggen dat kennis van PL\/SQL nodig is voor een succesvolle werking. Indien nodig kan het beheer van het systeem (zoals het starten van tests of het cre\u00ebren van metadata) uitbesteed worden aan een adminpaneel, bijvoorbeeld door Jenkins of iets dergelijks te gebruiken.<\/li>\n<li>Iedereen houdt van kwantitatieve en kwalitatieve indicatoren. Voor geautomatiseerd testen is een universele indicator de Code Coverage of de dekking van de code. Met deze indicator kunnen we bepalen welk percentage van de code van ons testende systeem wordt gedekt door geautomatiseerde tests. Sinds versie 12.2 biedt Oracle mogelijkheden voor de berekening van deze indicator en stelt het voor om het standaardpakket DBMS_PLSQL_CODE_COVERAGE te gebruiken.\n<p>Ons systeem voor geautomatiseerd testen is iets meer dan een jaar oud en misschien is dit het juiste moment voor een beoordeling van de dekking. In mijn vorige project (niet van Sportmaster) was dat ook het geval. Na een jaar werken aan de geautomatiseerde tests gaf het management de opdracht om te evalueren welk percentage van de code we dekken. Bij een dekking van meer dan 1% zou het management blij zijn. Wij, de ontwikkelaars, verwachtten een resultaat van rond de 10%. We hebben code coverage toegevoegd, gemeten en kregen 20%. Van blijdschap gingen we om een bonus vragen, maar hoe we dat deden en waar we daarna naartoe gingen, is een heel ander verhaal.<\/li>\n<li>Geautomatiseerde tests kunnen de aangeboden webservices controleren. Oracle maakt dit heel goed mogelijk, en we zullen niet langer een hele reeks problemen tegenkomen. <\/li>\n<li>En natuurlijk kan ons geautomatiseerde testsysteem ook op andere projecten worden toegepast. De door ons ontwikkelde oplossing is universeel en vereist alleen het gebruik van Oracle. Ik heb gehoord dat er op andere projecten van Sportmaster interesse is in geautomatiseerd testen en misschien gaan we daarheen.<\/li>\n<\/ol>\n<p><\/p>\n<h2>Conclusies<\/h2>\n<p>\nLaten we samenvatten. Op het project van het loyaliteitsysteem bij Sportmaster hebben we een geautomatiseerd testsysteem weten te implementeren. De basis ervan is de utPLSQL-oplossing van Steven Feuerstein. Rondom utPLSQL bevindt zich de code voor de autotests en ondersteunende zelfgeschreven modules: een startmodule, een module voor datageneratie en andere. De autotests worden dagelijks uitgevoerd en, wat het belangrijkste is, ze werken en leveren waarde. We zijn overtuigd dat we software van hogere kwaliteit zijn gaan leveren. Bovendien is de verkregen oplossing universeel en kan deze vrij worden toegepast op elk project waar geautomatiseerd testen op een Oracle-database nodig is.<\/p>\n<p><i>P.S. Dit artikel is niet erg specifiek geworden: er is veel tekst en vrijwel geen technische voorbeelden. Als het onderwerp interessant is, zijn we bereid om het voort te zetten en terug te komen met een vervolg waarin we vertellen wat er de afgelopen zes maanden is veranderd en voorbeelden van code geven.<\/p>\n<p>Laat een reactie achter als er aspecten zijn waarop we in de toekomst moeten focussen, of als er vragen zijn die verduidelijking vereisen.<\/i><\/p>\n<p class=\"for_users_only_msg\">Alleen geregistreerde gebruikers kunnen deelnemen aan de enqu\u00eate. <noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/auth\/login\/\">Log in<\/a><\/noindex>, alstublieft.<\/p>\n<h2 class=\"default-block__polling-title\">Gaan we hier verder mee?<\/h2>\n<ul class=\"content-list content-list_polling\">\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Ja, zeker<\/p>\n<\/li>\n<li class=\"content-list__item content-list__item_polling\">\n<p>                    Nee, bedankt<\/p>\n<\/li>\n<\/ul>\n<p>    12 gebruikers hebben gestemd. 4 gebruikers hebben zich onthouden.<br \/>\n<br \/>Bron: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/sportmaster_lab\/blog\/465047\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 \u0437\u0434\u0435\u0441\u044c. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044e. \u041f\u0435\u0440\u0435\u0434 \u0432\u0430\u043c\u0438 \u0441\u0442\u043e\u0438\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u043e\u0432\u043e\u0433\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0430. \u0423 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043e\u0442 \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u0435\u0434\u0448\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a\u043e\u0432. \u0415\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u0432\u044b \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043c\u043e\u0440\u0430\u043b\u044c\u043d\u044b\u0445 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442\u0435, \u0442\u043e \u043a\u0430\u043a \u0431\u044b \u0432\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043b\u0438? \u0427\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u0441\u0435 \u0441\u0442\u0430\u0440\u044b\u0435 \u043d\u0430\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043f\u043e\u0434\u0432\u0435\u0440\u0433\u0430\u044e\u0442\u0441\u044f \u0437\u0430\u0431\u0432\u0435\u043d\u0438\u044e \u0438 \u0432\u0441\u0451 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441\u043d\u0430\u0447\u0430\u043b\u0430. \u0412 \u0447\u0443\u0436\u043e\u043c \u043a\u043e\u0434\u0435 \u043a\u043e\u043f\u0430\u0442\u044c\u0441\u044f \u043d\u0438\u043a\u0442\u043e \u043d\u0435 \u043b\u044e\u0431\u0438\u0442, \u0430 \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":28269,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-37666","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 \u0437\u0434\u0435\u0441\u044c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/unit-testy-v-subd-kak-my-delaem-eto-v-sportmastere-chast-vtoraya\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"nl_NL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Unit-\u0442\u0435\u0441\u0442\u044b \u0432 \u0421\u0423\u0411\u0414 \u2014 \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0432 \u0421\u043f\u043e\u0440\u0442\u043c\u0430\u0441\u0442\u0435\u0440\u0435, \u0447\u0430\u0441\u0442\u044c \u0432\u0442\u043e\u0440\u0430\u044f | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 \u0437\u0434\u0435\u0441\u044c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/unit-testy-v-subd-kak-my-delaem-eto-v-sportmastere-chast-vtoraya\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T19:18:55+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T19:18:55+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Unit-tests in databases \u2014 hoe wij het doen bij Sportmaster, deel twee | ProHoster","description":"De eerste helft is hier.","canonical_url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/unit-testy-v-subd-kak-my-delaem-eto-v-sportmastere-chast-vtoraya","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"nl_NL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Unit-\u0442\u0435\u0441\u0442\u044b \u0432 \u0421\u0423\u0411\u0414 \u2014 \u043a\u0430\u043a \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0432 \u0421\u043f\u043e\u0440\u0442\u043c\u0430\u0441\u0442\u0435\u0440\u0435, \u0447\u0430\u0441\u0442\u044c \u0432\u0442\u043e\u0440\u0430\u044f | ProHoster","og:description":"\u041f\u0435\u0440\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 \u0437\u0434\u0435\u0441\u044c.","og:url":"https:\/\/prohoster.info\/nl\/blog\/administrirovanie\/unit-testy-v-subd-kak-my-delaem-eto-v-sportmastere-chast-vtoraya","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T19:18:55+00:00","article:modified_time":"2019-10-31T19:18:55+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"37666","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-23 18:48:19","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 01:23:06","updated":"2026-01-23 18:48:19","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/37666","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/comments?post=37666"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/posts\/37666\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media\/28269"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/media?parent=37666"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/categories?post=37666"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/nl\/wp-json\/wp\/v2\/tags?post=37666"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}