{"id":1635,"date":"2014-12-16T19:33:44","date_gmt":"2014-12-16T19:33:43","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1635"},"modified":"2023-04-28T10:32:10","modified_gmt":"2023-04-28T17:32:10","slug":"how-test-everything","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/pt\/how-test-everything\/","title":{"rendered":"Como testar tudo"},"content":{"rendered":"<div id=\"post\">\n<p><span style=\"color: #c0c0c0\"><em>[This post also appears\u00a0on <\/em><\/span><em><a href=\"https:\/\/dustin.github.com\/\"><span style=\"color: #c0c0c0\">Dustin&#8217;s github blog<\/span><\/a><\/em><span style=\"color: #c0c0c0\"><em>].<\/em><\/span><\/p>\n<p>I recently had a <a href=\"https:\/\/www.couchbase.com\/blog\/what-exactly-membase\/\">Membase<\/a> user point out a sequence of operations that led to an undesirable state. I\u2019ve got a lot of really good engine tests I\u2019ve written, but not <em>this<\/em> case:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\"><\/div>\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">add with timeout -&gt; wait for timeout -&gt; add with timeout<\/div>\n<\/div>\n<p>The bug is pretty straightforward \u2013 expiry is lazy and it turns out I\u2019m not checking for expiry in this case. It was pretty easy to<\/p>\n<p>write this test, but immediately made me think about what <em>other<\/em> cases weren\u2019t being run.<\/p>\n<p>Now, I know there are countless tools out there to aid in testing. I\u2019ve written another one. I probably spent an hour or so writing a framework to write and run all of the tests I needed. The difference between what I\u2019m describing here and, for example, <a href=\"https:\/\/www.haskell.org\/haskellwiki\/Introduction_to_QuickCheck\">quick check<\/a> is that I want something very simple to express actions that expect their environment to be in a particular state and will leave the environment in another state. Then I want to hit every possible arrangement of these actions to ensure they don\u2019t interfer with each other in unexpected ways.<\/p>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"floatright\" src=\"https:\/\/dustin.github.com\/images\/permutations.png\" alt=\"Permutations\" width=\"366\" height=\"284\" align=\"right\" \/><\/div>\n<p>This blows up very quickly \u2013 specifically the number of tests generated for a test sequence of <code>n<\/code> actions from <code>a<\/code> possible actions is approximately <code>a<sup>n<\/sup><\/code>.<\/p>\n<p>Consider three defined actions permuted into sequences of two. That blows out to nine possibilites as shown in the diagram on the right.<\/p>\n<p>The actions in the diagram are defined with memcached semantics on a single key, so <code>add<\/code> has a prerequisite that the item <em>must not<\/em> exist and <code>del<\/code> has a prerequisite that the item <em>must<\/em> exist.<\/p>\n<p>The generated test expects success at each white box, failure at each red box, and tracks the expected state mutations to build assertions.<\/p>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"floatleft\" src=\"https:\/\/dustin.github.com\/images\/breakdancer-exponentiality.png\" alt=\"BreakDancer Growth\" width=\"334\" height=\"142\" align=\"left\" \/><\/div>\n<p>My first test\u2026 um, test ran with <code>11<\/code> actions in sequences of <code>4<\/code> actions. I have more actions to go, but <code>4<\/code> is a pretty good length, so the chart at the left is going to demonstrate my growth rate.<\/p>\n<p>The awesome part is that it pointed out the original bug quite easily and another couple of bugs with limited effort.<\/p>\n<h4>How Do I Use This?<\/h4>\n<div><img loading=\"lazy\" decoding=\"async\" class=\"floatright\" src=\"https:\/\/dustin.github.com\/images\/action-life.png\" alt=\"action lifecycle\" width=\"284\" height=\"152\" align=\"right\" \/><\/div>\n<p>The API is so far pretty simple and composable. There are basically five classes (three are shown in the image on the right).<\/p>\n<h4>Condition<\/h4>\n<p>A <code>Condition<\/code> is a simple callable that is used for preconditions and postconditions. A given class doesn\u2019t care which one it\u2019s used for, and in many cases will be used for both.<\/p>\n<p>For example, consider my implementation of <code>DoesNotExist<\/code>:<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace\"><span style=\"color: #ff7700;font-weight: bold\">class<\/span> DoesNotExist<span style=\"color: black\">(<\/span>Condition<span style=\"color: black\">)<\/span>:<br \/>\n<span style=\"color: #ff7700;font-weight: bold\">def<\/span> <span style=\"color: #0000cd\">__call__<\/span><span style=\"color: black\">(<\/span><span style=\"color: #008000\">self<\/span><span style=\"color: #66cc66\">,<\/span> state<span style=\"color: black\">)<\/span>:<br \/>\n<span style=\"color: #ff7700;font-weight: bold\">return<\/span> TESTKEY <span style=\"color: #ff7700;font-weight: bold\">not<\/span> <span style=\"color: #ff7700;font-weight: bold\">in<\/span> state<\/div>\n<\/div>\n<h4>Effect<\/h4>\n<p>An <code>Effect<\/code> changes our view of the state (and depending on the driver, may actually cause something in the world to change with it). For example, the <code>StoreEffect<\/code> works as follows:<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace\"><span style=\"color: #ff7700;font-weight: bold\">class<\/span> StoreEffect<span style=\"color: black\">(<\/span>Effect<span style=\"color: black\">)<\/span>:<br \/>\n<span style=\"color: #ff7700;font-weight: bold\">def<\/span> <span style=\"color: #0000cd\">__call__<\/span><span style=\"color: black\">(<\/span><span style=\"color: #008000\">self<\/span><span style=\"color: #66cc66\">,<\/span> state<span style=\"color: black\">)<\/span>:<br \/>\nstate<span style=\"color: black\">[<\/span>TESTKEY<span style=\"color: black\">]<\/span> <span style=\"color: #66cc66\">=<\/span> <span style=\"color: #483d8b\">&#8216;0&#8217;<\/span><\/div>\n<\/div>\n<h4>Action<\/h4>\n<p>An <code>Action<\/code> brings an <code>Effect<\/code> and one or more <code>Condition<\/code> classes as pre and post conditions. For example, we\u2019ll look at two actions, an <code>Add<\/code> action and a <code>Set<\/code> action:<\/p>\n<div class=\"geshifilter\">\n<div class=\"text geshifilter-text\" style=\"font-family: monospace\">\n<p>class Set(Action):<br \/>\neffect = StoreEffect()<br \/>\npostconditions = [Exists()]<\/p>\n<p>class Add(Action):<br \/>\npreconditions = [DoesNotExist()]<br \/>\neffect = StoreEffect()<br \/>\npostconditions = [Exists()]<\/p>\n<\/div>\n<\/div>\n<p>The interesting part of this is that Set and Add have different semantics, but are expressed as different compositions of the same conditions and effects.<\/p>\n<h4>Driver<\/h4>\n<p>Driver is kind of a larger part (seven defined methods!). It does enough that I can do anything from generate a C test suite for memcached engines all the way to actually executing tests across a remote protocol.<\/p>\n<p>I won\u2019t describe the entire thing here since it\u2019s documented in the <a href=\"https:\/\/github.com\/dustin\/BreakDancer\">source<\/a>. I will however, close the loop by showing you some example code that it generated that demonstrated the error we failed to find in the first place:<\/p>\n<div class=\"geshifilter\">\n<div class=\"python geshifilter-python\" style=\"font-family: monospace\">static enum test_result test_add_add_delay_add<span style=\"color: black\">(<\/span>ENGINE_HANDLE *h<span style=\"color: #66cc66\">,<\/span><br \/>\nENGINE_HANDLE_V1 *h1<span style=\"color: black\">)<\/span> <span style=\"color: black\">{<\/span><br \/>\nadd<span style=\"color: black\">(<\/span>h<span style=\"color: #66cc66\">,<\/span> h1<span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span><br \/>\nassertHasNoError<span style=\"color: black\">(<\/span><span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span> \/\/ value <span style=\"color: #ff7700;font-weight: bold\">is<\/span> <span style=\"color: #483d8b\">&#8220;0&#8221;<\/span><br \/>\nadd<span style=\"color: black\">(<\/span>h<span style=\"color: #66cc66\">,<\/span> h1<span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span><br \/>\nassertHasError<span style=\"color: black\">(<\/span><span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span> \/\/ value <span style=\"color: #ff7700;font-weight: bold\">is<\/span> <span style=\"color: #483d8b\">&#8220;0&#8221;<\/span><br \/>\ndelay<span style=\"color: black\">(<\/span>expiry+<span style=\"color: #66cc66\">&lt;<\/span>span <span style=\"color: #ff7700;font-weight: bold\">class<\/span><span style=\"color: #66cc66\">=<\/span><span style=\"color: #483d8b\">&#8220;mi&#8221;<\/span><span style=\"color: #66cc66\">&gt;<\/span><span style=\"color: #ff4500\">1<\/span><span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span><br \/>\nassertHasNoError<span style=\"color: black\">(<\/span><span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span> \/\/ value <span style=\"color: #ff7700;font-weight: bold\">is<\/span> <span style=\"color: #ff7700;font-weight: bold\">not<\/span> defined<br \/>\nadd<span style=\"color: black\">(<\/span>h<span style=\"color: #66cc66\">,<\/span> h1<span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span><br \/>\nassertHasNoError<span style=\"color: black\">(<\/span><span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span> \/\/ value <span style=\"color: #ff7700;font-weight: bold\">is<\/span> <span style=\"color: #483d8b\">&#8220;0&#8221;<\/span><br \/>\ncheckValue<span style=\"color: black\">(<\/span>h<span style=\"color: #66cc66\">,<\/span> h1<span style=\"color: #66cc66\">,<\/span> <span style=\"color: #483d8b\">&#8220;0&#8221;<\/span><span style=\"color: black\">)<\/span><span style=\"color: #66cc66\">;<\/span><br \/>\n<span style=\"color: #ff7700;font-weight: bold\">return<\/span> SUCCESS<span style=\"color: #66cc66\">;<\/span><br \/>\n<span style=\"color: black\">}<\/span><br \/>\n<span style=\"color: #66cc66\">&lt;<\/span>\/span<span style=\"color: #66cc66\">&gt;<\/span><\/div>\n<\/div>\n<p>That demonstrates how much information you know at each step of the way. From there, we can do all kinds of stuff with our stubs (delay above is implemented with the memcached testapp \u201ctime travel\u201d feature, for example).<\/p>\n<p>From here, it\u2019s less exciting. We provide constraints, it writes tests, and makes sure that there\u2019s another area that it\u2019s impossible for users to encounter something we haven\u2019t seen before.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>[This post also appears\u00a0on Dustin&#8217;s github blog]. I recently had a Membase user point out a sequence of operations that led to an undesirable state. I\u2019ve got a lot of really good engine tests I\u2019ve written, but not this case: [&hellip;]<\/p>\n","protected":false},"author":34,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[8992],"class_list":["post-1635","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How to Test Everything - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/pt\/how-test-everything\/\" \/>\n<meta property=\"og:locale\" content=\"pt_BR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Test Everything\" \/>\n<meta property=\"og:description\" content=\"[This post also appears\u00a0on Dustin&#8217;s github blog]. I recently had a Membase user point out a sequence of operations that led to an undesirable state. I\u2019ve got a lot of really good engine tests I\u2019ve written, but not this case: [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/pt\/how-test-everything\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T19:33:43+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-04-28T17:32:10+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/dustin.github.com\/images\/permutations.png\" \/>\n<meta name=\"author\" content=\"Dustin Sallings, Chief Architect, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dustin Sallings, Chief Architect, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutos\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/\"},\"author\":{\"name\":\"Dustin Sallings, Chief Architect, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/e68b6f4489072ef4a84f60bc437c07d0\"},\"headline\":\"How to Test Everything\",\"datePublished\":\"2014-12-16T19:33:43+00:00\",\"dateModified\":\"2023-04-28T17:32:10+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/\"},\"wordCount\":758,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/\",\"name\":\"How to Test Everything - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T19:33:43+00:00\",\"dateModified\":\"2023-04-28T17:32:10+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#breadcrumb\"},\"inLanguage\":\"pt-BR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/how-test-everything\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Test Everything\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"pt-BR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/e68b6f4489072ef4a84f60bc437c07d0\",\"name\":\"Dustin Sallings, Chief Architect, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"pt-BR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=gc5bddc8d7dab8b5c9121282556b0dbff\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g\",\"caption\":\"Dustin Sallings, Chief Architect, Couchbase\"},\"description\":\"Dustin Sallings is a Chief Architect at Couchbase. Dustin is an Author of spymemcached and core contributor to Couchbase and Memcached projects.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/pt\\\/author\\\/dustin-sallings\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to Test Everything - The Couchbase Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/pt\/how-test-everything\/","og_locale":"pt_BR","og_type":"article","og_title":"How to Test Everything","og_description":"[This post also appears\u00a0on Dustin&#8217;s github blog]. I recently had a Membase user point out a sequence of operations that led to an undesirable state. I\u2019ve got a lot of really good engine tests I\u2019ve written, but not this case: [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/pt\/how-test-everything\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T19:33:43+00:00","article_modified_time":"2023-04-28T17:32:10+00:00","og_image":[{"url":"https:\/\/dustin.github.com\/images\/permutations.png","type":"","width":"","height":""}],"author":"Dustin Sallings, Chief Architect, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Dustin Sallings, Chief Architect, Couchbase","Est. reading time":"4 minutos"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/"},"author":{"name":"Dustin Sallings, Chief Architect, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e68b6f4489072ef4a84f60bc437c07d0"},"headline":"How to Test Everything","datePublished":"2014-12-16T19:33:43+00:00","dateModified":"2023-04-28T17:32:10+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/"},"wordCount":758,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Uncategorized"],"inLanguage":"pt-BR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/how-test-everything\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/","url":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/","name":"How to Test Everything - The Couchbase Blog","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T19:33:43+00:00","dateModified":"2023-04-28T17:32:10+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/#breadcrumb"},"inLanguage":"pt-BR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/how-test-everything\/"]}]},{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/how-test-everything\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"How to Test Everything"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"Blog do Couchbase","description":"Couchbase, o banco de dados NoSQL","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"pt-BR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"Blog do Couchbase","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/e68b6f4489072ef4a84f60bc437c07d0","name":"Dustin Sallings, arquiteto-chefe da Couchbase","image":{"@type":"ImageObject","inLanguage":"pt-BR","@id":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=gc5bddc8d7dab8b5c9121282556b0dbff","url":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g","caption":"Dustin Sallings, Chief Architect, Couchbase"},"description":"Dustin Sallings is a Chief Architect at Couchbase. Dustin is an Author of spymemcached and core contributor to Couchbase and Memcached projects.","url":"https:\/\/www.couchbase.com\/blog\/pt\/author\/dustin-sallings\/"}]}},"acf":[],"authors":[{"term_id":8992,"user_id":34,"is_guest":0,"slug":"dustin-sallings","display_name":"Dustin Sallings, Chief Architect, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/61704e29c6b19851f45c023b2f456b2a0c80ba03ae65e957e39080a0d15065e5?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/1635","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/comments?post=1635"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/posts\/1635\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/media?parent=1635"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/categories?post=1635"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/tags?post=1635"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/pt\/wp-json\/wp\/v2\/ppma_author?post=1635"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}