{"id":7816,"date":"2019-07-24T15:01:02","date_gmt":"2019-07-24T13:01:02","guid":{"rendered":"https:\/\/sii.pl\/blog\/?p=7816"},"modified":"2025-05-29T13:12:40","modified_gmt":"2025-05-29T11:12:40","slug":"automatyzacja-testow-systemow-wbudowanych-z-wykorzystaniem-robot-frameworka-czesc-2","status":"publish","type":"post","link":"https:\/\/sii.pl\/blog\/automatyzacja-testow-systemow-wbudowanych-z-wykorzystaniem-robot-frameworka-czesc-2\/","title":{"rendered":"Automatyzacja test\u00f3w System\u00f3w Wbudowanych z wykorzystaniem Robot Frameworka &#8211; cz\u0119\u015b\u0107 2"},"content":{"rendered":"\n<p>W tej cz\u0119\u015bci zajmiemy si\u0119 praktyczn\u0105 stron\u0105 testowania, poka\u017cemy w jaki spos\u00f3b u\u017cywa\u0107 s\u0142\u00f3w kluczowych oraz jak pisa\u0107 testy.\u00a0Cz\u0119\u015b\u0107 pierwsz\u0105 przeczytacie <a href=\"https:\/\/sii.pl\/blog\/automatyzacja-testow-systemow-wbudowanych-z-wykorzystaniem-robot-frameworka-czesc-1\">tutaj<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Biblioteki testowe<\/h2>\n\n\n\n<p>Du\u017cym atutem Robot&nbsp;Frameworka&nbsp;jest \u0142atwe do\u0142\u0105czanie i wykorzystywanie bibliotek testowych. Bardziej zaawansowane operacje s\u0105 prostsze w implementacji w j\u0119zyku skryptowym takim jak&nbsp;Python. Na poni\u017cszym przyk\u0142adzie przedstawimy dwie wersje&nbsp;s\u0142owa kluczowego,&nbsp;zaimplementowanego w Robot&nbsp;Frameworku&nbsp;i w Pythonie. Przy pracy z Robotem mo\u017cemy wykorzysta\u0107 wbudowane biblioteki albo zaimplementowa\u0107 w\u0142asne.<\/p>\n\n\n\n<p>Repozytorium kodu mo\u017cecie pobra\u0107 tutaj > <a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/robot-framework-tests.zip\" class=\"ek-link\">robot-framework-tests<\/a>.<\/p>\n\n\n\n<p>Importowanie biblioteki wygl\u0105da nast\u0119puj\u0105co:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n*** Settings ***\n \nLibrary DHT11TestLibrary.py\n<\/pre><\/div>\n\n\n<p>Je\u017celi nazwa pliku biblioteki oraz nazwa klasy b\u0119dzie taka sama, to Robot Framework sam utworzy instancj\u0119 biblioteki. W naszym przypadku dla klasy\u00a0DHT11TestLibrary\u00a0tworzymy o takiej samej nazwie z rozszerzeniem .py . Domy\u015blnie Robot\u00a0Framework\u00a0utworzy jedn\u0105 instancj\u0119 na jedn\u0105 egzekucj\u0119 test\u00f3w. Je\u017celi zale\u017cy nam na zmianie tego zachowania mo\u017cemy u\u017cy\u0107 nast\u0119puj\u0105cej deklaracji w bibliotece:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nclass DHT11TestLibrary:\nROBOT_LIBRARY_SCOPE = 'TEST CASE'\n<\/pre><\/div>\n\n\n<p>Spowoduje \u00a0to, \u017ce biblioteka b\u0119dzie inicjalizowana ponownie dla ka\u017cdego testu z osobna. Z dost\u0119pnych opcji mo\u017cemy ustawi\u0107 inicjalizacj\u0119 biblioteki:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>osobno dla ka\u017cdej grupy test\u00f3w ( \u2018TEST SUITE\u2019)<\/li><li>dla ca\u0142ej egzekucji (\u2018GLOBAL\u2019)<\/li><\/ul>\n\n\n\n<p>Robot Framework\u00a0parsuje\u00a0metody w klasie biblioteki testowej tak, aby mo\u017cna wywo\u0142ywa\u0107 je w skrypcie Robota. Dla poni\u017cszej metody testowej:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef temperature_string_shall_be_in_correct_format(self):\ntemperature_str = self.dht11_inst.temperature_to_str()\nif re.match(r'^&#x5B;1-9]+\\d* C$', temperature_str):\nreturn True\nraise AssertionError('Temperature string in invalid format: {}'.format(temperature_str))\n<\/pre><\/div>\n\n\n<p>Mo\u017cemy u\u017cy\u0107 nast\u0119puj\u0105cych metod wywo\u0142ania w Robocie (podkre\u015blniki\u00a0mo\u017cna zast\u0105pi\u0107 spacjami, wielko\u015b\u0107 liter nie ma znaczenia). Nie ma r\u00f3wnie\u017c potrzeby okre\u015blenia nazwy biblioteki, z kt\u00f3rej wywo\u0142ujemy\u00a0s\u0142owa kluczowe, co w ostateczno\u015bci skutkuje takim formatem wywo\u0142ania metody:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nTemperature_string_shall_be_in_correct_format\nTemperature string shall be in correct format\n<\/pre><\/div>\n\n\n<p>Mo\u017cemy u\u017cy\u0107 Robot API,\u00a0aby wywo\u0142a\u0107\u00a0s\u0142owo kluczowe\u00a0pod inn\u0105 nazw\u0105 ni\u017c zadeklarowana w bibliotece. Dzi\u0119ki API mo\u017cemy doda\u0107 wszelakie informacje, takie jak\u00a0tagi, dokumentacj\u0119 czy typ przekazywanego argumentu (domy\u015blnie przekazywane s\u0105 bez zmian).<br>Na przyk\u0142adzie naszego testu\u00a0keyword\u00a0napisany w Robot\u00a0Frameworku\u00a0oraz w\u00a0Pythonie\u00a0(o podobnym dzia\u0142aniu):<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Robot Framework<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\nTemperature shall be in range\n&#x5B;Arguments] ${min} ${max}\nLog \\nVerify that read temperature is between ${min} and ${max} console=True\n${data}= dht11 shall return sensor data\nLog Temperature: ${data.temperature} console=True\nRun_Keyword_If ${min} &gt; ${data.temperature} &gt; ${max} FAIL  msg=&#039;DHT11 returned temperature outside range&#039;\n<\/pre><\/div>\n\n\n<h3 class=\"wp-block-heading\">Python<\/h3>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\ndef humidity_shall_be_in_range(self, min_hum, max_hum):\n&quot;&quot;&quot;\nVerify that humidity from sensor is in given range.\nArgs:\nmin_hum(int): minimum for humidity threshold (exluding)\nmax_hum(int): maximum for humidity threshold (exluding)\n \nRaises:\nTimeoutError: when timeout pass before correct data is returned\nAssertionError: when read humidity is not between min_hum and max_hum\n \nReturns:\nTrue: when read humidity is between min_hum and max_hum\n&quot;&quot;&quot;\n \nlogger.info(&#039;Verify that humidity is between {} and {}&#039;.format(min_hum, max_hum), True, True)\nsenses = self.dht11_inst.get_sensor_data()\nlogger.info(&#039;Humidity: {}&#039;.format(senses.humidity), True, True)\nif (min_hum &gt; senses.humidity) or (senses.humidity &gt; max_hum):\nraise AssertionError(&#039;DHT11 returned humidity outside range&#039;)\nreturn True\n<\/pre><\/div>\n\n\n<h2 class=\"wp-block-heading\">Testowanie sensora DHT11 i struktura pliku .robot<\/h2>\n\n\n\n<p>Do pracy z sensorem DHT11 przygotowali\u015bmy modu\u0142 do obs\u0142ugi czujnika&nbsp;<em>DHT11.py<\/em>&nbsp;oraz bibliotek\u0119 testow\u0105&nbsp;<em>DHT11TestLibrary.py<\/em><br>Na podstawie postawionych wymaga\u0144 stworzyli\u015bmy plik Robot z testami, znajduj\u0105cy si\u0119 w pliku&nbsp;<em>DHT11Tests.robot<\/em><\/p>\n\n\n\n<p>Teraz dobrze by\u0142oby przyjrze\u0107 si\u0119 strukturze pliku, u\u017cywanego przez Robot Frameworka.<\/p>\n\n\n\n<p>W pliku znajduj\u0105 si\u0119 4 sekcje, zaczynaj\u0105ce si\u0119 s\u0142owem kluczowym, otoczonym gwiazdkami:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Settings \u2013 tutaj umieszczana jest dokumentacja testu, importowane s\u0105 biblioteki oraz \u2018zasoby\u2019, czyli wbudowane biblioteki robot frameworka,<\/li><li>Variables \u2013 w tym miejscu mo\u017cemy sobie zdefiniowa\u0107 zmienne, kt\u00f3re b\u0119dziemy stosowali testach,<\/li><li>Test Cases \u2013 chyba nikomu nie trzeba t\u0142umaczy\u0107\u00a0 ?<\/li><li>Keywords \u2013 miejsce na tworzenie s\u0142\u00f3w kluczowych w Robocie z pomoc\u0105 sk\u0142adni Robota<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Uruchamianie test\u00f3w<\/h2>\n\n\n\n<p>Aby uruchomi\u0107 testy przeznaczone dla Robot Frameworka, wystarczy wpisa\u0107 w wierszu polecenia\/linii komend nast\u0119puj\u0105ce zakl\u0119cie:<\/p>\n\n\n\n<p><em>robot &lt;lokalizacja_pliku_z_testami&gt;<\/em><\/p>\n\n\n\n<p>Mo\u017cliwe jest r\u00f3wnie\u017c podanie samego katalogu, gdzie znajduj\u0105 si\u0119 pliki .robot, w takim wypadku, zostan\u0105 uruchomione wszystkie testy, jakie znajduj\u0105 si\u0119 w plikach tego katalogu.<\/p>\n\n\n\n<p>Po uruchomieniu test\u00f3w na\u00a0Raspberry\u00a0Pi Robot wygenerowa\u0142 logi z test\u00f3w. Z konsoli mo\u017cemy odczyta\u0107 og\u00f3lny przebieg test\u00f3w (r\u00f3wnie\u017c w trakcie ich wykonywania):<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-z-testow-e1563964044215.png\"><img decoding=\"async\" width=\"566\" height=\"300\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-z-testow-e1563964044215.png\" alt=\"\" class=\"wp-image-17970\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-z-testow-e1563964044215.png 566w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-z-testow-e1563964044215-300x159.png 300w\" sizes=\"(max-width: 566px) 100vw, 566px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>Bardziej szczeg\u00f3\u0142owe informacje dost\u0119pne s\u0105 po zako\u0144czeniu test\u00f3w, gdy Robot wygeneruje sam logi oraz raport z egzekucji.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-1.png\"><img decoding=\"async\" width=\"637\" height=\"348\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-1.png\" alt=\"\" class=\"wp-image-17966\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-1.png 637w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-1-300x164.png 300w\" sizes=\"(max-width: 637px) 100vw, 637px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>Jak wida\u0107, ka\u017cdy z tych test\u00f3w ma mo\u017cliwo\u015b\u0107 \u201erozwini\u0119cia\u201d, dzi\u0119ki czemu mo\u017cemy zobaczy\u0107 dok\u0142adniej, jakie instrukcje zosta\u0142y wykonane w te\u015bcie.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-rozwiniete.png\"><img decoding=\"async\" width=\"674\" height=\"215\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-rozwiniete.png\" alt=\"\" class=\"wp-image-17968\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-rozwiniete.png 674w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/logi-html-rozwiniete-300x96.png 300w\" sizes=\"(max-width: 674px) 100vw, 674px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>Robot Framework udost\u0119pnia r\u00f3wnie\u017c szereg narz\u0119dzi do formatowania i\u00a0parsowania\u00a0raport\u00f3w (np.\u00a0testdoc,\u00a0rebot). Za ich pomoc\u0105 mo\u017cemy zmieni\u0107 wygl\u0105d log\u00f3w albo nadpisa\u0107 pewne dane. Dzi\u0119ki temu z jednej egzekucji test\u00f3w mo\u017cemy wygenerowa\u0107 raporty dla r\u00f3\u017cnych interesariuszy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Testowanie wy\u015bwietlacza LCD i Date Driven Tests<\/h2>\n\n\n\n<p>Do weryfikacji funkcji wy\u015bwietlacza nie wystarczy nam tylko oprogramowanie (chyba, \u017ce pos\u0142u\u017cyliby\u015bmy si\u0119 rozpoznawaniem tekstu), lecz potrzebna b\u0119dzie te\u017c osoba, kt\u00f3ra zweryfikuje, czy na wy\u015bwietlaczu pokazywane s\u0105 po\u017c\u0105dane rezultaty. Dlatego wygodnym sposobem jest jak najwi\u0119ksze&nbsp;zautomatyzowanie&nbsp;tego procesu oraz dostarczenie u\u017cytkownikowi w miar\u0119 wygodnego sposobu do weryfikacji zjawisk. W naszym przypadku b\u0119dzie to proste pytanie z wymagaj\u0105ce od u\u017cytkownika odpowiedzi y\/n&nbsp;.<\/p>\n\n\n\n<p>Plik z testami LCD znajduje si\u0119 w pliku LCDDataDriverTests.robot lub w LCDKeywordDrivenTests.robot.<\/p>\n\n\n\n<p>W pierwszym pliku jest zaprezentowany spos\u00f3b Data Driven, kt\u00f3ry by\u0142 opisywany w poprzedniej cz\u0119\u015b\u0107i artyku\u0142u. Tworzenie takich test\u00f3w polega na:<br>\u2013 Stworzeniu\/u\u017cyciu s\u0142owa kluczowego, kt\u00f3ry b\u0119dzie u\u017cywany przez ka\u017cdy przypadek testowy. W naszym przypadku jest to s\u0142owo kluczowe \u2018<em>Verify if text is displayed\u2019.<\/em><br>\u2013 Ustawienia keyworda jako szablonu, do kt\u00f3rego b\u0119d\u0105 podawane r\u00f3\u017cne dane, robimy to za pomoc\u0105 opcji&nbsp;<em>Test Template<\/em><br>\u2013 Napisania test\u00f3w, w tym przypadku polega to na podaniu nazwy testu i odpowiednich argument\u00f3w<\/p>\n\n\n\n<p>Gdy uruchomimy testy wy\u015bwietlacza, zauwa\u017cymy \u017ce egzekucja zostanie zatrzymana, a u\u017cytkownik poproszony o wprowadzenie odpowiedzi na podstawie w\u0142asnych obserwacji.<\/p>\n\n\n\n<p>Oto, jak wygl\u0105da w praktyce praca z takimi testami:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/1-pytanie-e1563964301172-1.png\"><img decoding=\"async\" width=\"840\" height=\"141\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/1-pytanie-e1563964301172-1.png\" alt=\"\" class=\"wp-image-17962\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/1-pytanie-e1563964301172-1.png 840w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/1-pytanie-e1563964301172-1-300x50.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/1-pytanie-e1563964301172-1-768x129.png 768w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><\/a><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-full\"><a href=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/2-pytanie-e1563964346723-1.png\"><img decoding=\"async\" width=\"840\" height=\"129\" src=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/2-pytanie-e1563964346723-1.png\" alt=\"\" class=\"wp-image-17964\" srcset=\"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/2-pytanie-e1563964346723-1.png 840w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/2-pytanie-e1563964346723-1-300x46.png 300w, https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/2-pytanie-e1563964346723-1-768x118.png 768w\" sizes=\"(max-width: 840px) 100vw, 840px\" \/><\/a><\/figure><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Podsumowanie<\/h2>\n\n\n\n<p>Powy\u017cej zaprezentowali\u015bmy zaledwie namiastk\u0119 mo\u017cliwo\u015bci, na jakie pozwala nam Robot Framework, w tym przypadku dla zastosowa\u0144 embedded, w kt\u00f3rych nie jest cz\u0119sto u\u017cywany. Pokazali\u015bmy r\u00f3wnie\u017c, jak mo\u017cemy u\u017cywa\u0107 bibliotek do zastosowa\u0144 testowych i jak pisa\u0107 testy w Robot Frameworku na dwa sposoby.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">U\u017cyteczne linki i bibliografia<\/h4>\n\n\n\n<p>Zauwa\u017cyli\u015bmy, \u017ce Robot Framework ma bardzo dobrze napisan\u0105 dokumentacj\u0119 wraz z przyk\u0142adami u\u017cycia, dlatego do\u0142\u0105czamy tutaj jeszcze kilka link\u00f3w dla os\u00f3b bardziej zainteresowanych.<\/p>\n\n\n\n<p><a href=\"https:\/\/robotframework.org\/\" rel=\"nofollow\" >https:\/\/robotframework.org\/<\/a><br><a href=\"https:\/\/robotframework.org\/robotframework\/latest\/RobotFrameworkUserGuide.html\" rel=\"nofollow\" >https:\/\/robotframework.org\/robotframework\/latest\/RobotFrameworkUserGuide.html<\/a><br><a href=\"https:\/\/github.com\/robotframework\/HowToWriteGoodTestCases\/blob\/master\/HowToWriteGoodTestCases.rst\" rel=\"nofollow\" >https:\/\/github.com\/robotframework\/HowToWriteGoodTestCases\/blob\/master\/HowToWriteGoodTestCases.rst<\/a><br><a href=\"https:\/\/github.com\/robotframework\/robotframework\/blob\/master\/doc\/userguide\/src\/ExtendingRobotFramework\/CreatingTestLibraries.rst\" rel=\"nofollow\" >https:\/\/github.com\/robotframework\/robotframework\/blob\/master\/doc\/userguide\/src\/ExtendingRobotFramework\/CreatingTestLibraries.rst<\/a><\/p>\n\n\n\n<p>Seria artyku\u0142\u00f3w powsta\u0142a dzi\u0119ki pracy dw\u00f3ch tester\u00f3w \u2013 Bart\u0142omieja Hirsza oraz Paw\u0142a Wilka, Tester\u00f3w z Centrum Kompetencyjnego Embedded w Sii.<\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;7816&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;8&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;4.2&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;11&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;4.2\\\/5 ( votes: 8)&quot;,&quot;size&quot;:&quot;18&quot;,&quot;title&quot;:&quot;Automatyzacja test\u00f3w System\u00f3w Wbudowanych z wykorzystaniem Robot Frameworka - cz\u0119\u015b\u0107 2&quot;,&quot;width&quot;:&quot;116.3&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} ( {votes}: {count})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 116.3px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 11px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 18px; height: 18px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 14.4px;\">\n            4.2\/5 ( votes: 8)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>W tej cz\u0119\u015bci zajmiemy si\u0119 praktyczn\u0105 stron\u0105 testowania, poka\u017cemy w jaki spos\u00f3b u\u017cywa\u0107 s\u0142\u00f3w kluczowych oraz jak pisa\u0107 testy.\u00a0Cz\u0119\u015b\u0107 pierwsz\u0105 &hellip; <a class=\"continued-btn\" href=\"https:\/\/sii.pl\/blog\/automatyzacja-testow-systemow-wbudowanych-z-wykorzystaniem-robot-frameworka-czesc-2\/\">Continued<\/a><\/p>\n","protected":false},"author":211,"featured_media":7837,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_editorskit_title_hidden":false,"_editorskit_reading_time":0,"_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}","inline_featured_image":false,"footnotes":""},"categories":[1314],"tags":[563,807,584,809,679,146],"class_list":["post-7816","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-na-twardo","tag-embedded","tag-testowanie","tag-python","tag-raspberrypi","tag-robot-framework","tag-testing"],"acf":[],"aioseo_notices":[],"republish_history":[],"featured_media_url":"https:\/\/sii.pl\/blog\/wp-content\/uploads\/2019\/07\/capacitor-chip-circuit-163100.jpg","category_names":["Development na twardo"],"_links":{"self":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/7816"}],"collection":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/users\/211"}],"replies":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/comments?post=7816"}],"version-history":[{"count":1,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/7816\/revisions"}],"predecessor-version":[{"id":17972,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/posts\/7816\/revisions\/17972"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media\/7837"}],"wp:attachment":[{"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/media?parent=7816"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/categories?post=7816"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sii.pl\/blog\/wp-json\/wp\/v2\/tags?post=7816"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}