{"id":847,"date":"2014-09-03T14:23:11","date_gmt":"2014-09-03T18:23:11","guid":{"rendered":"https:\/\/blog.splice.com\/?p=847"},"modified":"2024-01-18T14:42:43","modified_gmt":"2024-01-18T19:42:43","slug":"lesser-known-features-go-test","status":"publish","type":"post","link":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/","title":{"rendered":"Lesser-Known Features of Go Test"},"content":{"rendered":"<p><strong>Lesser-known features of go test<\/strong><\/p>\n<p>Most gophers know and love <code>go test<\/code>, the testing tool that comes with Go&#8217;s official <code>gc<\/code> toolchain. It is quite possibly the simplest thing that works, and that is beautiful.<\/p>\n<p>They know that running <code>go test<\/code> runs the tests for the package in the current directory, looking for <code>*_test.go<\/code> files, and within those files, looking for functions following the <code>TestXxx(*testing.T) {}<\/code> naming and signature (that is, a function that receives a <code>*testing.T<\/code> as sole argument, and that is named <code>TestXxx<\/code> where <code>Xxx<\/code> is any name that doesn&#8217;t start with a lowercase). This testing code does not pollute standard builds as it is compiled only when <code>go test<\/code> is used.<\/p>\n<p>But there is much more hiding in there.<\/p>\n<p><strong>The black box test package<\/strong><\/p>\n<p>Usually, in Go, tests are in the same package as the code it tests (the <em>system under test<\/em>), giving access to internal implementation details. For black-box testing, <code>go test<\/code> supports using a package name with the &#8220;_test&#8221; suffix that gets compiled into its own separate package.<\/p>\n<p>For example:<\/p>\n<pre><code>\n\/\/ in example.go\npackage example\n\nvar start int\n\nfunc Add(n int) int {\n  start += n\n  return start\n}\n\n\/\/ in example_test.go\npackage example_test\n\nimport (\n  \"testing\"\n\n  . \"bitbucket.org\/splice\/blog\/example\"\n)\n\nfunc TestAdd(t *testing.T) {\n  got := Add(1)\n  if got != 1 {\n    t.Errorf(\"got %d, want 1\", got)\n  }\n}\n<\/code><\/pre>\n<p>You can see the infamous <a href=\"http:\/\/golang.org\/ref\/spec#Import_declarations\">dot-import<\/a> in action. This is the one use case where it makes sense, when black-box testing a package and importing its exported symbols in the current package&#8217;s scope. It <a href=\"https:\/\/code.google.com\/p\/go-wiki\/wiki\/CodeReviewComments#Import_Dot\">should almost always be avoided in other circumstances<\/a>.<\/p>\n<p>As explained in the linked style guide section on dot imports, the black-box test pattern can also be used to break import cycles (when the package under test &#8220;a&#8221; is imported by package &#8220;b&#8221;, and the test of &#8220;a&#8221; needs to import &#8220;b&#8221; &#8211; the test can be moved to the &#8220;a_test&#8221; package and can then import both &#8220;a&#8221; and &#8220;b&#8221; without cycle).<\/p>\n<p><strong>Skipping tests<\/strong><\/p>\n<p>Some tests may require a particular context to be executed. For example, some tests may require the presence of an external command, a specific file, or an environment variable to be set. Instead of letting those tests fail when that condition is not met, it is easy to simply skip those tests:<\/p>\n<pre><code>\nfunc TestSomeProtectedResource(t *testing.T) {\n  if os.Getenv(\"SOME_ACCESS_TOKEN\") == \"\" {\n    t.Skip(\"skipping test; $SOME_ACCESS_TOKEN not set\")\n  }\n  \/\/ ... the actual test\n}\n<\/code><\/pre>\n<p>If <code>go test -v<\/code> is called (notice the verbose flag), the output will mention the skipped test:<\/p>\n<pre><code>\n=== RUN TestSomeProtectedResource\n--- SKIP: TestSomeProtectedResource (0.00 seconds)\n    example_test.go:17: skipping test; $SOME_ACCESS_TOKEN not set\n<\/code><\/pre>\n<p>Often used with the skip feature is the <code>-short<\/code> command-line flag, that is made available to the code via <code>testing.Short()<\/code> that simply returns true if the flag is set (just like the <code>-v<\/code> flag is made available via <code>testing.Verbose()<\/code> so you can print additional debugging information when this condition is met).<\/p>\n<p>When a test is known to take a while to run and you&#8217;re in a hurry, you can call <code>go test -short<\/code> and, provided the package developer was kind enough to implement this, long-running tests will be skipped. That&#8217;s how Go&#8217;s tests are run when installing from source, and here is an example of a long-running test skipped in short mode, from the stdlib:<\/p>\n<pre><code>\nfunc TestCountMallocs(t *testing.T) {\n  if testing.Short() {\n    t.Skip(\"skipping malloc count in short mode\")\n  }\n  \/\/ rest of test...\n}\n<\/code><\/pre>\n<p>Skipping is just one option, the <code>-short<\/code> flag is just an indication and the developer can choose to run the test but avoid some slower assertions instead.<\/p>\n<p>There&#8217;s also the <code>-timeout<\/code> flag that can be used to force a test to panic if it doesn&#8217;t finish within this duration. For example, running <code>go test -timeout 1s<\/code> with this test:<\/p>\n<pre><code>\nfunc TestWillTimeout(t *testing.T) {\n  time.Sleep(2 * time.Second)\n  \/\/ pass if timeout &gt; 2s\n}\n<\/code><\/pre>\n<p>produces this output (truncated):<\/p>\n<pre><code>\n=== RUN TestWillTimeout\npanic: test timed out after 1s\n<\/code><\/pre>\n<p>And running specific tests instead of the whole test suite is easy with <code>go test -run TestNameRegexp<\/code>.<\/p>\n<p><strong>Parallelizing tests<\/strong><\/p>\n<p>By default, tests for a specific package are executed sequentially, but it is possible to mark some tests as safe for parallel execution using <code>t.Parallel()<\/code> within the test function (assuming the argument is named <code>t<\/code>, as is the convention). Only those tests marked as parallel will be executed in parallel, so having just one is kind of useless. It should be called first in the test&#8217;s function body (after any skipping conditions) as it will reset the test&#8217;s duration:<\/p>\n<pre><code>\nfunc TestParallel(t *testing.T) {\n  t.Parallel()\n  \/\/ actual test...\n}\n<\/code><\/pre>\n<p>The number of tests run simultaneously in parallel is the current value of <code>GOMAXPROCS<\/code> by default. It can be set to a specific value via the <code>-parallel n<\/code> flag (<code>go test -parallel 4<\/code>).<\/p>\n<p>Another source of parallelization, albeit not at the granular test function level, but at the package level, is when <code>go test p1 p2 p3<\/code> is called (that is, when it is called with multiple packages to test). In this case, the test binaries of all packages are built then run at the same time. This can be great for the total running time, but it can also lead to randomly failing tests if some shared resources are used by many packages (e.g. if some tests access the database and delete some rows used by tests in other packages).<\/p>\n<p>To keep this under control, the <code>-p<\/code> flag can be used to specify the number of builds and tests to run in parallel. In a repository with many packages in subfolders, one can write <code>go test .\/...<\/code> to test all packages, including the one in the current directory and all subdirectories. Running without the <code>-p<\/code> flag, the total running time should be close to the longest package to test (plus build times). Running <code>go test -p 1 .\/...<\/code>, constraining the tool to build and test one package at a time, the total running time should be close to the sum of all individual package tests plus build times. You can play with it and run <code>go test -p 3 .\/...<\/code> to see the effect on running time.<\/p>\n<p>Yet another place where parallelization can occur (and should be tested) is in the package&#8217;s code. Thanks to Go&#8217;s awesome concurrency primitives, it isn&#8217;t unusual for a package to use goroutines, channels and other synchronization mechanisms. By default, unless GOMAXPROCS is set via an environment variable or explicity in the code, the tests are run with GOMAXPROCS=1. One can type <code>GOMAXPROCS=2 go test<\/code> to test with 2 CPUs, and then type <code>GOMAXPROCS=4 go test<\/code> to test with 4, but there is a better way: <code>go test -cpu=1,2,4<\/code> will run the tests three times, with 1, 2 and 4 as GOMAXPROCS values.<\/p>\n<p>The <code>-cpu<\/code> flag, combined with the data race detector flag <code>-race<\/code> is a match made in heaven (or hell, depending on how it goes). The race detector is an amazing tool that must be used for any serious concurrent development, but its overview is outside the scope of this blog post. The <a href=\"http:\/\/blog.golang.org\/race-detector\">introduction post on the Go blog<\/a> is a good place to start for any interested gopher.<\/p>\n<p><strong>And much more<\/strong><\/p>\n<p>The <code>go test<\/code> tool supports running benchmarks and assertable examples (!) in a similar manner as the test functions. The <code>godoc<\/code> tool even understands the example syntax and includes them in the generated documentation.<\/p>\n<p>There is also much to be said on code coverage and profiling, two features supported by the testing tool. For those interested to dive further, you can start with <a href=\"http:\/\/blog.golang.org\/cover\">&#8220;The cover story&#8221;<\/a> and <a href=\"http:\/\/blog.golang.org\/profiling-go-programs\">&#8220;Profiling Go programs&#8221;<\/a>, both on the Go blog.<\/p>\n<p>And before you roll out your own test utilities, you may want to look at the <code>testing\/iotest<\/code>, <code>testing\/quick<\/code> and <code>net\/http\/httptest<\/code> packages in the standard library!<\/p>\n<p>&nbsp;<\/p>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p class=\"has-text-align-center\">Explore royalty-free sounds from leading artists, producers, and sound designers:<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button aligncenter\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/splice.com\/sounds\" target=\"_blank\" rel=\"noreferrer noopener\">Join Splice today<\/a><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Lesser-known features of go test Most gophers know and love go test, the testing tool that comes with Go&#8217;s official gc toolchain. It is quite&#8230;<\/p>\n","protected":false},"author":17,"featured_media":850,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_exactmetrics_skip_tracking":false,"_exactmetrics_sitenote_active":false,"_exactmetrics_sitenote_note":"","_exactmetrics_sitenote_category":0,"footnotes":""},"categories":[61],"tags":[115],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v22.9 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Lesser-Known Features of Go Test - Blog | Splice<\/title>\n<meta name=\"description\" content=\"Go test is Golang&#039;s built-in testing framework. Simple and elegant but it packs advanced features, learn how to leverage them.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Lesser-Known Features of Go Test - Blog | Splice\" \/>\n<meta property=\"og:description\" content=\"Go test is Golang&#039;s built-in testing framework. Simple and elegant but it packs advanced features, learn how to leverage them.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog | Splice\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/Splice\" \/>\n<meta property=\"article:published_time\" content=\"2014-09-03T18:23:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-01-18T19:42:43+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"720\" \/>\n\t<meta property=\"og:image:height\" content=\"855\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Martin Angers\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@splice\" \/>\n<meta name=\"twitter:site\" content=\"@splice\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Martin Angers\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/\"},\"author\":{\"name\":\"Martin Angers\",\"@id\":\"https:\/\/splice.com\/blog\/#\/schema\/person\/5ed18aca22632875f5dc7a1729d7bc65\"},\"headline\":\"Lesser-Known Features of Go Test\",\"datePublished\":\"2014-09-03T18:23:11+00:00\",\"dateModified\":\"2024-01-18T19:42:43+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/\"},\"wordCount\":1091,\"publisher\":{\"@id\":\"https:\/\/splice.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg\",\"keywords\":[\"engineering\"],\"articleSection\":[\"Engineering\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/\",\"url\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/\",\"name\":\"Lesser-Known Features of Go Test - Blog | Splice\",\"isPartOf\":{\"@id\":\"https:\/\/splice.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg\",\"datePublished\":\"2014-09-03T18:23:11+00:00\",\"dateModified\":\"2024-01-18T19:42:43+00:00\",\"description\":\"Go test is Golang's built-in testing framework. Simple and elegant but it packs advanced features, learn how to leverage them.\",\"breadcrumb\":{\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage\",\"url\":\"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg\",\"contentUrl\":\"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg\",\"width\":720,\"height\":855},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/splice.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Lesser-Known Features of Go Test\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/splice.com\/blog\/#website\",\"url\":\"https:\/\/splice.com\/blog\/\",\"name\":\"Splice Blog\",\"description\":\"An inside look at making music\",\"publisher\":{\"@id\":\"https:\/\/splice.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/splice.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/splice.com\/blog\/#organization\",\"name\":\"Splice\",\"alternateName\":\"Splice Sounds\",\"url\":\"https:\/\/splice.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/splice.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/splice.com\/blog\/wp-content\/uploads\/2023\/09\/Splice-logo-black-background.png\",\"contentUrl\":\"https:\/\/splice.com\/blog\/wp-content\/uploads\/2023\/09\/Splice-logo-black-background.png\",\"width\":2928,\"height\":1540,\"caption\":\"Splice\"},\"image\":{\"@id\":\"https:\/\/splice.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/Splice\",\"https:\/\/x.com\/splice\",\"https:\/\/www.instagram.com\/splice\/\",\"https:\/\/www.youtube.com\/@splice\",\"https:\/\/discord.com\/invite\/splice\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/splice.com\/blog\/#\/schema\/person\/5ed18aca22632875f5dc7a1729d7bc65\",\"name\":\"Martin Angers\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/splice.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/2895982ab79509e2de6cc2712dcdf99b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/2895982ab79509e2de6cc2712dcdf99b?s=96&d=mm&r=g\",\"caption\":\"Martin Angers\"},\"url\":\"https:\/\/splice.com\/blog\/author\/martin\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Lesser-Known Features of Go Test - Blog | Splice","description":"Go test is Golang's built-in testing framework. Simple and elegant but it packs advanced features, learn how to leverage them.","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:\/\/splice.com\/blog\/lesser-known-features-go-test\/","og_locale":"en_US","og_type":"article","og_title":"Lesser-Known Features of Go Test - Blog | Splice","og_description":"Go test is Golang's built-in testing framework. Simple and elegant but it packs advanced features, learn how to leverage them.","og_url":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/","og_site_name":"Blog | Splice","article_publisher":"https:\/\/www.facebook.com\/Splice","article_published_time":"2014-09-03T18:23:11+00:00","article_modified_time":"2024-01-18T19:42:43+00:00","og_image":[{"width":720,"height":855,"url":"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg","type":"image\/jpeg"}],"author":"Martin Angers","twitter_card":"summary_large_image","twitter_creator":"@splice","twitter_site":"@splice","twitter_misc":{"Written by":"Martin Angers","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#article","isPartOf":{"@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/"},"author":{"name":"Martin Angers","@id":"https:\/\/splice.com\/blog\/#\/schema\/person\/5ed18aca22632875f5dc7a1729d7bc65"},"headline":"Lesser-Known Features of Go Test","datePublished":"2014-09-03T18:23:11+00:00","dateModified":"2024-01-18T19:42:43+00:00","mainEntityOfPage":{"@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/"},"wordCount":1091,"publisher":{"@id":"https:\/\/splice.com\/blog\/#organization"},"image":{"@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage"},"thumbnailUrl":"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg","keywords":["engineering"],"articleSection":["Engineering"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/","url":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/","name":"Lesser-Known Features of Go Test - Blog | Splice","isPartOf":{"@id":"https:\/\/splice.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage"},"image":{"@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage"},"thumbnailUrl":"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg","datePublished":"2014-09-03T18:23:11+00:00","dateModified":"2024-01-18T19:42:43+00:00","description":"Go test is Golang's built-in testing framework. Simple and elegant but it packs advanced features, learn how to leverage them.","breadcrumb":{"@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/splice.com\/blog\/lesser-known-features-go-test\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#primaryimage","url":"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg","contentUrl":"https:\/\/splice.com\/blog\/wp-content\/uploads\/2014\/09\/trafficLight.jpg","width":720,"height":855},{"@type":"BreadcrumbList","@id":"https:\/\/splice.com\/blog\/lesser-known-features-go-test\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/splice.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Lesser-Known Features of Go Test"}]},{"@type":"WebSite","@id":"https:\/\/splice.com\/blog\/#website","url":"https:\/\/splice.com\/blog\/","name":"Splice Blog","description":"An inside look at making music","publisher":{"@id":"https:\/\/splice.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/splice.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/splice.com\/blog\/#organization","name":"Splice","alternateName":"Splice Sounds","url":"https:\/\/splice.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/splice.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/splice.com\/blog\/wp-content\/uploads\/2023\/09\/Splice-logo-black-background.png","contentUrl":"https:\/\/splice.com\/blog\/wp-content\/uploads\/2023\/09\/Splice-logo-black-background.png","width":2928,"height":1540,"caption":"Splice"},"image":{"@id":"https:\/\/splice.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/Splice","https:\/\/x.com\/splice","https:\/\/www.instagram.com\/splice\/","https:\/\/www.youtube.com\/@splice","https:\/\/discord.com\/invite\/splice"]},{"@type":"Person","@id":"https:\/\/splice.com\/blog\/#\/schema\/person\/5ed18aca22632875f5dc7a1729d7bc65","name":"Martin Angers","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/splice.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/2895982ab79509e2de6cc2712dcdf99b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2895982ab79509e2de6cc2712dcdf99b?s=96&d=mm&r=g","caption":"Martin Angers"},"url":"https:\/\/splice.com\/blog\/author\/martin\/"}]}},"_links":{"self":[{"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/posts\/847"}],"collection":[{"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/users\/17"}],"replies":[{"embeddable":true,"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/comments?post=847"}],"version-history":[{"count":1,"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/posts\/847\/revisions"}],"predecessor-version":[{"id":30412,"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/posts\/847\/revisions\/30412"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/media\/850"}],"wp:attachment":[{"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/media?parent=847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/categories?post=847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/splice.com\/blog\/wp-json\/wp\/v2\/tags?post=847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}